1 |
1626 |
jcastillo |
/*+M*************************************************************************
|
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 |
|
|
* Sources include the Adaptec 1740 driver (aha1740.c), the Ultrastor 24F
|
22 |
|
|
* driver (ultrastor.c), various Linux kernel source, the Adaptec EISA
|
23 |
|
|
* config file (!adp7771.cfg), the Adaptec AHA-2740A Series User's Guide,
|
24 |
|
|
* the Linux Kernel Hacker's Guide, Writing a SCSI Device Driver for Linux,
|
25 |
|
|
* the Adaptec 1542 driver (aha1542.c), the Adaptec EISA overlay file
|
26 |
|
|
* (adp7770.ovl), the Adaptec AHA-2740 Series Technical Reference Manual,
|
27 |
|
|
* the Adaptec AIC-7770 Data Book, the ANSI SCSI specification, the
|
28 |
|
|
* ANSI SCSI-2 specification (draft 10c), ...
|
29 |
|
|
*
|
30 |
|
|
* --------------------------------------------------------------------------
|
31 |
|
|
*
|
32 |
|
|
* Modifications by Daniel M. Eischen (deischen@iworks.InterWorks.org):
|
33 |
|
|
*
|
34 |
|
|
* Substantially modified to include support for wide and twin bus
|
35 |
|
|
* adapters, DMAing of SCBs, tagged queueing, IRQ sharing, bug fixes,
|
36 |
|
|
* SCB paging, and other rework of the code.
|
37 |
|
|
*
|
38 |
|
|
* Parts of this driver were also based on the FreeBSD driver by
|
39 |
|
|
* Justin T. Gibbs. His copyright follows:
|
40 |
|
|
*
|
41 |
|
|
* --------------------------------------------------------------------------
|
42 |
|
|
* Copyright (c) 1994-1997 Justin Gibbs.
|
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, immediately at the beginning of the file.
|
51 |
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
52 |
|
|
* notice, this list of conditions and the following disclaimer in the
|
53 |
|
|
* documentation and/or other materials provided with the distribution.
|
54 |
|
|
* 3. The name of the author may not be used to endorse or promote products
|
55 |
|
|
* derived from this software without specific prior written permission.
|
56 |
|
|
*
|
57 |
|
|
* Where this Software is combined with software released under the terms of
|
58 |
|
|
* the GNU Public License ("GPL") and the terms of the GPL would require the
|
59 |
|
|
* combined work to also be released under the terms of the GPL, the terms
|
60 |
|
|
* and conditions of this License will apply in addition to those of the
|
61 |
|
|
* GPL with the exception of any terms or conditions of this License that
|
62 |
|
|
* conflict with, or are expressly prohibited by, the GPL.
|
63 |
|
|
*
|
64 |
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
65 |
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
66 |
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
67 |
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
68 |
|
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
69 |
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
70 |
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
71 |
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
72 |
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
73 |
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
74 |
|
|
* SUCH DAMAGE.
|
75 |
|
|
*
|
76 |
|
|
* $Id: aic7xxx.c,v 1.1 2005-12-20 10:17:45 jcastillo Exp $
|
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=ultra
|
91 |
|
|
* aic7xxx=irq_trigger:[0,1] # 0 edge, 1 level
|
92 |
|
|
* aic7xxx=verbose
|
93 |
|
|
*
|
94 |
|
|
* Daniel M. Eischen, deischen@iworks.InterWorks.org, 1/23/97
|
95 |
|
|
*
|
96 |
|
|
* $Id: aic7xxx.c,v 1.1 2005-12-20 10:17:45 jcastillo Exp $
|
97 |
|
|
*-M*************************************************************************/
|
98 |
|
|
|
99 |
|
|
/*+M**************************************************************************
|
100 |
|
|
*
|
101 |
|
|
* Further driver modifications made by Doug Ledford <dledford@redhat.com>
|
102 |
|
|
*
|
103 |
|
|
* Copyright (c) 1997-1999 Doug Ledford
|
104 |
|
|
*
|
105 |
|
|
* These changes are released under the same licensing terms as the FreeBSD
|
106 |
|
|
* driver written by Justin Gibbs. Please see his Copyright notice above
|
107 |
|
|
* for the exact terms and conditions covering my changes as well as the
|
108 |
|
|
* warranty statement.
|
109 |
|
|
*
|
110 |
|
|
* Modifications made to the aic7xxx.c,v 4.1 driver from Dan Eischen include
|
111 |
|
|
* but are not limited to:
|
112 |
|
|
*
|
113 |
|
|
* 1: Import of the latest FreeBSD sequencer code for this driver
|
114 |
|
|
* 2: Modification of kernel code to accomodate different sequencer semantics
|
115 |
|
|
* 3: Extensive changes throughout kernel portion of driver to improve
|
116 |
|
|
* abort/reset processing and error hanndling
|
117 |
|
|
* 4: Other work contributed by various people on the Internet
|
118 |
|
|
* 5: Changes to printk information and verbosity selection code
|
119 |
|
|
* 6: General reliability related changes, especially in IRQ management
|
120 |
|
|
* 7: Modifications to the default probe/attach order for supported cards
|
121 |
|
|
* 8: SMP friendliness has been improved
|
122 |
|
|
*
|
123 |
|
|
* Overall, this driver represents a significant departure from the official
|
124 |
|
|
* aic7xxx driver released by Dan Eischen in two ways. First, in the code
|
125 |
|
|
* itself. A diff between the two version of the driver is now a several
|
126 |
|
|
* thousand line diff. Second, in approach to solving the same problem. The
|
127 |
|
|
* problem is importing the FreeBSD aic7xxx driver code to linux can be a
|
128 |
|
|
* difficult and time consuming process, that also can be error prone. Dan
|
129 |
|
|
* Eischen's official driver uses the approach that the linux and FreeBSD
|
130 |
|
|
* drivers should be as identical as possible. To that end, his next version
|
131 |
|
|
* of this driver will be using a mid-layer code library that he is developing
|
132 |
|
|
* to moderate communications between the linux mid-level SCSI code and the
|
133 |
|
|
* low level FreeBSD driver. He intends to be able to essentially drop the
|
134 |
|
|
* FreeBSD driver into the linux kernel with only a few minor tweaks to some
|
135 |
|
|
* include files and the like and get things working, making for fast easy
|
136 |
|
|
* imports of the FreeBSD code into linux.
|
137 |
|
|
*
|
138 |
|
|
* I disagree with Dan's approach. Not that I don't think his way of doing
|
139 |
|
|
* things would be nice, easy to maintain, and create a more uniform driver
|
140 |
|
|
* between FreeBSD and Linux. I have no objection to those issues. My
|
141 |
|
|
* disagreement is on the needed functionality. There simply are certain
|
142 |
|
|
* things that are done differently in FreeBSD than linux that will cause
|
143 |
|
|
* problems for this driver regardless of any middle ware Dan implements.
|
144 |
|
|
* The biggest example of this at the moment is interrupt semantics. Linux
|
145 |
|
|
* doesn't provide the same protection techniques as FreeBSD does, nor can
|
146 |
|
|
* they be easily implemented in any middle ware code since they would truly
|
147 |
|
|
* belong in the kernel proper and would effect all drivers. For the time
|
148 |
|
|
* being, I see issues such as these as major stumbling blocks to the
|
149 |
|
|
* reliability of code based upon such middle ware. Therefore, I choose to
|
150 |
|
|
* use a different approach to importing the FreeBSD code that doesn't
|
151 |
|
|
* involve any middle ware type code. My approach is to import the sequencer
|
152 |
|
|
* code from FreeBSD wholesale. Then, to only make changes in the kernel
|
153 |
|
|
* portion of the driver as they are needed for the new sequencer semantics.
|
154 |
|
|
* In this way, the portion of the driver that speaks to the rest of the
|
155 |
|
|
* linux kernel is fairly static and can be changed/modified to solve
|
156 |
|
|
* any problems one might encounter without concern for the FreeBSD driver.
|
157 |
|
|
*
|
158 |
|
|
* Note: If time and experience should prove me wrong that the middle ware
|
159 |
|
|
* code Dan writes is reliable in its operation, then I'll retract my above
|
160 |
|
|
* statements. But, for those that don't know, I'm from Missouri (in the US)
|
161 |
|
|
* and our state motto is "The Show-Me State". Well, before I will put
|
162 |
|
|
* faith into it, you'll have to show me that it works :)
|
163 |
|
|
*
|
164 |
|
|
*_M*************************************************************************/
|
165 |
|
|
|
166 |
|
|
/*
|
167 |
|
|
* The next three defines are user configurable. These should be the only
|
168 |
|
|
* defines a user might need to get in here and change. There are other
|
169 |
|
|
* defines buried deeper in the code, but those really shouldn't need touched
|
170 |
|
|
* under normal conditions.
|
171 |
|
|
*/
|
172 |
|
|
|
173 |
|
|
/*
|
174 |
|
|
* AIC7XXX_FAKE_NEGOTIATION_CMDS
|
175 |
|
|
* We now have two distinctly different methods of device negotiation
|
176 |
|
|
* in this code. The two methods are selected by either defining or not
|
177 |
|
|
* defining this option. The difference is as follows:
|
178 |
|
|
*
|
179 |
|
|
* With AIC7XXX_FAKE_NEGOTIATION_CMDS not set (commented out)
|
180 |
|
|
* When the driver is in need of issuing a negotiation command for any
|
181 |
|
|
* given device, it will add the negotiation message on to part of a
|
182 |
|
|
* regular SCSI command for the device. In the process, if the device
|
183 |
|
|
* is configured for and using tagged queueing, then the code will
|
184 |
|
|
* also issue that single command as a non-tagged command, attach the
|
185 |
|
|
* negotiation message to that one command, and use a temporary
|
186 |
|
|
* queue depth of one to keep the untagged and tagged commands from
|
187 |
|
|
* overlapping.
|
188 |
|
|
* Pros: This doesn't use any extra SCB structures, it's simple, it
|
189 |
|
|
* works most of the time (if not all of the time now), and
|
190 |
|
|
* since we get the device capability info frmo the INQUIRY data
|
191 |
|
|
* now, shouldn't cause any problems.
|
192 |
|
|
* Cons: When we need to send a negotiation command to a device, we
|
193 |
|
|
* must use a command that is being sent to LUN 0 of the device.
|
194 |
|
|
* If we try sending one to high LUN numbers, then some devices
|
195 |
|
|
* get noticeably upset. Since we have to wait for a command with
|
196 |
|
|
* LUN == 0 to come along, we may not be able to renegotiate when
|
197 |
|
|
* we want if the user is actually using say LUN 1 of a CD Changer
|
198 |
|
|
* instead of using LUN 0 for an extended period of time.
|
199 |
|
|
*
|
200 |
|
|
* With AIC7XXX_FAKE_NEGOTIATION_CMDS defined
|
201 |
|
|
* When we need to negotiate with a device, instead of attaching our
|
202 |
|
|
* negotiation message to an existing command, we insert our own
|
203 |
|
|
* fictional Scsi_Cmnd into the chain that has the negotiation message
|
204 |
|
|
* attached to it. We send this one command as untagged regardless
|
205 |
|
|
* of the device type, and we fiddle with the queue depth the same as
|
206 |
|
|
* we would with the option unset to avoid overlapping commands. The
|
207 |
|
|
* primary difference between this and the unset option is that the
|
208 |
|
|
* negotiation message is no longer attached to a specific command,
|
209 |
|
|
* instead it is its own command and is merely triggered by a
|
210 |
|
|
* combination of both A) We need to negotiate and B) The mid level
|
211 |
|
|
* SCSI code has sent us a command. We still don't do any negotiation
|
212 |
|
|
* unless there is a valid SCSI command to be processed.
|
213 |
|
|
* Pros: This fixes the problem above in the Cons section. Since we
|
214 |
|
|
* issue our own fake command, we can set the LUN to 0 regardless
|
215 |
|
|
* of what the LUN is in the real command. It also means that if
|
216 |
|
|
* the device get's nasty over negotiation issues, it won't be
|
217 |
|
|
* showing up on a regular command, so we won't get any SENSE buffer
|
218 |
|
|
* data or STATUS_BYTE returns to the mid level code that are caused
|
219 |
|
|
* by snits in the negotiation code.
|
220 |
|
|
* Cons: We add more code, and more complexity. This means more ways
|
221 |
|
|
* in which things could break. It means a larger driver. It means
|
222 |
|
|
* more resource consumption for the fake commands. However, the
|
223 |
|
|
* biggest problem is this. Take a system where there is a CD-ROM
|
224 |
|
|
* on the SCSI bus. Someone has a CD in the CD-ROM and is using it.
|
225 |
|
|
* For some reason the SCSI bus gets reset. We don't touch the
|
226 |
|
|
* CD-ROM again for quite a period of time (so we don't renegotiate
|
227 |
|
|
* after the reset until we do touch the CD-ROM again). In the
|
228 |
|
|
* time while we aren't using the CD-ROM, the current disc is
|
229 |
|
|
* removed and a new one put in. When we go to check that disc, we
|
230 |
|
|
* will first have to renegotiate. In so doing, we issue our fake
|
231 |
|
|
* SCSI command, which happens to be TEST_UNIT_READY. The CD-ROM
|
232 |
|
|
* negotiates with us, then responds to our fake command with a
|
233 |
|
|
* CHECK_CONDITION status. We REQUEST_SENSE from the CD-ROM, it
|
234 |
|
|
* then sends the SENSE data to our fake command to tell it that
|
235 |
|
|
* it has been through a disc change. There, now we've cleared out
|
236 |
|
|
* the SENSE data along with our negotiation command, and when the
|
237 |
|
|
* real command executes, it won't pick up that the CD was changed.
|
238 |
|
|
* That's the biggest Con to this approach. In the future, I could
|
239 |
|
|
* probably code around this problem though, so this option is still
|
240 |
|
|
* viable.
|
241 |
|
|
*
|
242 |
|
|
* So, which command style should you use? I would appreciate it if people
|
243 |
|
|
* could try out both types. I want to know about any cases where one
|
244 |
|
|
* method works and the other doesn't. If one method works on significantly
|
245 |
|
|
* more systems than another, then it will become the default. If the second
|
246 |
|
|
* option turns out to work best, then I'll find a way to work around that
|
247 |
|
|
* big con I listed.
|
248 |
|
|
*
|
249 |
|
|
* -- July 7, 02:33
|
250 |
|
|
* OK...I just added some code that should make the Con listed for the
|
251 |
|
|
* fake commands a non issue now. However, it needs testing. For now,
|
252 |
|
|
* I'm going to make the default to use the fake commands, we'll see how
|
253 |
|
|
* it goes.
|
254 |
|
|
*/
|
255 |
|
|
|
256 |
|
|
#define AIC7XXX_FAKE_NEGOTIATION_CMDS
|
257 |
|
|
|
258 |
|
|
/*
|
259 |
|
|
* AIC7XXX_STRICT_PCI_SETUP
|
260 |
|
|
* Should we assume the PCI config options on our controllers are set with
|
261 |
|
|
* sane and proper values, or should we be anal about our PCI config
|
262 |
|
|
* registers and force them to what we want? The main advantage to
|
263 |
|
|
* defining this option is on non-Intel hardware where the BIOS may not
|
264 |
|
|
* have been run to set things up, or if you have one of the BIOSless
|
265 |
|
|
* Adaptec controllers, such as a 2910, that don't get set up by the
|
266 |
|
|
* BIOS. However, keep in mind that we really do set the most important
|
267 |
|
|
* items in the driver regardless of this setting, this only controls some
|
268 |
|
|
* of the more esoteric PCI options on these cards. In that sense, I
|
269 |
|
|
* would default to leaving this off. However, if people wish to try
|
270 |
|
|
* things both ways, that would also help me to know if there are some
|
271 |
|
|
* machines where it works one way but not another.
|
272 |
|
|
*
|
273 |
|
|
* -- July 7, 17:09
|
274 |
|
|
* OK...I need this on my machine for testing, so the default is to
|
275 |
|
|
* leave it defined.
|
276 |
|
|
*
|
277 |
|
|
* -- July 7, 18:49
|
278 |
|
|
* I needed it for testing, but it didn't make any difference, so back
|
279 |
|
|
* off she goes.
|
280 |
|
|
*
|
281 |
|
|
* -- July 16, 23:04
|
282 |
|
|
* I turned it back on to try and compensate for the 2.1.x PCI code
|
283 |
|
|
* which no longer relies solely on the BIOS and now tries to set
|
284 |
|
|
* things itself.
|
285 |
|
|
*/
|
286 |
|
|
|
287 |
|
|
#define AIC7XXX_STRICT_PCI_SETUP
|
288 |
|
|
|
289 |
|
|
/*
|
290 |
|
|
* AIC7XXX_VERBOSE_DEBUGGING
|
291 |
|
|
* This option enables a lot of extra printk();s in the code, surrounded
|
292 |
|
|
* by if (aic7xxx_verbose ...) statements. Executing all of those if
|
293 |
|
|
* statements and the extra checks can get to where it actually does have
|
294 |
|
|
* an impact on CPU usage and such, as well as code size. Disabling this
|
295 |
|
|
* define will keep some of those from becoming part of the code.
|
296 |
|
|
*
|
297 |
|
|
* NOTE: Currently, this option has no real effect, I will be adding the
|
298 |
|
|
* various #ifdef's in the code later when I've decided a section is
|
299 |
|
|
* complete and no longer needs debugging. OK...a lot of things are now
|
300 |
|
|
* surrounded by this define, so turning this off does have an impact.
|
301 |
|
|
*/
|
302 |
|
|
|
303 |
|
|
/*
|
304 |
|
|
* #define AIC7XXX_VERBOSE_DEBUGGING
|
305 |
|
|
*/
|
306 |
|
|
|
307 |
|
|
#if defined(MODULE) || defined(PCMCIA)
|
308 |
|
|
#include <linux/module.h>
|
309 |
|
|
#endif
|
310 |
|
|
|
311 |
|
|
#if defined(PCMCIA)
|
312 |
|
|
# undef MODULE
|
313 |
|
|
#endif
|
314 |
|
|
|
315 |
|
|
#include <stdarg.h>
|
316 |
|
|
#include <asm/io.h>
|
317 |
|
|
#include <asm/irq.h>
|
318 |
|
|
#include <asm/byteorder.h>
|
319 |
|
|
#include <linux/version.h>
|
320 |
|
|
#include <linux/string.h>
|
321 |
|
|
#include <linux/errno.h>
|
322 |
|
|
#include <linux/kernel.h>
|
323 |
|
|
#include <linux/ioport.h>
|
324 |
|
|
#include <linux/delay.h>
|
325 |
|
|
#include <linux/sched.h>
|
326 |
|
|
#include <linux/pci.h>
|
327 |
|
|
#include <linux/proc_fs.h>
|
328 |
|
|
#include <linux/blk.h>
|
329 |
|
|
#include <linux/tqueue.h>
|
330 |
|
|
#include <linux/tasks.h>
|
331 |
|
|
#include "sd.h"
|
332 |
|
|
#include "scsi.h"
|
333 |
|
|
#include "hosts.h"
|
334 |
|
|
#include "aic7xxx.h"
|
335 |
|
|
|
336 |
|
|
#include "aic7xxx/sequencer.h"
|
337 |
|
|
#include "aic7xxx/scsi_message.h"
|
338 |
|
|
#include "aic7xxx_reg.h"
|
339 |
|
|
#include <scsi/scsicam.h>
|
340 |
|
|
|
341 |
|
|
#include <linux/stat.h>
|
342 |
|
|
#include <linux/malloc.h> /* for kmalloc() */
|
343 |
|
|
|
344 |
|
|
#include <linux/config.h> /* for CONFIG_PCI */
|
345 |
|
|
|
346 |
|
|
/*
|
347 |
|
|
* To generate the correct addresses for the controller to issue
|
348 |
|
|
* on the bus. Originally added for DEC Alpha support.
|
349 |
|
|
*/
|
350 |
|
|
#define VIRT_TO_BUS(a) (unsigned int)virt_to_bus((void *)(a))
|
351 |
|
|
|
352 |
|
|
struct proc_dir_entry proc_scsi_aic7xxx = {
|
353 |
|
|
PROC_SCSI_AIC7XXX, 7, "aic7xxx",
|
354 |
|
|
S_IFDIR | S_IRUGO | S_IXUGO, 2,
|
355 |
|
|
0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
356 |
|
|
};
|
357 |
|
|
|
358 |
|
|
#define AIC7XXX_C_VERSION "5.1.13"
|
359 |
|
|
|
360 |
|
|
#define NUMBER(arr) (sizeof(arr) / sizeof(arr[0]))
|
361 |
|
|
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
362 |
|
|
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
363 |
|
|
#define ALL_TARGETS -1
|
364 |
|
|
#define ALL_CHANNELS -1
|
365 |
|
|
#define ALL_LUNS -1
|
366 |
|
|
#define MAX_TARGETS 16
|
367 |
|
|
#define MAX_LUNS 8
|
368 |
|
|
#ifndef TRUE
|
369 |
|
|
# define TRUE 1
|
370 |
|
|
#endif
|
371 |
|
|
#ifndef FALSE
|
372 |
|
|
# define FALSE 0
|
373 |
|
|
#endif
|
374 |
|
|
|
375 |
|
|
#ifndef KERNEL_VERSION
|
376 |
|
|
# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
|
377 |
|
|
#endif
|
378 |
|
|
|
379 |
|
|
/*
|
380 |
|
|
* We need the bios32.h file if we are kernel version 2.1.92 or less. The
|
381 |
|
|
* full set of pci_* changes wasn't in place until 2.1.93
|
382 |
|
|
*/
|
383 |
|
|
|
384 |
|
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,92)
|
385 |
|
|
# if defined(__sparc_v9__) || defined(__powerpc__)
|
386 |
|
|
# error "PPC and Sparc platforms are only support under 2.1.92 and above"
|
387 |
|
|
# endif
|
388 |
|
|
# include <linux/bios32.h>
|
389 |
|
|
#endif
|
390 |
|
|
|
391 |
|
|
#if defined(__powerpc__)
|
392 |
|
|
# define MMAPIO
|
393 |
|
|
# ifdef mb
|
394 |
|
|
# undef mb
|
395 |
|
|
# endif
|
396 |
|
|
# define mb() \
|
397 |
|
|
__asm__ __volatile__("eieio" ::: "memory")
|
398 |
|
|
#elif defined(__i386__)
|
399 |
|
|
# define MMAPIO
|
400 |
|
|
# ifdef mb
|
401 |
|
|
# undef mb
|
402 |
|
|
# endif
|
403 |
|
|
# define mb() \
|
404 |
|
|
__asm__ __volatile__("lock ; addl $0,0(%%esp)": : :"memory")
|
405 |
|
|
#elif defined(__alpha__)
|
406 |
|
|
# ifdef mb
|
407 |
|
|
# undef mb
|
408 |
|
|
# endif
|
409 |
|
|
# define mb() \
|
410 |
|
|
__asm__ __volatile__("mb": : :"memory")
|
411 |
|
|
#endif
|
412 |
|
|
|
413 |
|
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
|
414 |
|
|
# include <asm/spinlock.h>
|
415 |
|
|
# include <linux/smp.h>
|
416 |
|
|
# define cpuid smp_processor_id()
|
417 |
|
|
# if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
|
418 |
|
|
# define DRIVER_LOCK_INIT \
|
419 |
|
|
spin_lock_init(&p->spin_lock);
|
420 |
|
|
# define DRIVER_LOCK \
|
421 |
|
|
if(!p->cpu_lock_count[cpuid]) { \
|
422 |
|
|
spin_lock_irqsave(&p->spin_lock, cpu_flags); \
|
423 |
|
|
p->cpu_lock_count[cpuid]++; \
|
424 |
|
|
} else { \
|
425 |
|
|
p->cpu_lock_count[cpuid]++; \
|
426 |
|
|
}
|
427 |
|
|
# define DRIVER_UNLOCK \
|
428 |
|
|
if(--p->cpu_lock_count[cpuid] == 0) \
|
429 |
|
|
spin_unlock_irqrestore(&p->spin_lock, cpu_flags);
|
430 |
|
|
# else
|
431 |
|
|
# define DRIVER_LOCK_INIT
|
432 |
|
|
# define DRIVER_LOCK
|
433 |
|
|
# define DRIVER_UNLOCK
|
434 |
|
|
# endif
|
435 |
|
|
#else
|
436 |
|
|
# define cpuid 0
|
437 |
|
|
# define DRIVER_LOCK_INIT
|
438 |
|
|
# define DRIVER_LOCK \
|
439 |
|
|
save_flags(cpu_flags); \
|
440 |
|
|
cli();
|
441 |
|
|
# define DRIVER_UNLOCK \
|
442 |
|
|
restore_flags(cpu_flags);
|
443 |
|
|
# define le32_to_cpu(x) (x)
|
444 |
|
|
# define cpu_to_le32(x) (x)
|
445 |
|
|
#endif
|
446 |
|
|
|
447 |
|
|
/*
|
448 |
|
|
* You can try raising me if tagged queueing is enabled, or lowering
|
449 |
|
|
* me if you only have 4 SCBs.
|
450 |
|
|
*/
|
451 |
|
|
#ifdef CONFIG_AIC7XXX_CMDS_PER_DEVICE
|
452 |
|
|
#define AIC7XXX_CMDS_PER_DEVICE CONFIG_AIC7XXX_CMDS_PER_DEVICE
|
453 |
|
|
#else
|
454 |
|
|
#define AIC7XXX_CMDS_PER_DEVICE 8
|
455 |
|
|
#endif
|
456 |
|
|
|
457 |
|
|
/* Set this to the delay in seconds after SCSI bus reset. */
|
458 |
|
|
#ifdef CONFIG_AIC7XXX_RESET_DELAY
|
459 |
|
|
#define AIC7XXX_RESET_DELAY CONFIG_AIC7XXX_RESET_DELAY
|
460 |
|
|
#else
|
461 |
|
|
#define AIC7XXX_RESET_DELAY 5
|
462 |
|
|
#endif
|
463 |
|
|
|
464 |
|
|
/*
|
465 |
|
|
* Control collection of SCSI transfer statistics for the /proc filesystem.
|
466 |
|
|
*
|
467 |
|
|
* NOTE: Do NOT enable this when running on kernels version 1.2.x and below.
|
468 |
|
|
* NOTE: This does affect performance since it has to maintain statistics.
|
469 |
|
|
*/
|
470 |
|
|
#ifdef CONFIG_AIC7XXX_PROC_STATS
|
471 |
|
|
#define AIC7XXX_PROC_STATS
|
472 |
|
|
#endif
|
473 |
|
|
|
474 |
|
|
/*
|
475 |
|
|
* NOTE: Uncommenting the define below no longer has any effect, the
|
476 |
|
|
* tagged queue value array is always active now. I've added
|
477 |
|
|
* a setup option to set this particular array and I'm hoping
|
478 |
|
|
* insmod will be smart enough to set it properly as well. It's
|
479 |
|
|
* by use of this array that a person can enable tagged queueing.
|
480 |
|
|
* The DEFAULT_TAG_COMMANDS define has been changed to disable
|
481 |
|
|
* tagged queueing by default, so if your devices can handle tagged
|
482 |
|
|
* queueing you will need to add a line to their lilo.conf file like:
|
483 |
|
|
* append="aic7xxx=verbose,tag_info:{{32,32,32,32},{32,32,32,32}}"
|
484 |
|
|
* which will result in the first four devices on the first two
|
485 |
|
|
* controllers being set to a tagged queue depth of 32.
|
486 |
|
|
*
|
487 |
|
|
* Set this for defining the number of tagged commands on a device
|
488 |
|
|
* by device, and controller by controller basis. The first set
|
489 |
|
|
* of tagged commands will be used for the first detected aic7xxx
|
490 |
|
|
* controller, the second set will be used for the second detected
|
491 |
|
|
* aic7xxx controller, and so on. These values will *only* be used
|
492 |
|
|
* for targets that are tagged queueing capable; these values will
|
493 |
|
|
* be ignored in all other cases. The tag_commands is an array of
|
494 |
|
|
* 16 to allow for wide and twin adapters. Twin adapters will use
|
495 |
|
|
* indexes 0-7 for channel 0, and indexes 8-15 for channel 1.
|
496 |
|
|
*
|
497 |
|
|
* *** Determining commands per LUN ***
|
498 |
|
|
*
|
499 |
|
|
* When AIC7XXX_CMDS_PER_DEVICE is not defined, the driver will use its
|
500 |
|
|
* own algorithm to determine the commands/LUN. If SCB paging is
|
501 |
|
|
* enabled, which is always now, the default is 8 commands per lun
|
502 |
|
|
* that indicates it supports tagged queueing. All non-tagged devices
|
503 |
|
|
* use an internal queue depth of 3, with no more than one of those
|
504 |
|
|
* three commands active at one time.
|
505 |
|
|
*/
|
506 |
|
|
/* #define AIC7XXX_TAGGED_QUEUEING_BY_DEVICE */
|
507 |
|
|
|
508 |
|
|
typedef struct
|
509 |
|
|
{
|
510 |
|
|
unsigned char tag_commands[16]; /* Allow for wide/twin adapters. */
|
511 |
|
|
} adapter_tag_info_t;
|
512 |
|
|
|
513 |
|
|
/*
|
514 |
|
|
* Make a define that will tell the driver not to use tagged queueing
|
515 |
|
|
* by default.
|
516 |
|
|
*/
|
517 |
|
|
#ifdef CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT
|
518 |
|
|
#define DEFAULT_TAG_COMMANDS {0, 0, 0, 0, 0, 0, 0, 0,\
|
519 |
|
|
0, 0, 0, 0, 0, 0, 0, 0}
|
520 |
|
|
#else
|
521 |
|
|
#define DEFAULT_TAG_COMMANDS {255, 255, 255, 255, 255, 255, 255, 255,\
|
522 |
|
|
255, 255, 255, 255, 255, 255, 255, 255}
|
523 |
|
|
#endif
|
524 |
|
|
|
525 |
|
|
/*
|
526 |
|
|
* Modify this as you see fit for your system. By setting tag_commands
|
527 |
|
|
* to 0, the driver will use it's own algorithm for determining the
|
528 |
|
|
* number of commands to use (see above). When 255, the driver will
|
529 |
|
|
* not enable tagged queueing for that particular device. When positive
|
530 |
|
|
* (> 0) and (< 255) the values in the array are used for the queue_depth.
|
531 |
|
|
* Note that the maximum value for an entry is 254, but you're insane if
|
532 |
|
|
* you try to use that many commands on one device.
|
533 |
|
|
*
|
534 |
|
|
* In this example, the first line will disable tagged queueing for all
|
535 |
|
|
* the devices on the first probed aic7xxx adapter.
|
536 |
|
|
*
|
537 |
|
|
* The second line enables tagged queueing with 4 commands/LUN for IDs
|
538 |
|
|
* (1, 2-11, 13-15), disables tagged queueing for ID 12, and tells the
|
539 |
|
|
* driver to use its own algorithm for ID 1.
|
540 |
|
|
*
|
541 |
|
|
* The third line is the same as the first line.
|
542 |
|
|
*
|
543 |
|
|
* The fourth line disables tagged queueing for devices 0 and 3. It
|
544 |
|
|
* enables tagged queueing for the other IDs, with 16 commands/LUN
|
545 |
|
|
* for IDs 1 and 4, 127 commands/LUN for ID 8, and 4 commands/LUN for
|
546 |
|
|
* IDs 2, 5-7, and 9-15.
|
547 |
|
|
*/
|
548 |
|
|
|
549 |
|
|
/*
|
550 |
|
|
* NOTE: The below structure is for reference only, the actual structure
|
551 |
|
|
* to modify in order to change things is located around line
|
552 |
|
|
* number 1305
|
553 |
|
|
adapter_tag_info_t aic7xxx_tag_info[] =
|
554 |
|
|
{
|
555 |
|
|
{DEFAULT_TAG_COMMANDS},
|
556 |
|
|
{{4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 255, 4, 4, 4}},
|
557 |
|
|
{DEFAULT_TAG_COMMANDS},
|
558 |
|
|
{{255, 16, 4, 255, 16, 4, 4, 4, 127, 4, 4, 4, 4, 4, 4, 4}}
|
559 |
|
|
};
|
560 |
|
|
*/
|
561 |
|
|
|
562 |
|
|
static adapter_tag_info_t aic7xxx_tag_info[] =
|
563 |
|
|
{
|
564 |
|
|
{DEFAULT_TAG_COMMANDS},
|
565 |
|
|
{DEFAULT_TAG_COMMANDS},
|
566 |
|
|
{DEFAULT_TAG_COMMANDS},
|
567 |
|
|
{DEFAULT_TAG_COMMANDS},
|
568 |
|
|
{DEFAULT_TAG_COMMANDS},
|
569 |
|
|
{DEFAULT_TAG_COMMANDS},
|
570 |
|
|
{DEFAULT_TAG_COMMANDS},
|
571 |
|
|
{DEFAULT_TAG_COMMANDS},
|
572 |
|
|
{DEFAULT_TAG_COMMANDS},
|
573 |
|
|
{DEFAULT_TAG_COMMANDS},
|
574 |
|
|
{DEFAULT_TAG_COMMANDS},
|
575 |
|
|
{DEFAULT_TAG_COMMANDS},
|
576 |
|
|
{DEFAULT_TAG_COMMANDS},
|
577 |
|
|
{DEFAULT_TAG_COMMANDS},
|
578 |
|
|
{DEFAULT_TAG_COMMANDS},
|
579 |
|
|
{DEFAULT_TAG_COMMANDS}
|
580 |
|
|
};
|
581 |
|
|
|
582 |
|
|
|
583 |
|
|
/*
|
584 |
|
|
* Define an array of board names that can be indexed by aha_type.
|
585 |
|
|
* Don't forget to change this when changing the types!
|
586 |
|
|
*/
|
587 |
|
|
static const char *board_names[] = {
|
588 |
|
|
"AIC-7xxx Unknown", /* AIC_NONE */
|
589 |
|
|
"Adaptec AIC-7810 Hardware RAID Controller", /* AIC_7810 */
|
590 |
|
|
"Adaptec AIC-7770 SCSI host adapter", /* AIC_7770 */
|
591 |
|
|
"Adaptec AHA-274X SCSI host adapter", /* AIC_7771 */
|
592 |
|
|
"Adaptec AHA-284X SCSI host adapter", /* AIC_284x */
|
593 |
|
|
"Adaptec AIC-7850 SCSI host adapter", /* AIC_7850 */
|
594 |
|
|
"Adaptec AIC-7855 SCSI host adapter", /* AIC_7855 */
|
595 |
|
|
"Adaptec AIC-7860 Ultra SCSI host adapter", /* AIC_7860 */
|
596 |
|
|
"Adaptec AHA-2940A Ultra SCSI host adapter", /* AIC_7861 */
|
597 |
|
|
"Adaptec AIC-7870 SCSI host adapter", /* AIC_7870 */
|
598 |
|
|
"Adaptec AHA-294X SCSI host adapter", /* AIC_7871 */
|
599 |
|
|
"Adaptec AHA-394X SCSI host adapter", /* AIC_7872 */
|
600 |
|
|
"Adaptec AHA-398X SCSI host adapter", /* AIC_7873 */
|
601 |
|
|
"Adaptec AHA-2944 SCSI host adapter", /* AIC_7874 */
|
602 |
|
|
"Adaptec AIC-7880 Ultra SCSI host adapter", /* AIC_7880 */
|
603 |
|
|
"Adaptec AHA-294X Ultra SCSI host adapter", /* AIC_7881 */
|
604 |
|
|
"Adaptec AHA-394X Ultra SCSI host adapter", /* AIC_7882 */
|
605 |
|
|
"Adaptec AHA-398X Ultra SCSI host adapter", /* AIC_7883 */
|
606 |
|
|
"Adaptec AHA-2944 Ultra SCSI host adapter", /* AIC_7884 */
|
607 |
|
|
"Adaptec AIC-7895 Ultra SCSI host adapter", /* AIC_7895 */
|
608 |
|
|
"Adaptec AIC-7890/1 Ultra2 SCSI host adapter", /* AIC_7890 */
|
609 |
|
|
"Adaptec AHA-293X Ultra2 SCSI host adapter", /* AIC_7890 */
|
610 |
|
|
"Adaptec AHA-294X Ultra2 SCSI host adapter", /* AIC_7890 */
|
611 |
|
|
"Adaptec AIC-7896/7 Ultra2 SCSI host adapter", /* AIC_7896 */
|
612 |
|
|
"Adaptec AHA-394X Ultra2 SCSI host adapter", /* AIC_7897 */
|
613 |
|
|
"Adaptec AHA-395X Ultra2 SCSI host adapter", /* AIC_7897 */
|
614 |
|
|
"Adaptec PCMCIA SCSI controller", /* card bus stuff */
|
615 |
|
|
"Adaptec AIC-7892 Ultra 160/m SCSI host adapter", /* AIC_7892 */
|
616 |
|
|
"Adaptec AIC-7899 Ultra 160/m SCSI host adapter", /* AIC_7899 */
|
617 |
|
|
};
|
618 |
|
|
|
619 |
|
|
/*
|
620 |
|
|
* There should be a specific return value for this in scsi.h, but
|
621 |
|
|
* it seems that most drivers ignore it.
|
622 |
|
|
*/
|
623 |
|
|
#define DID_UNDERFLOW DID_ERROR
|
624 |
|
|
|
625 |
|
|
/*
|
626 |
|
|
* What we want to do is have the higher level scsi driver requeue
|
627 |
|
|
* the command to us. There is no specific driver status for this
|
628 |
|
|
* condition, but the higher level scsi driver will requeue the
|
629 |
|
|
* command on a DID_BUS_BUSY error.
|
630 |
|
|
*
|
631 |
|
|
* Upon further inspection and testing, it seems that DID_BUS_BUSY
|
632 |
|
|
* will *always* retry the command. We can get into an infinite loop
|
633 |
|
|
* if this happens when we really want some sort of counter that
|
634 |
|
|
* will automatically abort/reset the command after so many retries.
|
635 |
|
|
* Using DID_ERROR will do just that. (Made by a suggestion by
|
636 |
|
|
* Doug Ledford 8/1/96)
|
637 |
|
|
*/
|
638 |
|
|
#define DID_RETRY_COMMAND DID_ERROR
|
639 |
|
|
|
640 |
|
|
#define HSCSIID 0x07
|
641 |
|
|
#define SCSI_RESET 0x040
|
642 |
|
|
|
643 |
|
|
/*
|
644 |
|
|
* EISA/VL-bus stuff
|
645 |
|
|
*/
|
646 |
|
|
#define MINSLOT 1
|
647 |
|
|
#define MAXSLOT 15
|
648 |
|
|
#define SLOTBASE(x) ((x) << 12)
|
649 |
|
|
#define BASE_TO_SLOT(x) ((x) >> 12)
|
650 |
|
|
|
651 |
|
|
/*
|
652 |
|
|
* Standard EISA Host ID regs (Offset from slot base)
|
653 |
|
|
*/
|
654 |
|
|
#define AHC_HID0 0x80 /* 0,1: msb of ID2, 2-7: ID1 */
|
655 |
|
|
#define AHC_HID1 0x81 /* 0-4: ID3, 5-7: LSB ID2 */
|
656 |
|
|
#define AHC_HID2 0x82 /* product */
|
657 |
|
|
#define AHC_HID3 0x83 /* firmware revision */
|
658 |
|
|
|
659 |
|
|
/*
|
660 |
|
|
* AIC-7770 I/O range to reserve for a card
|
661 |
|
|
*/
|
662 |
|
|
#define MINREG 0xC00
|
663 |
|
|
#define MAXREG 0xCBF
|
664 |
|
|
|
665 |
|
|
#define INTDEF 0x5C /* Interrupt Definition Register */
|
666 |
|
|
|
667 |
|
|
/*
|
668 |
|
|
* AIC-78X0 PCI registers
|
669 |
|
|
*/
|
670 |
|
|
#define CLASS_PROGIF_REVID 0x08
|
671 |
|
|
#define DEVREVID 0x000000FFul
|
672 |
|
|
#define PROGINFC 0x0000FF00ul
|
673 |
|
|
#define SUBCLASS 0x00FF0000ul
|
674 |
|
|
#define BASECLASS 0xFF000000ul
|
675 |
|
|
|
676 |
|
|
#define CSIZE_LATTIME 0x0C
|
677 |
|
|
#define CACHESIZE 0x0000003Ful /* only 5 bits */
|
678 |
|
|
#define LATTIME 0x0000FF00ul
|
679 |
|
|
|
680 |
|
|
#define DEVCONFIG 0x40
|
681 |
|
|
#define SCBSIZE32 0x00010000ul /* aic789X only */
|
682 |
|
|
#define MPORTMODE 0x00000400ul /* aic7870 only */
|
683 |
|
|
#define RAMPSM 0x00000200ul /* aic7870 only */
|
684 |
|
|
#define RAMPSM_ULTRA2 0x00000004
|
685 |
|
|
#define VOLSENSE 0x00000100ul
|
686 |
|
|
#define SCBRAMSEL 0x00000080ul
|
687 |
|
|
#define SCBRAMSEL_ULTRA2 0x00000008
|
688 |
|
|
#define MRDCEN 0x00000040ul
|
689 |
|
|
#define EXTSCBTIME 0x00000020ul /* aic7870 only */
|
690 |
|
|
#define EXTSCBPEN 0x00000010ul /* aic7870 only */
|
691 |
|
|
#define BERREN 0x00000008ul
|
692 |
|
|
#define DACEN 0x00000004ul
|
693 |
|
|
#define STPWLEVEL 0x00000002ul
|
694 |
|
|
#define DIFACTNEGEN 0x00000001ul /* aic7870 only */
|
695 |
|
|
|
696 |
|
|
#define SCAMCTL 0x1a /* Ultra2 only */
|
697 |
|
|
#define CCSCBBADDR 0xf0 /* aic7895/6/7 */
|
698 |
|
|
|
699 |
|
|
/*
|
700 |
|
|
* Define the different types of SEEPROMs on aic7xxx adapters
|
701 |
|
|
* and make it also represent the address size used in accessing
|
702 |
|
|
* its registers. The 93C46 chips have 1024 bits organized into
|
703 |
|
|
* 64 16-bit words, while the 93C56 chips have 2048 bits organized
|
704 |
|
|
* into 128 16-bit words. The C46 chips use 6 bits to address
|
705 |
|
|
* each word, while the C56 and C66 (4096 bits) use 8 bits to
|
706 |
|
|
* address each word.
|
707 |
|
|
*/
|
708 |
|
|
typedef enum {C46 = 6, C56_66 = 8} seeprom_chip_type;
|
709 |
|
|
|
710 |
|
|
/*
|
711 |
|
|
*
|
712 |
|
|
* Define the format of the SEEPROM registers (16 bits).
|
713 |
|
|
*
|
714 |
|
|
*/
|
715 |
|
|
struct seeprom_config {
|
716 |
|
|
|
717 |
|
|
/*
|
718 |
|
|
* SCSI ID Configuration Flags
|
719 |
|
|
*/
|
720 |
|
|
#define CFXFER 0x0007 /* synchronous transfer rate */
|
721 |
|
|
#define CFSYNCH 0x0008 /* enable synchronous transfer */
|
722 |
|
|
#define CFDISC 0x0010 /* enable disconnection */
|
723 |
|
|
#define CFWIDEB 0x0020 /* wide bus device (wide card) */
|
724 |
|
|
#define CFSYNCHISULTRA 0x0040 /* CFSYNC is an ultra offset */
|
725 |
|
|
#define CFNEWULTRAFORMAT 0x0080 /* Use the Ultra2 SEEPROM format */
|
726 |
|
|
#define CFSTART 0x0100 /* send start unit SCSI command */
|
727 |
|
|
#define CFINCBIOS 0x0200 /* include in BIOS scan */
|
728 |
|
|
#define CFRNFOUND 0x0400 /* report even if not found */
|
729 |
|
|
#define CFMULTILUN 0x0800 /* probe mult luns in BIOS scan */
|
730 |
|
|
#define CFWBCACHEYES 0x4000 /* Enable W-Behind Cache on drive */
|
731 |
|
|
#define CFWBCACHENC 0xc000 /* Don't change W-Behind Cache */
|
732 |
|
|
/* UNUSED 0x3000 */
|
733 |
|
|
unsigned short device_flags[16]; /* words 0-15 */
|
734 |
|
|
|
735 |
|
|
/*
|
736 |
|
|
* BIOS Control Bits
|
737 |
|
|
*/
|
738 |
|
|
#define CFSUPREM 0x0001 /* support all removable drives */
|
739 |
|
|
#define CFSUPREMB 0x0002 /* support removable drives for boot only */
|
740 |
|
|
#define CFBIOSEN 0x0004 /* BIOS enabled */
|
741 |
|
|
/* UNUSED 0x0008 */
|
742 |
|
|
#define CFSM2DRV 0x0010 /* support more than two drives */
|
743 |
|
|
#define CF284XEXTEND 0x0020 /* extended translation (284x cards) */
|
744 |
|
|
/* UNUSED 0x0040 */
|
745 |
|
|
#define CFEXTEND 0x0080 /* extended translation enabled */
|
746 |
|
|
/* UNUSED 0xFF00 */
|
747 |
|
|
unsigned short bios_control; /* word 16 */
|
748 |
|
|
|
749 |
|
|
/*
|
750 |
|
|
* Host Adapter Control Bits
|
751 |
|
|
*/
|
752 |
|
|
#define CFAUTOTERM 0x0001 /* Perform Auto termination */
|
753 |
|
|
#define CFULTRAEN 0x0002 /* Ultra SCSI speed enable (Ultra cards) */
|
754 |
|
|
#define CF284XSELTO 0x0003 /* Selection timeout (284x cards) */
|
755 |
|
|
#define CF284XFIFO 0x000C /* FIFO Threshold (284x cards) */
|
756 |
|
|
#define CFSTERM 0x0004 /* SCSI low byte termination */
|
757 |
|
|
#define CFWSTERM 0x0008 /* SCSI high byte termination (wide card) */
|
758 |
|
|
#define CFSPARITY 0x0010 /* SCSI parity */
|
759 |
|
|
#define CF284XSTERM 0x0020 /* SCSI low byte termination (284x cards) */
|
760 |
|
|
#define CFRESETB 0x0040 /* reset SCSI bus at boot */
|
761 |
|
|
#define CFBPRIMARY 0x0100 /* Channel B primary on 7895 chipsets */
|
762 |
|
|
#define CFSEAUTOTERM 0x0400 /* aic7890 Perform SE Auto Term */
|
763 |
|
|
#define CFLVDSTERM 0x0800 /* aic7890 LVD Termination */
|
764 |
|
|
/* UNUSED 0xF280 */
|
765 |
|
|
unsigned short adapter_control; /* word 17 */
|
766 |
|
|
|
767 |
|
|
/*
|
768 |
|
|
* Bus Release, Host Adapter ID
|
769 |
|
|
*/
|
770 |
|
|
#define CFSCSIID 0x000F /* host adapter SCSI ID */
|
771 |
|
|
/* UNUSED 0x00F0 */
|
772 |
|
|
#define CFBRTIME 0xFF00 /* bus release time */
|
773 |
|
|
unsigned short brtime_id; /* word 18 */
|
774 |
|
|
|
775 |
|
|
/*
|
776 |
|
|
* Maximum targets
|
777 |
|
|
*/
|
778 |
|
|
#define CFMAXTARG 0x00FF /* maximum targets */
|
779 |
|
|
/* UNUSED 0xFF00 */
|
780 |
|
|
unsigned short max_targets; /* word 19 */
|
781 |
|
|
|
782 |
|
|
unsigned short res_1[11]; /* words 20-30 */
|
783 |
|
|
unsigned short checksum; /* word 31 */
|
784 |
|
|
};
|
785 |
|
|
|
786 |
|
|
#define SELBUS_MASK 0x0a
|
787 |
|
|
#define SELNARROW 0x00
|
788 |
|
|
#define SELBUSB 0x08
|
789 |
|
|
#define SINGLE_BUS 0x00
|
790 |
|
|
|
791 |
|
|
#define SCB_TARGET(scb) \
|
792 |
|
|
(((scb)->hscb->target_channel_lun & TID) >> 4)
|
793 |
|
|
#define SCB_LUN(scb) \
|
794 |
|
|
((scb)->hscb->target_channel_lun & LID)
|
795 |
|
|
#define SCB_IS_SCSIBUS_B(scb) \
|
796 |
|
|
(((scb)->hscb->target_channel_lun & SELBUSB) != 0)
|
797 |
|
|
|
798 |
|
|
/*
|
799 |
|
|
* If an error occurs during a data transfer phase, run the command
|
800 |
|
|
* to completion - it's easier that way - making a note of the error
|
801 |
|
|
* condition in this location. This then will modify a DID_OK status
|
802 |
|
|
* into an appropriate error for the higher-level SCSI code.
|
803 |
|
|
*/
|
804 |
|
|
#define aic7xxx_error(cmd) ((cmd)->SCp.Status)
|
805 |
|
|
|
806 |
|
|
/*
|
807 |
|
|
* Keep track of the targets returned status.
|
808 |
|
|
*/
|
809 |
|
|
#define aic7xxx_status(cmd) ((cmd)->SCp.sent_command)
|
810 |
|
|
|
811 |
|
|
/*
|
812 |
|
|
* The position of the SCSI commands scb within the scb array.
|
813 |
|
|
*/
|
814 |
|
|
#define aic7xxx_position(cmd) ((cmd)->SCp.have_data_in)
|
815 |
|
|
|
816 |
|
|
/*
|
817 |
|
|
* So we can keep track of our host structs
|
818 |
|
|
*/
|
819 |
|
|
static struct aic7xxx_host *first_aic7xxx = NULL;
|
820 |
|
|
|
821 |
|
|
/*
|
822 |
|
|
* As of Linux 2.1, the mid-level SCSI code uses virtual addresses
|
823 |
|
|
* in the scatter-gather lists. We need to convert the virtual
|
824 |
|
|
* addresses to physical addresses.
|
825 |
|
|
*/
|
826 |
|
|
struct hw_scatterlist {
|
827 |
|
|
unsigned int address;
|
828 |
|
|
unsigned int length;
|
829 |
|
|
};
|
830 |
|
|
|
831 |
|
|
/*
|
832 |
|
|
* Maximum number of SG segments these cards can support.
|
833 |
|
|
*/
|
834 |
|
|
#define AIC7XXX_MAX_SG 128
|
835 |
|
|
|
836 |
|
|
/*
|
837 |
|
|
* The maximum number of SCBs we could have for ANY type
|
838 |
|
|
* of card. DON'T FORGET TO CHANGE THE SCB MASK IN THE
|
839 |
|
|
* SEQUENCER CODE IF THIS IS MODIFIED!
|
840 |
|
|
*/
|
841 |
|
|
#define AIC7XXX_MAXSCB 255
|
842 |
|
|
|
843 |
|
|
|
844 |
|
|
struct aic7xxx_hwscb {
|
845 |
|
|
/* ------------ Begin hardware supported fields ---------------- */
|
846 |
|
|
/* 0*/ unsigned char control;
|
847 |
|
|
/* 1*/ unsigned char target_channel_lun; /* 4/1/3 bits */
|
848 |
|
|
/* 2*/ unsigned char target_status;
|
849 |
|
|
/* 3*/ unsigned char SG_segment_count;
|
850 |
|
|
/* 4*/ unsigned int SG_list_pointer;
|
851 |
|
|
/* 8*/ unsigned char residual_SG_segment_count;
|
852 |
|
|
/* 9*/ unsigned char residual_data_count[3];
|
853 |
|
|
/*12*/ unsigned int data_pointer;
|
854 |
|
|
/*16*/ unsigned int data_count;
|
855 |
|
|
/*20*/ unsigned int SCSI_cmd_pointer;
|
856 |
|
|
/*24*/ unsigned char SCSI_cmd_length;
|
857 |
|
|
/*25*/ unsigned char tag; /* Index into our kernel SCB array.
|
858 |
|
|
* Also used as the tag for tagged I/O
|
859 |
|
|
*/
|
860 |
|
|
#define SCB_PIO_TRANSFER_SIZE 26 /* amount we need to upload/download
|
861 |
|
|
* via PIO to initialize a transaction.
|
862 |
|
|
*/
|
863 |
|
|
/*26*/ unsigned char next; /* Used to thread SCBs awaiting selection
|
864 |
|
|
* or disconnected down in the sequencer.
|
865 |
|
|
*/
|
866 |
|
|
/*27*/ unsigned char prev;
|
867 |
|
|
/*28*/ unsigned int pad; /*
|
868 |
|
|
* Unused by the kernel, but we require
|
869 |
|
|
* the padding so that the array of
|
870 |
|
|
* hardware SCBs is alligned on 32 byte
|
871 |
|
|
* boundaries so the sequencer can index
|
872 |
|
|
*/
|
873 |
|
|
};
|
874 |
|
|
|
875 |
|
|
typedef enum {
|
876 |
|
|
SCB_FREE = 0x0000,
|
877 |
|
|
SCB_WAITINGQ = 0x0002,
|
878 |
|
|
SCB_ACTIVE = 0x0004,
|
879 |
|
|
SCB_SENSE = 0x0008,
|
880 |
|
|
SCB_ABORT = 0x0010,
|
881 |
|
|
SCB_DEVICE_RESET = 0x0020,
|
882 |
|
|
SCB_RESET = 0x0040,
|
883 |
|
|
SCB_RECOVERY_SCB = 0x0080,
|
884 |
|
|
SCB_WAS_BUSY = 0x0100,
|
885 |
|
|
SCB_MSGOUT_SENT = 0x0200,
|
886 |
|
|
SCB_MSGOUT_SDTR = 0x0400,
|
887 |
|
|
SCB_MSGOUT_WDTR = 0x0800,
|
888 |
|
|
SCB_MSGOUT_BITS = SCB_MSGOUT_SENT |
|
889 |
|
|
SCB_MSGOUT_SDTR |
|
890 |
|
|
SCB_MSGOUT_WDTR,
|
891 |
|
|
SCB_QUEUED_ABORT = 0x1000,
|
892 |
|
|
SCB_QUEUED_FOR_DONE = 0x2000
|
893 |
|
|
} scb_flag_type;
|
894 |
|
|
|
895 |
|
|
typedef enum {
|
896 |
|
|
AHC_FNONE = 0x00000000,
|
897 |
|
|
AHC_PAGESCBS = 0x00000001,
|
898 |
|
|
AHC_CHANNEL_B_PRIMARY = 0x00000002,
|
899 |
|
|
AHC_USEDEFAULTS = 0x00000004,
|
900 |
|
|
AHC_INDIRECT_PAGING = 0x00000008,
|
901 |
|
|
AHC_CHNLB = 0x00000020,
|
902 |
|
|
AHC_CHNLC = 0x00000040,
|
903 |
|
|
AHC_EXTEND_TRANS_A = 0x00000100,
|
904 |
|
|
AHC_EXTEND_TRANS_B = 0x00000200,
|
905 |
|
|
AHC_TERM_ENB_A = 0x00000400,
|
906 |
|
|
AHC_TERM_ENB_SE_LOW = 0x00000400,
|
907 |
|
|
AHC_TERM_ENB_B = 0x00000800,
|
908 |
|
|
AHC_TERM_ENB_SE_HIGH = 0x00000800,
|
909 |
|
|
AHC_HANDLING_REQINITS = 0x00001000,
|
910 |
|
|
AHC_TARGETMODE = 0x00002000,
|
911 |
|
|
AHC_NEWEEPROM_FMT = 0x00004000,
|
912 |
|
|
/*
|
913 |
|
|
* Here ends the FreeBSD defined flags and here begins the linux defined
|
914 |
|
|
* flags. NOTE: I did not preserve the old flag name during this change
|
915 |
|
|
* specifically to force me to evaluate what flags were being used properly
|
916 |
|
|
* and what flags weren't. This way, I could clean up the flag usage on
|
917 |
|
|
* a use by use basis. Doug Ledford
|
918 |
|
|
*/
|
919 |
|
|
AHC_RESET_DELAY = 0x00080000,
|
920 |
|
|
AHC_A_SCANNED = 0x00100000,
|
921 |
|
|
AHC_B_SCANNED = 0x00200000,
|
922 |
|
|
AHC_MULTI_CHANNEL = 0x00400000,
|
923 |
|
|
AHC_BIOS_ENABLED = 0x00800000,
|
924 |
|
|
AHC_SEEPROM_FOUND = 0x01000000,
|
925 |
|
|
AHC_TERM_ENB_LVD = 0x02000000,
|
926 |
|
|
AHC_ABORT_PENDING = 0x04000000,
|
927 |
|
|
AHC_RESET_PENDING = 0x08000000,
|
928 |
|
|
#define AHC_IN_ISR_BIT 28
|
929 |
|
|
AHC_IN_ISR = 0x10000000,
|
930 |
|
|
AHC_IN_ABORT = 0x20000000,
|
931 |
|
|
AHC_IN_RESET = 0x40000000,
|
932 |
|
|
AHC_EXTERNAL_SRAM = 0x80000000
|
933 |
|
|
} ahc_flag_type;
|
934 |
|
|
|
935 |
|
|
typedef enum {
|
936 |
|
|
AHC_NONE = 0x0000,
|
937 |
|
|
AHC_CHIPID_MASK = 0x00ff,
|
938 |
|
|
AHC_AIC7770 = 0x0001,
|
939 |
|
|
AHC_AIC7850 = 0x0002,
|
940 |
|
|
AHC_AIC7860 = 0x0003,
|
941 |
|
|
AHC_AIC7870 = 0x0004,
|
942 |
|
|
AHC_AIC7880 = 0x0005,
|
943 |
|
|
AHC_AIC7890 = 0x0006,
|
944 |
|
|
AHC_AIC7895 = 0x0007,
|
945 |
|
|
AHC_AIC7896 = 0x0008,
|
946 |
|
|
AHC_AIC7892 = 0x0009,
|
947 |
|
|
AHC_AIC7899 = 0x000a,
|
948 |
|
|
AHC_VL = 0x0100,
|
949 |
|
|
AHC_EISA = 0x0200,
|
950 |
|
|
AHC_PCI = 0x0400,
|
951 |
|
|
} ahc_chip;
|
952 |
|
|
|
953 |
|
|
typedef enum {
|
954 |
|
|
AHC_FENONE = 0x0000,
|
955 |
|
|
AHC_ULTRA = 0x0001,
|
956 |
|
|
AHC_ULTRA2 = 0x0002,
|
957 |
|
|
AHC_WIDE = 0x0004,
|
958 |
|
|
AHC_TWIN = 0x0008,
|
959 |
|
|
AHC_MORE_SRAM = 0x0010,
|
960 |
|
|
AHC_CMD_CHAN = 0x0020,
|
961 |
|
|
AHC_QUEUE_REGS = 0x0040,
|
962 |
|
|
AHC_SG_PRELOAD = 0x0080,
|
963 |
|
|
AHC_SPIOCAP = 0x0100,
|
964 |
|
|
AHC_ULTRA160 = 0x0200,
|
965 |
|
|
AHC_AIC7770_FE = AHC_FENONE,
|
966 |
|
|
AHC_AIC7850_FE = AHC_SPIOCAP,
|
967 |
|
|
AHC_AIC7860_FE = AHC_ULTRA|AHC_SPIOCAP,
|
968 |
|
|
AHC_AIC7870_FE = AHC_FENONE,
|
969 |
|
|
AHC_AIC7880_FE = AHC_ULTRA,
|
970 |
|
|
AHC_AIC7890_FE = AHC_MORE_SRAM|AHC_CMD_CHAN|AHC_ULTRA2|
|
971 |
|
|
AHC_QUEUE_REGS|AHC_SG_PRELOAD,
|
972 |
|
|
AHC_AIC7895_FE = AHC_MORE_SRAM|AHC_CMD_CHAN|AHC_ULTRA,
|
973 |
|
|
AHC_AIC7896_FE = AHC_AIC7890_FE,
|
974 |
|
|
AHC_AIC7892_FE = AHC_AIC7890_FE|AHC_ULTRA160,
|
975 |
|
|
AHC_AIC7899_FE = AHC_AIC7890_FE|AHC_ULTRA160,
|
976 |
|
|
} ahc_feature;
|
977 |
|
|
|
978 |
|
|
struct aic7xxx_scb {
|
979 |
|
|
struct aic7xxx_hwscb *hscb; /* corresponding hardware scb */
|
980 |
|
|
Scsi_Cmnd *cmd; /* Scsi_Cmnd for this scb */
|
981 |
|
|
struct aic7xxx_scb *q_next; /* next scb in queue */
|
982 |
|
|
volatile scb_flag_type flags; /* current state of scb */
|
983 |
|
|
struct hw_scatterlist *sg_list; /* SG list in adapter format */
|
984 |
|
|
unsigned char tag_action;
|
985 |
|
|
unsigned char sg_count;
|
986 |
|
|
unsigned char sense_cmd[6]; /*
|
987 |
|
|
* Allocate 6 characters for
|
988 |
|
|
* sense command.
|
989 |
|
|
*/
|
990 |
|
|
unsigned int sg_length; /* We init this during buildscb so we
|
991 |
|
|
* don't have to calculate anything
|
992 |
|
|
* during underflow/overflow/stat code
|
993 |
|
|
*/
|
994 |
|
|
void *kmalloc_ptr;
|
995 |
|
|
};
|
996 |
|
|
|
997 |
|
|
/*
|
998 |
|
|
* Define a linked list of SCBs.
|
999 |
|
|
*/
|
1000 |
|
|
typedef struct {
|
1001 |
|
|
struct aic7xxx_scb *head;
|
1002 |
|
|
struct aic7xxx_scb *tail;
|
1003 |
|
|
} scb_queue_type;
|
1004 |
|
|
|
1005 |
|
|
static struct {
|
1006 |
|
|
unsigned char errno;
|
1007 |
|
|
const char *errmesg;
|
1008 |
|
|
} hard_error[] = {
|
1009 |
|
|
{ ILLHADDR, "Illegal Host Access" },
|
1010 |
|
|
{ ILLSADDR, "Illegal Sequencer Address referenced" },
|
1011 |
|
|
{ ILLOPCODE, "Illegal Opcode in sequencer program" },
|
1012 |
|
|
{ SQPARERR, "Sequencer Ram Parity Error" },
|
1013 |
|
|
{ DPARERR, "Data-Path Ram Parity Error" },
|
1014 |
|
|
{ MPARERR, "Scratch Ram/SCB Array Ram Parity Error" },
|
1015 |
|
|
{ PCIERRSTAT,"PCI Error detected" },
|
1016 |
|
|
{ CIOPARERR, "CIOBUS Parity Error" }
|
1017 |
|
|
};
|
1018 |
|
|
|
1019 |
|
|
static unsigned char
|
1020 |
|
|
generic_sense[] = { REQUEST_SENSE, 0, 0, 0, 255, 0 };
|
1021 |
|
|
|
1022 |
|
|
typedef struct {
|
1023 |
|
|
scb_queue_type free_scbs; /*
|
1024 |
|
|
* SCBs assigned to free slot on
|
1025 |
|
|
* card (no paging required)
|
1026 |
|
|
*/
|
1027 |
|
|
struct aic7xxx_scb *scb_array[AIC7XXX_MAXSCB];
|
1028 |
|
|
struct aic7xxx_hwscb *hscbs;
|
1029 |
|
|
unsigned char numscbs; /* current number of scbs */
|
1030 |
|
|
unsigned char maxhscbs; /* hardware scbs */
|
1031 |
|
|
unsigned char maxscbs; /* max scbs including pageable scbs */
|
1032 |
|
|
void *hscb_kmalloc_ptr;
|
1033 |
|
|
} scb_data_type;
|
1034 |
|
|
|
1035 |
|
|
struct target_cmd {
|
1036 |
|
|
unsigned char mesg_bytes[4];
|
1037 |
|
|
unsigned char command[28];
|
1038 |
|
|
};
|
1039 |
|
|
|
1040 |
|
|
#define AHC_TRANS_CUR 0x0001
|
1041 |
|
|
#define AHC_TRANS_ACTIVE 0x0002
|
1042 |
|
|
#define AHC_TRANS_GOAL 0x0004
|
1043 |
|
|
#define AHC_TRANS_USER 0x0008
|
1044 |
|
|
#define AHC_TRANS_QUITE 0x0010
|
1045 |
|
|
typedef struct {
|
1046 |
|
|
unsigned char cur_width;
|
1047 |
|
|
unsigned char goal_width;
|
1048 |
|
|
unsigned char cur_period;
|
1049 |
|
|
unsigned char goal_period;
|
1050 |
|
|
unsigned char cur_offset;
|
1051 |
|
|
unsigned char goal_offset;
|
1052 |
|
|
unsigned char user_width;
|
1053 |
|
|
unsigned char user_period;
|
1054 |
|
|
unsigned char user_offset;
|
1055 |
|
|
} transinfo_type;
|
1056 |
|
|
|
1057 |
|
|
/*
|
1058 |
|
|
* Define a structure used for each host adapter. Note, in order to avoid
|
1059 |
|
|
* problems with architectures I can't test on (because I don't have one,
|
1060 |
|
|
* such as the Alpha based systems) which happen to give faults for
|
1061 |
|
|
* non-aligned memory accesses, care was taken to align this structure
|
1062 |
|
|
* in a way that gauranteed all accesses larger than 8 bits were aligned
|
1063 |
|
|
* on the appropriate boundary. It's also organized to try and be more
|
1064 |
|
|
* cache line efficient. Be careful when changing this lest you might hurt
|
1065 |
|
|
* overall performance and bring down the wrath of the masses.
|
1066 |
|
|
*/
|
1067 |
|
|
struct aic7xxx_host {
|
1068 |
|
|
/*
|
1069 |
|
|
* This is the first 64 bytes in the host struct
|
1070 |
|
|
*/
|
1071 |
|
|
|
1072 |
|
|
/*
|
1073 |
|
|
* We are grouping things here....first, items that get either read or
|
1074 |
|
|
* written with nearly every interrupt
|
1075 |
|
|
*/
|
1076 |
|
|
volatile ahc_flag_type flags;
|
1077 |
|
|
ahc_feature features; /* chip features */
|
1078 |
|
|
unsigned long base; /* card base address */
|
1079 |
|
|
volatile unsigned char *maddr; /* memory mapped address */
|
1080 |
|
|
unsigned long isr_count; /* Interrupt count */
|
1081 |
|
|
unsigned long spurious_int;
|
1082 |
|
|
scb_data_type *scb_data;
|
1083 |
|
|
volatile unsigned short needsdtr;
|
1084 |
|
|
volatile unsigned short sdtr_pending;
|
1085 |
|
|
volatile unsigned short needwdtr;
|
1086 |
|
|
volatile unsigned short wdtr_pending;
|
1087 |
|
|
struct aic7xxx_cmd_queue {
|
1088 |
|
|
Scsi_Cmnd *head;
|
1089 |
|
|
Scsi_Cmnd *tail;
|
1090 |
|
|
} completeq;
|
1091 |
|
|
|
1092 |
|
|
/*
|
1093 |
|
|
* Things read/written on nearly every entry into aic7xxx_queue()
|
1094 |
|
|
*/
|
1095 |
|
|
volatile scb_queue_type waiting_scbs;
|
1096 |
|
|
unsigned short discenable; /* Targets allowed to disconnect */
|
1097 |
|
|
unsigned short tagenable; /* Targets using tagged I/O */
|
1098 |
|
|
unsigned short orderedtag; /* Ordered Q tags allowed */
|
1099 |
|
|
unsigned char unpause; /* unpause value for HCNTRL */
|
1100 |
|
|
unsigned char pause; /* pause value for HCNTRL */
|
1101 |
|
|
volatile unsigned char qoutfifonext;
|
1102 |
|
|
volatile unsigned char activescbs; /* active scbs */
|
1103 |
|
|
volatile unsigned char max_activescbs;
|
1104 |
|
|
volatile unsigned char qinfifonext;
|
1105 |
|
|
|
1106 |
|
|
#define DEVICE_PRESENT 0x01
|
1107 |
|
|
#define BUS_DEVICE_RESET_PENDING 0x02
|
1108 |
|
|
#define DEVICE_RESET_DELAY 0x04
|
1109 |
|
|
#define DEVICE_PRINT_SDTR 0x08
|
1110 |
|
|
#define DEVICE_PRINT_WDTR 0x10
|
1111 |
|
|
#define DEVICE_WAS_BUSY 0x20
|
1112 |
|
|
#define DEVICE_SCANNED 0x80
|
1113 |
|
|
volatile unsigned char dev_flags[MAX_TARGETS];
|
1114 |
|
|
volatile unsigned char dev_active_cmds[MAX_TARGETS];
|
1115 |
|
|
volatile unsigned char dev_temp_queue_depth[MAX_TARGETS];
|
1116 |
|
|
unsigned char dev_commands_sent[MAX_TARGETS];
|
1117 |
|
|
|
1118 |
|
|
unsigned int dev_timer_active; /* Which devs have a timer set */
|
1119 |
|
|
struct timer_list dev_timer;
|
1120 |
|
|
unsigned long dev_expires[MAX_TARGETS];
|
1121 |
|
|
|
1122 |
|
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
|
1123 |
|
|
spinlock_t spin_lock;
|
1124 |
|
|
volatile unsigned char cpu_lock_count[NR_CPUS];
|
1125 |
|
|
#endif
|
1126 |
|
|
|
1127 |
|
|
|
1128 |
|
|
#ifdef AIC7XXX_FAKE_NEGOTIATION_CMDS
|
1129 |
|
|
Scsi_Cmnd *dev_wdtr_cmnd[MAX_TARGETS];
|
1130 |
|
|
Scsi_Cmnd *dev_sdtr_cmnd[MAX_TARGETS];
|
1131 |
|
|
#endif
|
1132 |
|
|
|
1133 |
|
|
unsigned char dev_last_queue_full[MAX_TARGETS];
|
1134 |
|
|
unsigned char dev_last_queue_full_count[MAX_TARGETS];
|
1135 |
|
|
unsigned char dev_max_queue_depth[MAX_TARGETS];
|
1136 |
|
|
|
1137 |
|
|
volatile scb_queue_type delayed_scbs[MAX_TARGETS];
|
1138 |
|
|
|
1139 |
|
|
|
1140 |
|
|
unsigned char msg_buf[9]; /* The message for the target */
|
1141 |
|
|
unsigned char msg_type;
|
1142 |
|
|
#define MSG_TYPE_NONE 0x00
|
1143 |
|
|
#define MSG_TYPE_INITIATOR_MSGOUT 0x01
|
1144 |
|
|
#define MSG_TYPE_INITIATOR_MSGIN 0x02
|
1145 |
|
|
unsigned char msg_len; /* Length of message */
|
1146 |
|
|
unsigned char msg_index; /* Index into msg_buf array */
|
1147 |
|
|
transinfo_type transinfo[MAX_TARGETS];
|
1148 |
|
|
|
1149 |
|
|
|
1150 |
|
|
/*
|
1151 |
|
|
* We put the less frequently used host structure items after the more
|
1152 |
|
|
* frequently used items to try and ease the burden on the cache subsystem.
|
1153 |
|
|
* These entries are not *commonly* accessed, whereas the preceding entries
|
1154 |
|
|
* are accessed very often. The only exceptions are the qinfifo, qoutfifo,
|
1155 |
|
|
* and untagged_scbs array. But, they are often accessed only once and each
|
1156 |
|
|
* access into these arrays is likely to blow a cache line, so they are put
|
1157 |
|
|
* down here so we can minimize the number of cache lines required to hold
|
1158 |
|
|
* the preceeding entries.
|
1159 |
|
|
*/
|
1160 |
|
|
|
1161 |
|
|
volatile unsigned char untagged_scbs[256];
|
1162 |
|
|
volatile unsigned char qoutfifo[256];
|
1163 |
|
|
volatile unsigned char qinfifo[256];
|
1164 |
|
|
unsigned int irq; /* IRQ for this adapter */
|
1165 |
|
|
int instance; /* aic7xxx instance number */
|
1166 |
|
|
int scsi_id; /* host adapter SCSI ID */
|
1167 |
|
|
int scsi_id_b; /* channel B for twin adapters */
|
1168 |
|
|
unsigned int bios_address;
|
1169 |
|
|
int board_name_index;
|
1170 |
|
|
unsigned short needsdtr_copy; /* default config */
|
1171 |
|
|
unsigned short needwdtr_copy; /* default config */
|
1172 |
|
|
unsigned short ultraenb; /* Ultra mode target list */
|
1173 |
|
|
unsigned short bios_control; /* bios control - SEEPROM */
|
1174 |
|
|
unsigned short adapter_control; /* adapter control - SEEPROM */
|
1175 |
|
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
|
1176 |
|
|
struct pci_dev *pdev;
|
1177 |
|
|
#endif
|
1178 |
|
|
unsigned char pci_bus;
|
1179 |
|
|
unsigned char pci_device_fn;
|
1180 |
|
|
struct seeprom_config sc;
|
1181 |
|
|
unsigned short sc_type;
|
1182 |
|
|
unsigned short sc_size;
|
1183 |
|
|
struct aic7xxx_host *next; /* allow for multiple IRQs */
|
1184 |
|
|
struct Scsi_Host *host; /* pointer to scsi host */
|
1185 |
|
|
int host_no; /* SCSI host number */
|
1186 |
|
|
unsigned long mbase; /* I/O memory address */
|
1187 |
|
|
ahc_chip chip; /* chip type */
|
1188 |
|
|
|
1189 |
|
|
/*
|
1190 |
|
|
* Statistics Kept:
|
1191 |
|
|
*
|
1192 |
|
|
* Total Xfers (count for each command that has a data xfer),
|
1193 |
|
|
* broken down further by reads && writes.
|
1194 |
|
|
*
|
1195 |
|
|
* Binned sizes, writes && reads:
|
1196 |
|
|
* < 512, 512, 1-2K, 2-4K, 4-8K, 8-16K, 16-32K, 32-64K, 64K-128K, > 128K
|
1197 |
|
|
*
|
1198 |
|
|
* Total amounts read/written above 512 bytes (amts under ignored)
|
1199 |
|
|
*
|
1200 |
|
|
* NOTE: Enabling this feature is likely to cause a noticeable performance
|
1201 |
|
|
* decrease as the accesses into the stats structures blows apart multiple
|
1202 |
|
|
* cache lines and is CPU time consuming.
|
1203 |
|
|
*
|
1204 |
|
|
* NOTE: Since it doesn't really buy us much, but consumes *tons* of RAM
|
1205 |
|
|
* and blows apart all sorts of cache lines, I modified this so that we
|
1206 |
|
|
* no longer look at the LUN. All LUNs now go into the same bin on each
|
1207 |
|
|
* device for stats purposes.
|
1208 |
|
|
*/
|
1209 |
|
|
struct aic7xxx_xferstats {
|
1210 |
|
|
long w_total; /* total writes */
|
1211 |
|
|
long r_total; /* total reads */
|
1212 |
|
|
#ifdef AIC7XXX_PROC_STATS
|
1213 |
|
|
long w_bins[8]; /* binned write */
|
1214 |
|
|
long r_bins[8]; /* binned reads */
|
1215 |
|
|
#endif /* AIC7XXX_PROC_STATS */
|
1216 |
|
|
} stats[MAX_TARGETS]; /* [(channel << 3)|target] */
|
1217 |
|
|
|
1218 |
|
|
#if 0
|
1219 |
|
|
struct target_cmd *targetcmds;
|
1220 |
|
|
unsigned int num_targetcmds;
|
1221 |
|
|
#endif
|
1222 |
|
|
|
1223 |
|
|
};
|
1224 |
|
|
|
1225 |
|
|
/*
|
1226 |
|
|
* Valid SCSIRATE values. (p. 3-17)
|
1227 |
|
|
* Provides a mapping of transfer periods in ns/4 to the proper value to
|
1228 |
|
|
* stick in the SCSIRATE reg to use that transfer rate.
|
1229 |
|
|
*/
|
1230 |
|
|
#define AHC_SYNCRATE_ULTRA2 0
|
1231 |
|
|
#define AHC_SYNCRATE_ULTRA 2
|
1232 |
|
|
#define AHC_SYNCRATE_FAST 5
|
1233 |
|
|
static struct aic7xxx_syncrate {
|
1234 |
|
|
/* Rates in Ultra mode have bit 8 of sxfr set */
|
1235 |
|
|
#define ULTRA_SXFR 0x100
|
1236 |
|
|
int sxfr_ultra2;
|
1237 |
|
|
int sxfr;
|
1238 |
|
|
unsigned char period;
|
1239 |
|
|
const char *rate[2];
|
1240 |
|
|
} aic7xxx_syncrates[] = {
|
1241 |
|
|
{ 0x13, 0x000, 10, {"40.0", "80.0"} },
|
1242 |
|
|
{ 0x14, 0x000, 11, {"33.0", "66.6"} },
|
1243 |
|
|
{ 0x15, 0x100, 12, {"20.0", "40.0"} },
|
1244 |
|
|
{ 0x16, 0x110, 15, {"16.0", "32.0"} },
|
1245 |
|
|
{ 0x17, 0x120, 18, {"13.4", "26.8"} },
|
1246 |
|
|
{ 0x18, 0x000, 25, {"10.0", "20.0"} },
|
1247 |
|
|
{ 0x19, 0x010, 31, {"8.0", "16.0"} },
|
1248 |
|
|
{ 0x1a, 0x020, 37, {"6.67", "13.3"} },
|
1249 |
|
|
{ 0x1b, 0x030, 43, {"5.7", "11.4"} },
|
1250 |
|
|
{ 0x10, 0x040, 50, {"5.0", "10.0"} },
|
1251 |
|
|
{ 0x00, 0x050, 56, {"4.4", "8.8" } },
|
1252 |
|
|
{ 0x00, 0x060, 62, {"4.0", "8.0" } },
|
1253 |
|
|
{ 0x00, 0x070, 68, {"3.6", "7.2" } },
|
1254 |
|
|
{ 0x00, 0x000, 0, {NULL, NULL} },
|
1255 |
|
|
};
|
1256 |
|
|
|
1257 |
|
|
#define CTL_OF_SCB(scb) (((scb->hscb)->target_channel_lun >> 3) & 0x1), \
|
1258 |
|
|
(((scb->hscb)->target_channel_lun >> 4) & 0xf), \
|
1259 |
|
|
((scb->hscb)->target_channel_lun & 0x07)
|
1260 |
|
|
|
1261 |
|
|
#define CTL_OF_CMD(cmd) ((cmd->channel) & 0x01), \
|
1262 |
|
|
((cmd->target) & 0x0f), \
|
1263 |
|
|
((cmd->lun) & 0x07)
|
1264 |
|
|
|
1265 |
|
|
#define TARGET_INDEX(cmd) ((cmd)->target | ((cmd)->channel << 3))
|
1266 |
|
|
|
1267 |
|
|
/*
|
1268 |
|
|
* A nice little define to make doing our printks a little easier
|
1269 |
|
|
*/
|
1270 |
|
|
|
1271 |
|
|
#define WARN_LEAD KERN_WARNING "(scsi%d:%d:%d:%d) "
|
1272 |
|
|
#define INFO_LEAD KERN_INFO "(scsi%d:%d:%d:%d) "
|
1273 |
|
|
|
1274 |
|
|
/*
|
1275 |
|
|
* XXX - these options apply unilaterally to _all_ 274x/284x/294x
|
1276 |
|
|
* cards in the system. This should be fixed. Exceptions to this
|
1277 |
|
|
* rule are noted in the comments.
|
1278 |
|
|
*/
|
1279 |
|
|
|
1280 |
|
|
|
1281 |
|
|
/*
|
1282 |
|
|
* Skip the scsi bus reset. Non 0 make us skip the reset at startup. This
|
1283 |
|
|
* has no effect on any later resets that might occur due to things like
|
1284 |
|
|
* SCSI bus timeouts.
|
1285 |
|
|
*/
|
1286 |
|
|
static unsigned int aic7xxx_no_reset = 0;
|
1287 |
|
|
/*
|
1288 |
|
|
* Certain PCI motherboards will scan PCI devices from highest to lowest,
|
1289 |
|
|
* others scan from lowest to highest, and they tend to do all kinds of
|
1290 |
|
|
* strange things when they come into contact with PCI bridge chips. The
|
1291 |
|
|
* net result of all this is that the PCI card that is actually used to boot
|
1292 |
|
|
* the machine is very hard to detect. Most motherboards go from lowest
|
1293 |
|
|
* PCI slot number to highest, and the first SCSI controller found is the
|
1294 |
|
|
* one you boot from. The only exceptions to this are when a controller
|
1295 |
|
|
* has its BIOS disabled. So, we by default sort all of our SCSI controllers
|
1296 |
|
|
* from lowest PCI slot number to highest PCI slot number. We also force
|
1297 |
|
|
* all controllers with their BIOS disabled to the end of the list. This
|
1298 |
|
|
* works on *almost* all computers. Where it doesn't work, we have this
|
1299 |
|
|
* option. Setting this option to non-0 will reverse the order of the sort
|
1300 |
|
|
* to highest first, then lowest, but will still leave cards with their BIOS
|
1301 |
|
|
* disabled at the very end. That should fix everyone up unless there are
|
1302 |
|
|
* really strange cirumstances.
|
1303 |
|
|
*/
|
1304 |
|
|
static int aic7xxx_reverse_scan = 0;
|
1305 |
|
|
/*
|
1306 |
|
|
* Should we force EXTENDED translation on a controller.
|
1307 |
|
|
* 0 == Use whatever is in the SEEPROM or default to off
|
1308 |
|
|
* 1 == Use whatever is in the SEEPROM or default to on
|
1309 |
|
|
*/
|
1310 |
|
|
static unsigned int aic7xxx_extended = 0;
|
1311 |
|
|
/*
|
1312 |
|
|
* The IRQ trigger method used on EISA controllers. Does not effect PCI cards.
|
1313 |
|
|
* -1 = Use detected settings.
|
1314 |
|
|
* 0 = Force Edge triggered mode.
|
1315 |
|
|
* 1 = Force Level triggered mode.
|
1316 |
|
|
*/
|
1317 |
|
|
static int aic7xxx_irq_trigger = -1;
|
1318 |
|
|
/*
|
1319 |
|
|
* This variable is used to override the termination settings on a controller.
|
1320 |
|
|
* This should not be used under normal conditions. However, in the case
|
1321 |
|
|
* that a controller does not have a readable SEEPROM (so that we can't
|
1322 |
|
|
* read the SEEPROM settings directly) and that a controller has a buggered
|
1323 |
|
|
* version of the cable detection logic, this can be used to force the
|
1324 |
|
|
* correct termination. It is preferable to use the manual termination
|
1325 |
|
|
* settings in the BIOS if possible, but some motherboard controllers store
|
1326 |
|
|
* those settings in a format we can't read. In other cases, auto term
|
1327 |
|
|
* should also work, but the chipset was put together with no auto term
|
1328 |
|
|
* logic (common on motherboard controllers). In those cases, we have
|
1329 |
|
|
* 32 bits here to work with. That's good for 8 controllers/channels. The
|
1330 |
|
|
* bits are organized as 4 bits per channel, with scsi0 getting the lowest
|
1331 |
|
|
* 4 bits in the int. A 1 in a bit position indicates the termination setting
|
1332 |
|
|
* that corresponds to that bit should be enabled, a 0 is disabled.
|
1333 |
|
|
* It looks something like this:
|
1334 |
|
|
*
|
1335 |
|
|
* 0x0f = 1111-Single Ended Low Byte Termination on/off
|
1336 |
|
|
* ||\-Single Ended High Byte Termination on/off
|
1337 |
|
|
* |\-LVD Low Byte Termination on/off
|
1338 |
|
|
* \-LVD High Byte Termination on/off
|
1339 |
|
|
*
|
1340 |
|
|
* For non-Ultra2 controllers, the upper 2 bits are not important. So, to
|
1341 |
|
|
* enable both high byte and low byte termination on scsi0, I would need to
|
1342 |
|
|
* make sure that the override_term variable was set to 0x03 (bits 0011).
|
1343 |
|
|
* To make sure that all termination is enabled on an Ultra2 controller at
|
1344 |
|
|
* scsi2 and only high byte termination on scsi1 and high and low byte
|
1345 |
|
|
* termination on scsi0, I would set override_term=0xf23 (bits 1111 0010 0011)
|
1346 |
|
|
*
|
1347 |
|
|
* For the most part, users should never have to use this, that's why I
|
1348 |
|
|
* left it fairly cryptic instead of easy to understand. If you need it,
|
1349 |
|
|
* most likely someone will be telling you what your's needs to be set to.
|
1350 |
|
|
*/
|
1351 |
|
|
static int aic7xxx_override_term = -1;
|
1352 |
|
|
/*
|
1353 |
|
|
* Certain motherboard chipset controllers tend to screw
|
1354 |
|
|
* up the polarity of the term enable output pin. Use this variable
|
1355 |
|
|
* to force the correct polarity for your system. This is a bitfield variable
|
1356 |
|
|
* similar to the previous one, but this one has one bit per channel instead
|
1357 |
|
|
* of four.
|
1358 |
|
|
* 0 = Force the setting to active low.
|
1359 |
|
|
* 1 = Force setting to active high.
|
1360 |
|
|
* Most Adaptec cards are active high, several motherboards are active low.
|
1361 |
|
|
* To force a 2940 card at SCSI 0 to active high and a motherboard 7895
|
1362 |
|
|
* controller at scsi1 and scsi2 to active low, and a 2910 card at scsi3
|
1363 |
|
|
* to active high, you would need to set stpwlev=0x9 (bits 1001).
|
1364 |
|
|
*
|
1365 |
|
|
* People shouldn't need to use this, but if you are experiencing lots of
|
1366 |
|
|
* SCSI timeout problems, this may help. There is one sure way to test what
|
1367 |
|
|
* this option needs to be. Using a boot floppy to boot the system, configure
|
1368 |
|
|
* your system to enable all SCSI termination (in the Adaptec SCSI BIOS) and
|
1369 |
|
|
* if needed then also pass a value to override_term to make sure that the
|
1370 |
|
|
* driver is enabling SCSI termination, then set this variable to either 0
|
1371 |
|
|
* or 1. When the driver boots, make sure there are *NO* SCSI cables
|
1372 |
|
|
* connected to your controller. If it finds and inits the controller
|
1373 |
|
|
* without problem, then the setting you passed to stpwlev was correct. If
|
1374 |
|
|
* the driver goes into a reset loop and hangs the system, then you need the
|
1375 |
|
|
* other setting for this variable. If neither setting lets the machine
|
1376 |
|
|
* boot then you have definite termination problems that may not be fixable.
|
1377 |
|
|
*/
|
1378 |
|
|
static int aic7xxx_stpwlev = -1;
|
1379 |
|
|
/*
|
1380 |
|
|
* Set this to non-0 in order to force the driver to panic the kernel
|
1381 |
|
|
* and print out debugging info on a SCSI abort or reset cycle.
|
1382 |
|
|
*/
|
1383 |
|
|
static int aic7xxx_panic_on_abort = 0;
|
1384 |
|
|
/*
|
1385 |
|
|
* PCI bus parity checking of the Adaptec controllers. This is somewhat
|
1386 |
|
|
* dubious at best. To my knowledge, this option has never actually
|
1387 |
|
|
* solved a PCI parity problem, but on certain machines with broken PCI
|
1388 |
|
|
* chipset configurations, it can generate tons of false error messages.
|
1389 |
|
|
* It's included in the driver for completeness.
|
1390 |
|
|
* 0 = Shut off PCI parity check
|
1391 |
|
|
* -1 = Normal polarity pci parity checking
|
1392 |
|
|
* 1 = reverse polarity pci parity checking
|
1393 |
|
|
*
|
1394 |
|
|
* NOTE: you can't actually pass -1 on the lilo prompt. So, to set this
|
1395 |
|
|
* variable to -1 you would actually want to simply pass the variable
|
1396 |
|
|
* name without a number. That will invert the 0 which will result in
|
1397 |
|
|
* -1.
|
1398 |
|
|
*/
|
1399 |
|
|
static int aic7xxx_pci_parity = 0;
|
1400 |
|
|
/*
|
1401 |
|
|
* Set this to any non-0 value to cause us to dump the contents of all
|
1402 |
|
|
* the card's registers in a hex dump format tailored to each model of
|
1403 |
|
|
* controller.
|
1404 |
|
|
*
|
1405 |
|
|
* NOTE: THE CONTROLLER IS LEFT IN AN UNUSEABLE STATE BY THIS OPTION.
|
1406 |
|
|
* YOU CANNOT BOOT UP WITH THIS OPTION, IT IS FOR DEBUGGING PURPOSES
|
1407 |
|
|
* ONLY
|
1408 |
|
|
*/
|
1409 |
|
|
static int aic7xxx_dump_card = 0;
|
1410 |
|
|
/*
|
1411 |
|
|
* Set this to a non-0 value to make us dump out the 32 bit instruction
|
1412 |
|
|
* registers on the card after completing the sequencer download. This
|
1413 |
|
|
* allows the actual sequencer download to be verified. It is possible
|
1414 |
|
|
* to use this option and still boot up and run your system. This is
|
1415 |
|
|
* only intended for debugging purposes.
|
1416 |
|
|
*/
|
1417 |
|
|
static int aic7xxx_dump_sequencer = 0;
|
1418 |
|
|
/*
|
1419 |
|
|
* Certain newer motherboards have put new PCI based devices into the
|
1420 |
|
|
* IO spaces that used to typically be occupied by VLB or EISA cards.
|
1421 |
|
|
* This overlap can cause these newer motherboards to lock up when scanned
|
1422 |
|
|
* for older EISA and VLB devices. Setting this option to non-0 will
|
1423 |
|
|
* cause the driver to skip scanning for any VLB or EISA controllers and
|
1424 |
|
|
* only support the PCI controllers. NOTE: this means that if the kernel
|
1425 |
|
|
* os compiled with PCI support disabled, then setting this to non-0
|
1426 |
|
|
* would result in never finding any devices :)
|
1427 |
|
|
*/
|
1428 |
|
|
static int aic7xxx_no_probe = 0;
|
1429 |
|
|
|
1430 |
|
|
/*
|
1431 |
|
|
* So that insmod can find the variable and make it point to something
|
1432 |
|
|
*/
|
1433 |
|
|
#ifdef MODULE
|
1434 |
|
|
static char * aic7xxx = NULL;
|
1435 |
|
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,18)
|
1436 |
|
|
MODULE_PARM(aic7xxx, "s");
|
1437 |
|
|
#endif
|
1438 |
|
|
|
1439 |
|
|
/*
|
1440 |
|
|
* Just in case someone uses commas to separate items on the insmod
|
1441 |
|
|
* command line, we define a dummy buffer here to avoid having insmod
|
1442 |
|
|
* write wild stuff into our code segment
|
1443 |
|
|
*/
|
1444 |
|
|
static char dummy_buffer[60] = "Please don't trounce on me insmod!!\n";
|
1445 |
|
|
|
1446 |
|
|
#endif
|
1447 |
|
|
|
1448 |
|
|
#define VERBOSE_NORMAL 0x0000
|
1449 |
|
|
#define VERBOSE_NEGOTIATION 0x0001
|
1450 |
|
|
#define VERBOSE_SEQINT 0x0002
|
1451 |
|
|
#define VERBOSE_SCSIINT 0x0004
|
1452 |
|
|
#define VERBOSE_PROBE 0x0008
|
1453 |
|
|
#define VERBOSE_PROBE2 0x0010
|
1454 |
|
|
#define VERBOSE_NEGOTIATION2 0x0020
|
1455 |
|
|
#define VERBOSE_MINOR_ERROR 0x0040
|
1456 |
|
|
#define VERBOSE_TRACING 0x0080
|
1457 |
|
|
#define VERBOSE_ABORT 0x0f00
|
1458 |
|
|
#define VERBOSE_ABORT_MID 0x0100
|
1459 |
|
|
#define VERBOSE_ABORT_FIND 0x0200
|
1460 |
|
|
#define VERBOSE_ABORT_PROCESS 0x0400
|
1461 |
|
|
#define VERBOSE_ABORT_RETURN 0x0800
|
1462 |
|
|
#define VERBOSE_RESET 0xf000
|
1463 |
|
|
#define VERBOSE_RESET_MID 0x1000
|
1464 |
|
|
#define VERBOSE_RESET_FIND 0x2000
|
1465 |
|
|
#define VERBOSE_RESET_PROCESS 0x4000
|
1466 |
|
|
#define VERBOSE_RESET_RETURN 0x8000
|
1467 |
|
|
static int aic7xxx_verbose = VERBOSE_NORMAL | VERBOSE_NEGOTIATION |
|
1468 |
|
|
VERBOSE_PROBE; /* verbose messages */
|
1469 |
|
|
|
1470 |
|
|
|
1471 |
|
|
/****************************************************************************
|
1472 |
|
|
*
|
1473 |
|
|
* We're going to start putting in function declarations so that order of
|
1474 |
|
|
* functions is no longer important. As needed, they are added here.
|
1475 |
|
|
*
|
1476 |
|
|
***************************************************************************/
|
1477 |
|
|
|
1478 |
|
|
static void aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd);
|
1479 |
|
|
static void aic7xxx_print_card(struct aic7xxx_host *p);
|
1480 |
|
|
static void aic7xxx_print_scratch_ram(struct aic7xxx_host *p);
|
1481 |
|
|
static void aic7xxx_print_sequencer(struct aic7xxx_host *p, int downloaded);
|
1482 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
1483 |
|
|
static void aic7xxx_check_scbs(struct aic7xxx_host *p, char *buffer);
|
1484 |
|
|
#endif
|
1485 |
|
|
|
1486 |
|
|
/****************************************************************************
|
1487 |
|
|
*
|
1488 |
|
|
* These functions are now used. They happen to be wrapped in useless
|
1489 |
|
|
* inb/outb port read/writes around the real reads and writes because it
|
1490 |
|
|
* seems that certain very fast CPUs have a problem dealing with us when
|
1491 |
|
|
* going at full speed.
|
1492 |
|
|
*
|
1493 |
|
|
***************************************************************************/
|
1494 |
|
|
|
1495 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
|
1496 |
|
|
static inline void
|
1497 |
|
|
mdelay(int milliseconds)
|
1498 |
|
|
{
|
1499 |
|
|
int i;
|
1500 |
|
|
|
1501 |
|
|
for(i=0; i<milliseconds; i++)
|
1502 |
|
|
udelay(1000);
|
1503 |
|
|
}
|
1504 |
|
|
|
1505 |
|
|
static inline int
|
1506 |
|
|
time_after_eq(unsigned long a, unsigned long b)
|
1507 |
|
|
{
|
1508 |
|
|
return((long)((a) - (b)) >= 0L);
|
1509 |
|
|
}
|
1510 |
|
|
|
1511 |
|
|
static inline int
|
1512 |
|
|
timer_pending(struct timer_list *timer)
|
1513 |
|
|
{
|
1514 |
|
|
return( timer->prev != NULL );
|
1515 |
|
|
}
|
1516 |
|
|
|
1517 |
|
|
#define PCI_DEVICE_ID_ADAPTEC_1480A 0x6075
|
1518 |
|
|
|
1519 |
|
|
#endif
|
1520 |
|
|
|
1521 |
|
|
static inline unsigned char
|
1522 |
|
|
aic_inb(struct aic7xxx_host *p, long port)
|
1523 |
|
|
{
|
1524 |
|
|
#ifdef MMAPIO
|
1525 |
|
|
unsigned char x;
|
1526 |
|
|
if(p->maddr)
|
1527 |
|
|
{
|
1528 |
|
|
x = p->maddr[port];
|
1529 |
|
|
}
|
1530 |
|
|
else
|
1531 |
|
|
{
|
1532 |
|
|
x = inb(p->base + port);
|
1533 |
|
|
}
|
1534 |
|
|
mb();
|
1535 |
|
|
return(x);
|
1536 |
|
|
#else
|
1537 |
|
|
return(inb(p->base + port));
|
1538 |
|
|
#endif
|
1539 |
|
|
}
|
1540 |
|
|
|
1541 |
|
|
static inline void
|
1542 |
|
|
aic_outb(struct aic7xxx_host *p, unsigned char val, long port)
|
1543 |
|
|
{
|
1544 |
|
|
#ifdef MMAPIO
|
1545 |
|
|
if(p->maddr)
|
1546 |
|
|
{
|
1547 |
|
|
p->maddr[port] = val;
|
1548 |
|
|
}
|
1549 |
|
|
else
|
1550 |
|
|
{
|
1551 |
|
|
outb(val, p->base + port);
|
1552 |
|
|
}
|
1553 |
|
|
mb();
|
1554 |
|
|
#else
|
1555 |
|
|
outb(val, p->base + port);
|
1556 |
|
|
#endif
|
1557 |
|
|
}
|
1558 |
|
|
|
1559 |
|
|
/*+F*************************************************************************
|
1560 |
|
|
* Function:
|
1561 |
|
|
* aic7xxx_setup
|
1562 |
|
|
*
|
1563 |
|
|
* Description:
|
1564 |
|
|
* Handle Linux boot parameters. This routine allows for assigning a value
|
1565 |
|
|
* to a parameter with a ':' between the parameter and the value.
|
1566 |
|
|
* ie. aic7xxx=unpause:0x0A,extended
|
1567 |
|
|
*-F*************************************************************************/
|
1568 |
|
|
void
|
1569 |
|
|
aic7xxx_setup(char *s, int *dummy)
|
1570 |
|
|
{
|
1571 |
|
|
int i, n;
|
1572 |
|
|
char *p;
|
1573 |
|
|
char *end;
|
1574 |
|
|
|
1575 |
|
|
static struct {
|
1576 |
|
|
const char *name;
|
1577 |
|
|
unsigned int *flag;
|
1578 |
|
|
} options[] = {
|
1579 |
|
|
{ "extended", &aic7xxx_extended },
|
1580 |
|
|
{ "no_reset", &aic7xxx_no_reset },
|
1581 |
|
|
{ "irq_trigger", &aic7xxx_irq_trigger },
|
1582 |
|
|
{ "verbose", &aic7xxx_verbose },
|
1583 |
|
|
{ "reverse_scan",&aic7xxx_reverse_scan },
|
1584 |
|
|
{ "override_term", &aic7xxx_override_term },
|
1585 |
|
|
{ "stpwlev", &aic7xxx_stpwlev },
|
1586 |
|
|
{ "no_probe", &aic7xxx_no_probe },
|
1587 |
|
|
{ "panic_on_abort", &aic7xxx_panic_on_abort },
|
1588 |
|
|
{ "pci_parity", &aic7xxx_pci_parity },
|
1589 |
|
|
{ "dump_card", &aic7xxx_dump_card },
|
1590 |
|
|
{ "dump_sequencer", &aic7xxx_dump_sequencer },
|
1591 |
|
|
{ "tag_info", NULL }
|
1592 |
|
|
};
|
1593 |
|
|
|
1594 |
|
|
end = strchr(s, '\0');
|
1595 |
|
|
|
1596 |
|
|
for (p = strtok(s, ",."); p; p = strtok(NULL, ",."))
|
1597 |
|
|
{
|
1598 |
|
|
for (i = 0; i < NUMBER(options); i++)
|
1599 |
|
|
{
|
1600 |
|
|
n = strlen(options[i].name);
|
1601 |
|
|
if (!strncmp(options[i].name, p, n))
|
1602 |
|
|
{
|
1603 |
|
|
if (!strncmp(p, "tag_info", n))
|
1604 |
|
|
{
|
1605 |
|
|
if (p[n] == ':')
|
1606 |
|
|
{
|
1607 |
|
|
char *base;
|
1608 |
|
|
char *tok, *tok_end, *tok_end2;
|
1609 |
|
|
char tok_list[] = { '.', ',', '{', '}', '\0' };
|
1610 |
|
|
int i, instance = -1, device = -1;
|
1611 |
|
|
unsigned char done = FALSE;
|
1612 |
|
|
|
1613 |
|
|
base = p;
|
1614 |
|
|
tok = base + n + 1; /* Forward us just past the ':' */
|
1615 |
|
|
tok_end = strchr(tok, '\0');
|
1616 |
|
|
if (tok_end < end)
|
1617 |
|
|
*tok_end = ',';
|
1618 |
|
|
while(!done)
|
1619 |
|
|
{
|
1620 |
|
|
switch(*tok)
|
1621 |
|
|
{
|
1622 |
|
|
case '{':
|
1623 |
|
|
if (instance == -1)
|
1624 |
|
|
instance = 0;
|
1625 |
|
|
else if (device == -1)
|
1626 |
|
|
device = 0;
|
1627 |
|
|
tok++;
|
1628 |
|
|
break;
|
1629 |
|
|
case '}':
|
1630 |
|
|
if (device != -1)
|
1631 |
|
|
device = -1;
|
1632 |
|
|
else if (instance != -1)
|
1633 |
|
|
instance = -1;
|
1634 |
|
|
tok++;
|
1635 |
|
|
break;
|
1636 |
|
|
case ',':
|
1637 |
|
|
case '.':
|
1638 |
|
|
if (instance == -1)
|
1639 |
|
|
done = TRUE;
|
1640 |
|
|
else if (device >= 0)
|
1641 |
|
|
device++;
|
1642 |
|
|
else if (instance >= 0)
|
1643 |
|
|
instance++;
|
1644 |
|
|
if ( (device >= MAX_TARGETS) ||
|
1645 |
|
|
(instance >= NUMBER(aic7xxx_tag_info)) )
|
1646 |
|
|
done = TRUE;
|
1647 |
|
|
tok++;
|
1648 |
|
|
if (!done)
|
1649 |
|
|
{
|
1650 |
|
|
base = tok;
|
1651 |
|
|
}
|
1652 |
|
|
break;
|
1653 |
|
|
case '\0':
|
1654 |
|
|
done = TRUE;
|
1655 |
|
|
break;
|
1656 |
|
|
default:
|
1657 |
|
|
done = TRUE;
|
1658 |
|
|
tok_end = strchr(tok, '\0');
|
1659 |
|
|
for(i=0; tok_list[i]; i++)
|
1660 |
|
|
{
|
1661 |
|
|
tok_end2 = strchr(tok, tok_list[i]);
|
1662 |
|
|
if ( (tok_end2) && (tok_end2 < tok_end) )
|
1663 |
|
|
{
|
1664 |
|
|
tok_end = tok_end2;
|
1665 |
|
|
done = FALSE;
|
1666 |
|
|
}
|
1667 |
|
|
}
|
1668 |
|
|
if ( (instance >= 0) && (device >= 0) &&
|
1669 |
|
|
(instance < NUMBER(aic7xxx_tag_info)) &&
|
1670 |
|
|
(device < MAX_TARGETS) )
|
1671 |
|
|
aic7xxx_tag_info[instance].tag_commands[device] =
|
1672 |
|
|
simple_strtoul(tok, NULL, 0) & 0xff;
|
1673 |
|
|
tok = tok_end;
|
1674 |
|
|
break;
|
1675 |
|
|
}
|
1676 |
|
|
}
|
1677 |
|
|
while((p != base) && (p != NULL))
|
1678 |
|
|
p = strtok(NULL, ",.");
|
1679 |
|
|
}
|
1680 |
|
|
}
|
1681 |
|
|
else if (p[n] == ':')
|
1682 |
|
|
{
|
1683 |
|
|
*(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0);
|
1684 |
|
|
}
|
1685 |
|
|
else if (!strncmp(p, "verbose", n))
|
1686 |
|
|
{
|
1687 |
|
|
*(options[i].flag) = 0xff09;
|
1688 |
|
|
}
|
1689 |
|
|
else
|
1690 |
|
|
{
|
1691 |
|
|
*(options[i].flag) = ~(*(options[i].flag));
|
1692 |
|
|
}
|
1693 |
|
|
}
|
1694 |
|
|
}
|
1695 |
|
|
}
|
1696 |
|
|
}
|
1697 |
|
|
|
1698 |
|
|
/*+F*************************************************************************
|
1699 |
|
|
* Function:
|
1700 |
|
|
* pause_sequencer
|
1701 |
|
|
*
|
1702 |
|
|
* Description:
|
1703 |
|
|
* Pause the sequencer and wait for it to actually stop - this
|
1704 |
|
|
* is important since the sequencer can disable pausing for critical
|
1705 |
|
|
* sections.
|
1706 |
|
|
*-F*************************************************************************/
|
1707 |
|
|
static inline void
|
1708 |
|
|
pause_sequencer(struct aic7xxx_host *p)
|
1709 |
|
|
{
|
1710 |
|
|
aic_outb(p, p->pause, HCNTRL);
|
1711 |
|
|
while ((aic_inb(p, HCNTRL) & PAUSE) == 0)
|
1712 |
|
|
{
|
1713 |
|
|
;
|
1714 |
|
|
}
|
1715 |
|
|
}
|
1716 |
|
|
|
1717 |
|
|
/*+F*************************************************************************
|
1718 |
|
|
* Function:
|
1719 |
|
|
* unpause_sequencer
|
1720 |
|
|
*
|
1721 |
|
|
* Description:
|
1722 |
|
|
* Unpause the sequencer. Unremarkable, yet done often enough to
|
1723 |
|
|
* warrant an easy way to do it.
|
1724 |
|
|
*-F*************************************************************************/
|
1725 |
|
|
static inline void
|
1726 |
|
|
unpause_sequencer(struct aic7xxx_host *p, int unpause_always)
|
1727 |
|
|
{
|
1728 |
|
|
if (unpause_always ||
|
1729 |
|
|
( !(aic_inb(p, INTSTAT) & (SCSIINT | SEQINT | BRKADRINT)) &&
|
1730 |
|
|
!(p->flags & AHC_HANDLING_REQINITS) ) )
|
1731 |
|
|
{
|
1732 |
|
|
aic_outb(p, p->unpause, HCNTRL);
|
1733 |
|
|
}
|
1734 |
|
|
}
|
1735 |
|
|
|
1736 |
|
|
/*+F*************************************************************************
|
1737 |
|
|
* Function:
|
1738 |
|
|
* restart_sequencer
|
1739 |
|
|
*
|
1740 |
|
|
* Description:
|
1741 |
|
|
* Restart the sequencer program from address zero. This assumes
|
1742 |
|
|
* that the sequencer is already paused.
|
1743 |
|
|
*-F*************************************************************************/
|
1744 |
|
|
static inline void
|
1745 |
|
|
restart_sequencer(struct aic7xxx_host *p)
|
1746 |
|
|
{
|
1747 |
|
|
aic_outb(p, 0, SEQADDR0);
|
1748 |
|
|
aic_outb(p, 0, SEQADDR1);
|
1749 |
|
|
aic_outb(p, FASTMODE, SEQCTL);
|
1750 |
|
|
}
|
1751 |
|
|
|
1752 |
|
|
/*
|
1753 |
|
|
* We include the aic7xxx_seq.c file here so that the other defines have
|
1754 |
|
|
* already been made, and so that it comes before the code that actually
|
1755 |
|
|
* downloads the instructions (since we don't typically use function
|
1756 |
|
|
* prototype, our code has to be ordered that way, it's a left-over from
|
1757 |
|
|
* the original driver days.....I should fix it some time DL).
|
1758 |
|
|
*/
|
1759 |
|
|
#include "aic7xxx_seq.c"
|
1760 |
|
|
|
1761 |
|
|
/*+F*************************************************************************
|
1762 |
|
|
* Function:
|
1763 |
|
|
* aic7xxx_check_patch
|
1764 |
|
|
*
|
1765 |
|
|
* Description:
|
1766 |
|
|
* See if the next patch to download should be downloaded.
|
1767 |
|
|
*-F*************************************************************************/
|
1768 |
|
|
static int
|
1769 |
|
|
aic7xxx_check_patch(struct aic7xxx_host *p,
|
1770 |
|
|
struct sequencer_patch **start_patch, int start_instr, int *skip_addr)
|
1771 |
|
|
{
|
1772 |
|
|
struct sequencer_patch *cur_patch;
|
1773 |
|
|
struct sequencer_patch *last_patch;
|
1774 |
|
|
int num_patches;
|
1775 |
|
|
|
1776 |
|
|
num_patches = sizeof(sequencer_patches)/sizeof(struct sequencer_patch);
|
1777 |
|
|
last_patch = &sequencer_patches[num_patches];
|
1778 |
|
|
cur_patch = *start_patch;
|
1779 |
|
|
|
1780 |
|
|
while ((cur_patch < last_patch) && (start_instr == cur_patch->begin))
|
1781 |
|
|
{
|
1782 |
|
|
if (cur_patch->patch_func(p) == 0)
|
1783 |
|
|
{
|
1784 |
|
|
/*
|
1785 |
|
|
* Start rejecting code.
|
1786 |
|
|
*/
|
1787 |
|
|
*skip_addr = start_instr + cur_patch->skip_instr;
|
1788 |
|
|
cur_patch += cur_patch->skip_patch;
|
1789 |
|
|
}
|
1790 |
|
|
else
|
1791 |
|
|
{
|
1792 |
|
|
/*
|
1793 |
|
|
* Found an OK patch. Advance the patch pointer to the next patch
|
1794 |
|
|
* and wait for our instruction pointer to get here.
|
1795 |
|
|
*/
|
1796 |
|
|
cur_patch++;
|
1797 |
|
|
}
|
1798 |
|
|
}
|
1799 |
|
|
|
1800 |
|
|
*start_patch = cur_patch;
|
1801 |
|
|
if (start_instr < *skip_addr)
|
1802 |
|
|
/*
|
1803 |
|
|
* Still skipping
|
1804 |
|
|
*/
|
1805 |
|
|
return (0);
|
1806 |
|
|
return(1);
|
1807 |
|
|
}
|
1808 |
|
|
|
1809 |
|
|
|
1810 |
|
|
/*+F*************************************************************************
|
1811 |
|
|
* Function:
|
1812 |
|
|
* aic7xxx_download_instr
|
1813 |
|
|
*
|
1814 |
|
|
* Description:
|
1815 |
|
|
* Find the next patch to download.
|
1816 |
|
|
*-F*************************************************************************/
|
1817 |
|
|
static void
|
1818 |
|
|
aic7xxx_download_instr(struct aic7xxx_host *p, int instrptr,
|
1819 |
|
|
unsigned char *dconsts)
|
1820 |
|
|
{
|
1821 |
|
|
union ins_formats instr;
|
1822 |
|
|
struct ins_format1 *fmt1_ins;
|
1823 |
|
|
struct ins_format3 *fmt3_ins;
|
1824 |
|
|
unsigned char opcode;
|
1825 |
|
|
|
1826 |
|
|
instr = *(union ins_formats*) &seqprog[instrptr * 4];
|
1827 |
|
|
|
1828 |
|
|
instr.integer = le32_to_cpu(instr.integer);
|
1829 |
|
|
|
1830 |
|
|
fmt1_ins = &instr.format1;
|
1831 |
|
|
fmt3_ins = NULL;
|
1832 |
|
|
|
1833 |
|
|
/* Pull the opcode */
|
1834 |
|
|
opcode = instr.format1.opcode;
|
1835 |
|
|
switch (opcode)
|
1836 |
|
|
{
|
1837 |
|
|
case AIC_OP_JMP:
|
1838 |
|
|
case AIC_OP_JC:
|
1839 |
|
|
case AIC_OP_JNC:
|
1840 |
|
|
case AIC_OP_CALL:
|
1841 |
|
|
case AIC_OP_JNE:
|
1842 |
|
|
case AIC_OP_JNZ:
|
1843 |
|
|
case AIC_OP_JE:
|
1844 |
|
|
case AIC_OP_JZ:
|
1845 |
|
|
{
|
1846 |
|
|
struct sequencer_patch *cur_patch;
|
1847 |
|
|
int address_offset;
|
1848 |
|
|
unsigned int address;
|
1849 |
|
|
int skip_addr;
|
1850 |
|
|
int i;
|
1851 |
|
|
|
1852 |
|
|
fmt3_ins = &instr.format3;
|
1853 |
|
|
address_offset = 0;
|
1854 |
|
|
address = fmt3_ins->address;
|
1855 |
|
|
cur_patch = sequencer_patches;
|
1856 |
|
|
skip_addr = 0;
|
1857 |
|
|
|
1858 |
|
|
for (i = 0; i < address;)
|
1859 |
|
|
{
|
1860 |
|
|
aic7xxx_check_patch(p, &cur_patch, i, &skip_addr);
|
1861 |
|
|
if (skip_addr > i)
|
1862 |
|
|
{
|
1863 |
|
|
int end_addr;
|
1864 |
|
|
|
1865 |
|
|
end_addr = MIN(address, skip_addr);
|
1866 |
|
|
address_offset += end_addr - i;
|
1867 |
|
|
i = skip_addr;
|
1868 |
|
|
}
|
1869 |
|
|
else
|
1870 |
|
|
{
|
1871 |
|
|
i++;
|
1872 |
|
|
}
|
1873 |
|
|
}
|
1874 |
|
|
address -= address_offset;
|
1875 |
|
|
fmt3_ins->address = address;
|
1876 |
|
|
/* Fall Through to the next code section */
|
1877 |
|
|
}
|
1878 |
|
|
case AIC_OP_OR:
|
1879 |
|
|
case AIC_OP_AND:
|
1880 |
|
|
case AIC_OP_XOR:
|
1881 |
|
|
case AIC_OP_ADD:
|
1882 |
|
|
case AIC_OP_ADC:
|
1883 |
|
|
case AIC_OP_BMOV:
|
1884 |
|
|
if (fmt1_ins->parity != 0)
|
1885 |
|
|
{
|
1886 |
|
|
fmt1_ins->immediate = dconsts[fmt1_ins->immediate];
|
1887 |
|
|
}
|
1888 |
|
|
fmt1_ins->parity = 0;
|
1889 |
|
|
/* Fall Through to the next code section */
|
1890 |
|
|
case AIC_OP_ROL:
|
1891 |
|
|
if ((p->features & AHC_ULTRA2) != 0)
|
1892 |
|
|
{
|
1893 |
|
|
int i, count;
|
1894 |
|
|
|
1895 |
|
|
/* Calculate odd parity for the instruction */
|
1896 |
|
|
for ( i=0, count=0; i < 31; i++)
|
1897 |
|
|
{
|
1898 |
|
|
unsigned int mask;
|
1899 |
|
|
|
1900 |
|
|
mask = 0x01 << i;
|
1901 |
|
|
if ((instr.integer & mask) != 0)
|
1902 |
|
|
count++;
|
1903 |
|
|
}
|
1904 |
|
|
if (!(count & 0x01))
|
1905 |
|
|
instr.format1.parity = 1;
|
1906 |
|
|
}
|
1907 |
|
|
else
|
1908 |
|
|
{
|
1909 |
|
|
if (fmt3_ins != NULL)
|
1910 |
|
|
{
|
1911 |
|
|
instr.integer = fmt3_ins->immediate |
|
1912 |
|
|
(fmt3_ins->source << 8) |
|
1913 |
|
|
(fmt3_ins->address << 16) |
|
1914 |
|
|
(fmt3_ins->opcode << 25);
|
1915 |
|
|
}
|
1916 |
|
|
else
|
1917 |
|
|
{
|
1918 |
|
|
instr.integer = fmt1_ins->immediate |
|
1919 |
|
|
(fmt1_ins->source << 8) |
|
1920 |
|
|
(fmt1_ins->destination << 16) |
|
1921 |
|
|
(fmt1_ins->ret << 24) |
|
1922 |
|
|
(fmt1_ins->opcode << 25);
|
1923 |
|
|
}
|
1924 |
|
|
}
|
1925 |
|
|
aic_outb(p, (instr.integer & 0xff), SEQRAM);
|
1926 |
|
|
aic_outb(p, ((instr.integer >> 8) & 0xff), SEQRAM);
|
1927 |
|
|
aic_outb(p, ((instr.integer >> 16) & 0xff), SEQRAM);
|
1928 |
|
|
aic_outb(p, ((instr.integer >> 24) & 0xff), SEQRAM);
|
1929 |
|
|
break;
|
1930 |
|
|
|
1931 |
|
|
default:
|
1932 |
|
|
panic("aic7xxx: Unknown opcode encountered in sequencer program.");
|
1933 |
|
|
break;
|
1934 |
|
|
}
|
1935 |
|
|
}
|
1936 |
|
|
|
1937 |
|
|
|
1938 |
|
|
/*+F*************************************************************************
|
1939 |
|
|
* Function:
|
1940 |
|
|
* aic7xxx_loadseq
|
1941 |
|
|
*
|
1942 |
|
|
* Description:
|
1943 |
|
|
* Load the sequencer code into the controller memory.
|
1944 |
|
|
*-F*************************************************************************/
|
1945 |
|
|
static void
|
1946 |
|
|
aic7xxx_loadseq(struct aic7xxx_host *p)
|
1947 |
|
|
{
|
1948 |
|
|
struct sequencer_patch *cur_patch;
|
1949 |
|
|
int i;
|
1950 |
|
|
int downloaded;
|
1951 |
|
|
int skip_addr;
|
1952 |
|
|
unsigned char download_consts[4] = {0, 0, 0, 0};
|
1953 |
|
|
|
1954 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE)
|
1955 |
|
|
{
|
1956 |
|
|
printk(KERN_INFO "(scsi%d) Downloading sequencer code...", p->host_no);
|
1957 |
|
|
}
|
1958 |
|
|
#if 0
|
1959 |
|
|
download_consts[TMODE_NUMCMDS] = p->num_targetcmds;
|
1960 |
|
|
#endif
|
1961 |
|
|
download_consts[TMODE_NUMCMDS] = 0;
|
1962 |
|
|
cur_patch = &sequencer_patches[0];
|
1963 |
|
|
downloaded = 0;
|
1964 |
|
|
skip_addr = 0;
|
1965 |
|
|
|
1966 |
|
|
aic_outb(p, PERRORDIS|LOADRAM|FAILDIS|FASTMODE, SEQCTL);
|
1967 |
|
|
aic_outb(p, 0, SEQADDR0);
|
1968 |
|
|
aic_outb(p, 0, SEQADDR1);
|
1969 |
|
|
|
1970 |
|
|
for (i = 0; i < sizeof(seqprog) / 4; i++)
|
1971 |
|
|
{
|
1972 |
|
|
if (aic7xxx_check_patch(p, &cur_patch, i, &skip_addr) == 0)
|
1973 |
|
|
{
|
1974 |
|
|
/* Skip this instruction for this configuration. */
|
1975 |
|
|
continue;
|
1976 |
|
|
}
|
1977 |
|
|
aic7xxx_download_instr(p, i, &download_consts[0]);
|
1978 |
|
|
downloaded++;
|
1979 |
|
|
}
|
1980 |
|
|
|
1981 |
|
|
aic_outb(p, 0, SEQADDR0);
|
1982 |
|
|
aic_outb(p, 0, SEQADDR1);
|
1983 |
|
|
aic_outb(p, FASTMODE | FAILDIS, SEQCTL);
|
1984 |
|
|
unpause_sequencer(p, TRUE);
|
1985 |
|
|
mdelay(1);
|
1986 |
|
|
pause_sequencer(p);
|
1987 |
|
|
aic_outb(p, FASTMODE, SEQCTL);
|
1988 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE)
|
1989 |
|
|
{
|
1990 |
|
|
printk(" %d instructions downloaded\n", downloaded);
|
1991 |
|
|
}
|
1992 |
|
|
if (aic7xxx_dump_sequencer)
|
1993 |
|
|
aic7xxx_print_sequencer(p, downloaded);
|
1994 |
|
|
}
|
1995 |
|
|
|
1996 |
|
|
/*+F*************************************************************************
|
1997 |
|
|
* Function:
|
1998 |
|
|
* aic7xxx_print_sequencer
|
1999 |
|
|
*
|
2000 |
|
|
* Description:
|
2001 |
|
|
* Print the contents of the sequencer memory to the screen.
|
2002 |
|
|
*-F*************************************************************************/
|
2003 |
|
|
static void
|
2004 |
|
|
aic7xxx_print_sequencer(struct aic7xxx_host *p, int downloaded)
|
2005 |
|
|
{
|
2006 |
|
|
int i, k, temp;
|
2007 |
|
|
|
2008 |
|
|
aic_outb(p, PERRORDIS|LOADRAM|FAILDIS|FASTMODE, SEQCTL);
|
2009 |
|
|
aic_outb(p, 0, SEQADDR0);
|
2010 |
|
|
aic_outb(p, 0, SEQADDR1);
|
2011 |
|
|
|
2012 |
|
|
k = 0;
|
2013 |
|
|
for (i=0; i < downloaded; i++)
|
2014 |
|
|
{
|
2015 |
|
|
if ( k == 0 )
|
2016 |
|
|
printk("%03x: ", i);
|
2017 |
|
|
temp = aic_inb(p, SEQRAM);
|
2018 |
|
|
temp |= (aic_inb(p, SEQRAM) << 8);
|
2019 |
|
|
temp |= (aic_inb(p, SEQRAM) << 16);
|
2020 |
|
|
temp |= (aic_inb(p, SEQRAM) << 24);
|
2021 |
|
|
printk("%08x", temp);
|
2022 |
|
|
if ( ++k == 8 )
|
2023 |
|
|
{
|
2024 |
|
|
printk("\n");
|
2025 |
|
|
k = 0;
|
2026 |
|
|
}
|
2027 |
|
|
else
|
2028 |
|
|
printk(" ");
|
2029 |
|
|
}
|
2030 |
|
|
aic_outb(p, 0, SEQADDR0);
|
2031 |
|
|
aic_outb(p, 0, SEQADDR1);
|
2032 |
|
|
aic_outb(p, FASTMODE | FAILDIS, SEQCTL);
|
2033 |
|
|
unpause_sequencer(p, TRUE);
|
2034 |
|
|
mdelay(1);
|
2035 |
|
|
pause_sequencer(p);
|
2036 |
|
|
aic_outb(p, FASTMODE, SEQCTL);
|
2037 |
|
|
printk("\n");
|
2038 |
|
|
}
|
2039 |
|
|
|
2040 |
|
|
/*+F*************************************************************************
|
2041 |
|
|
* Function:
|
2042 |
|
|
* aic7xxx_delay
|
2043 |
|
|
*
|
2044 |
|
|
* Description:
|
2045 |
|
|
* Delay for specified amount of time. We use mdelay because the timer
|
2046 |
|
|
* interrupt is not guaranteed to be enabled. This will cause an
|
2047 |
|
|
* infinite loop since jiffies (clock ticks) is not updated.
|
2048 |
|
|
*-F*************************************************************************/
|
2049 |
|
|
static void
|
2050 |
|
|
aic7xxx_delay(int seconds)
|
2051 |
|
|
{
|
2052 |
|
|
mdelay(seconds * 1000);
|
2053 |
|
|
}
|
2054 |
|
|
|
2055 |
|
|
/*+F*************************************************************************
|
2056 |
|
|
* Function:
|
2057 |
|
|
* aic7xxx_info
|
2058 |
|
|
*
|
2059 |
|
|
* Description:
|
2060 |
|
|
* Return a string describing the driver.
|
2061 |
|
|
*-F*************************************************************************/
|
2062 |
|
|
const char *
|
2063 |
|
|
aic7xxx_info(struct Scsi_Host *dooh)
|
2064 |
|
|
{
|
2065 |
|
|
static char buffer[256];
|
2066 |
|
|
char *bp;
|
2067 |
|
|
struct aic7xxx_host *p;
|
2068 |
|
|
|
2069 |
|
|
bp = &buffer[0];
|
2070 |
|
|
p = (struct aic7xxx_host *)dooh->hostdata;
|
2071 |
|
|
memset(bp, 0, sizeof(buffer));
|
2072 |
|
|
strcpy(bp, "Adaptec AHA274x/284x/294x (EISA/VLB/PCI-Fast SCSI) ");
|
2073 |
|
|
strcat(bp, AIC7XXX_C_VERSION);
|
2074 |
|
|
strcat(bp, "/");
|
2075 |
|
|
strcat(bp, AIC7XXX_H_VERSION);
|
2076 |
|
|
strcat(bp, "\n");
|
2077 |
|
|
strcat(bp, " <");
|
2078 |
|
|
strcat(bp, board_names[p->board_name_index]);
|
2079 |
|
|
strcat(bp, ">");
|
2080 |
|
|
|
2081 |
|
|
return(bp);
|
2082 |
|
|
}
|
2083 |
|
|
|
2084 |
|
|
/*+F*************************************************************************
|
2085 |
|
|
* Function:
|
2086 |
|
|
* aic7xxx_find_syncrate
|
2087 |
|
|
*
|
2088 |
|
|
* Description:
|
2089 |
|
|
* Look up the valid period to SCSIRATE conversion in our table
|
2090 |
|
|
*-F*************************************************************************/
|
2091 |
|
|
static struct aic7xxx_syncrate *
|
2092 |
|
|
aic7xxx_find_syncrate(struct aic7xxx_host *p, unsigned int *period,
|
2093 |
|
|
unsigned int maxsync)
|
2094 |
|
|
{
|
2095 |
|
|
struct aic7xxx_syncrate *syncrate;
|
2096 |
|
|
|
2097 |
|
|
syncrate = &aic7xxx_syncrates[maxsync];
|
2098 |
|
|
while ( (syncrate->rate[0] != NULL) &&
|
2099 |
|
|
(!(p->features & AHC_ULTRA2) || syncrate->sxfr_ultra2) )
|
2100 |
|
|
{
|
2101 |
|
|
if ( *period <= syncrate->period )
|
2102 |
|
|
{
|
2103 |
|
|
/*
|
2104 |
|
|
* When responding to a target that requests sync, the requested rate
|
2105 |
|
|
* may fall between two rates that we can output, but still be a rate
|
2106 |
|
|
* that we can receive. Because of this, we want to respond with the
|
2107 |
|
|
* same rate that it sent to us even if the persiod we use to send
|
2108 |
|
|
* data to it is lower. Only lower the response period if we must.
|
2109 |
|
|
*/
|
2110 |
|
|
if(syncrate == &aic7xxx_syncrates[maxsync])
|
2111 |
|
|
{
|
2112 |
|
|
*period = syncrate->period;
|
2113 |
|
|
}
|
2114 |
|
|
break;
|
2115 |
|
|
}
|
2116 |
|
|
syncrate++;
|
2117 |
|
|
}
|
2118 |
|
|
if ( (*period == 0) || (syncrate->rate[0] == NULL) ||
|
2119 |
|
|
((p->features & AHC_ULTRA2) && (syncrate->sxfr_ultra2 == 0)) )
|
2120 |
|
|
{
|
2121 |
|
|
/*
|
2122 |
|
|
* Use async transfers for this target
|
2123 |
|
|
*/
|
2124 |
|
|
*period = 0;
|
2125 |
|
|
syncrate = NULL;
|
2126 |
|
|
}
|
2127 |
|
|
return (syncrate);
|
2128 |
|
|
}
|
2129 |
|
|
|
2130 |
|
|
|
2131 |
|
|
/*+F*************************************************************************
|
2132 |
|
|
* Function:
|
2133 |
|
|
* aic7xxx_find_period
|
2134 |
|
|
*
|
2135 |
|
|
* Description:
|
2136 |
|
|
* Look up the valid SCSIRATE to period conversion in our table
|
2137 |
|
|
*-F*************************************************************************/
|
2138 |
|
|
static unsigned int
|
2139 |
|
|
aic7xxx_find_period(struct aic7xxx_host *p, unsigned int scsirate,
|
2140 |
|
|
unsigned int maxsync)
|
2141 |
|
|
{
|
2142 |
|
|
struct aic7xxx_syncrate *syncrate;
|
2143 |
|
|
|
2144 |
|
|
if ((p->features & AHC_ULTRA2) != 0)
|
2145 |
|
|
{
|
2146 |
|
|
scsirate &= SXFR_ULTRA2;
|
2147 |
|
|
}
|
2148 |
|
|
else
|
2149 |
|
|
{
|
2150 |
|
|
scsirate &= SXFR;
|
2151 |
|
|
}
|
2152 |
|
|
|
2153 |
|
|
syncrate = &aic7xxx_syncrates[maxsync];
|
2154 |
|
|
while (syncrate->rate[0] != NULL)
|
2155 |
|
|
{
|
2156 |
|
|
if ((p->features & AHC_ULTRA2) != 0)
|
2157 |
|
|
{
|
2158 |
|
|
if (syncrate->sxfr_ultra2 == 0)
|
2159 |
|
|
break;
|
2160 |
|
|
else if (scsirate == syncrate->sxfr_ultra2)
|
2161 |
|
|
return (syncrate->period);
|
2162 |
|
|
}
|
2163 |
|
|
else if (scsirate == (syncrate->sxfr & ~ULTRA_SXFR))
|
2164 |
|
|
{
|
2165 |
|
|
return (syncrate->period);
|
2166 |
|
|
}
|
2167 |
|
|
syncrate++;
|
2168 |
|
|
}
|
2169 |
|
|
return (0); /* async */
|
2170 |
|
|
}
|
2171 |
|
|
|
2172 |
|
|
/*+F*************************************************************************
|
2173 |
|
|
* Function:
|
2174 |
|
|
* aic7xxx_validate_offset
|
2175 |
|
|
*
|
2176 |
|
|
* Description:
|
2177 |
|
|
* Set a valid offset value for a particular card in use and transfer
|
2178 |
|
|
* settings in use.
|
2179 |
|
|
*-F*************************************************************************/
|
2180 |
|
|
static void
|
2181 |
|
|
aic7xxx_validate_offset(struct aic7xxx_host *p,
|
2182 |
|
|
struct aic7xxx_syncrate *syncrate, unsigned int *offset, int wide)
|
2183 |
|
|
{
|
2184 |
|
|
unsigned int maxoffset;
|
2185 |
|
|
|
2186 |
|
|
/* Limit offset to what the card (and device) can do */
|
2187 |
|
|
if (syncrate == NULL)
|
2188 |
|
|
{
|
2189 |
|
|
maxoffset = 0;
|
2190 |
|
|
}
|
2191 |
|
|
else if (p->features & AHC_ULTRA2)
|
2192 |
|
|
{
|
2193 |
|
|
maxoffset = MAX_OFFSET_ULTRA2;
|
2194 |
|
|
}
|
2195 |
|
|
else
|
2196 |
|
|
{
|
2197 |
|
|
if (wide)
|
2198 |
|
|
maxoffset = MAX_OFFSET_16BIT;
|
2199 |
|
|
else
|
2200 |
|
|
maxoffset = MAX_OFFSET_8BIT;
|
2201 |
|
|
}
|
2202 |
|
|
*offset = MIN(*offset, maxoffset);
|
2203 |
|
|
}
|
2204 |
|
|
|
2205 |
|
|
/*+F*************************************************************************
|
2206 |
|
|
* Function:
|
2207 |
|
|
* aic7xxx_set_syncrate
|
2208 |
|
|
*
|
2209 |
|
|
* Description:
|
2210 |
|
|
* Set the actual syncrate down in the card and in our host structs
|
2211 |
|
|
*-F*************************************************************************/
|
2212 |
|
|
static void
|
2213 |
|
|
aic7xxx_set_syncrate(struct aic7xxx_host *p, struct aic7xxx_syncrate *syncrate,
|
2214 |
|
|
int target, int channel, unsigned int period, unsigned int offset,
|
2215 |
|
|
unsigned int type)
|
2216 |
|
|
{
|
2217 |
|
|
unsigned char tindex;
|
2218 |
|
|
unsigned short target_mask;
|
2219 |
|
|
unsigned char lun;
|
2220 |
|
|
unsigned int old_period, old_offset;
|
2221 |
|
|
|
2222 |
|
|
tindex = target | (channel << 3);
|
2223 |
|
|
target_mask = 0x01 << tindex;
|
2224 |
|
|
lun = aic_inb(p, SCB_TCL) & 0x07;
|
2225 |
|
|
|
2226 |
|
|
if (syncrate == NULL)
|
2227 |
|
|
{
|
2228 |
|
|
period = 0;
|
2229 |
|
|
offset = 0;
|
2230 |
|
|
}
|
2231 |
|
|
|
2232 |
|
|
old_period = p->transinfo[tindex].cur_period;
|
2233 |
|
|
old_offset = p->transinfo[tindex].cur_offset;
|
2234 |
|
|
|
2235 |
|
|
|
2236 |
|
|
if (type & AHC_TRANS_CUR)
|
2237 |
|
|
{
|
2238 |
|
|
unsigned int scsirate;
|
2239 |
|
|
|
2240 |
|
|
scsirate = aic_inb(p, TARG_SCSIRATE + tindex);
|
2241 |
|
|
if (p->features & AHC_ULTRA2)
|
2242 |
|
|
{
|
2243 |
|
|
scsirate &= ~SXFR_ULTRA2;
|
2244 |
|
|
if (syncrate != NULL)
|
2245 |
|
|
{
|
2246 |
|
|
scsirate |= syncrate->sxfr_ultra2;
|
2247 |
|
|
}
|
2248 |
|
|
if (type & AHC_TRANS_ACTIVE)
|
2249 |
|
|
{
|
2250 |
|
|
aic_outb(p, offset, SCSIOFFSET);
|
2251 |
|
|
}
|
2252 |
|
|
aic_outb(p, offset, TARG_OFFSET + tindex);
|
2253 |
|
|
}
|
2254 |
|
|
else /* Not an Ultra2 controller */
|
2255 |
|
|
{
|
2256 |
|
|
scsirate &= ~(SXFR|SOFS);
|
2257 |
|
|
p->ultraenb &= ~target_mask;
|
2258 |
|
|
if (syncrate != NULL)
|
2259 |
|
|
{
|
2260 |
|
|
if (syncrate->sxfr & ULTRA_SXFR)
|
2261 |
|
|
{
|
2262 |
|
|
p->ultraenb |= target_mask;
|
2263 |
|
|
}
|
2264 |
|
|
scsirate |= (syncrate->sxfr & SXFR);
|
2265 |
|
|
scsirate |= (offset & SOFS);
|
2266 |
|
|
}
|
2267 |
|
|
if (type & AHC_TRANS_ACTIVE)
|
2268 |
|
|
{
|
2269 |
|
|
unsigned char sxfrctl0;
|
2270 |
|
|
|
2271 |
|
|
sxfrctl0 = aic_inb(p, SXFRCTL0);
|
2272 |
|
|
sxfrctl0 &= ~FAST20;
|
2273 |
|
|
if (p->ultraenb & target_mask)
|
2274 |
|
|
sxfrctl0 |= FAST20;
|
2275 |
|
|
aic_outb(p, sxfrctl0, SXFRCTL0);
|
2276 |
|
|
}
|
2277 |
|
|
aic_outb(p, p->ultraenb & 0xff, ULTRA_ENB);
|
2278 |
|
|
aic_outb(p, (p->ultraenb >> 8) & 0xff, ULTRA_ENB + 1 );
|
2279 |
|
|
}
|
2280 |
|
|
if (type & AHC_TRANS_ACTIVE)
|
2281 |
|
|
{
|
2282 |
|
|
aic_outb(p, scsirate, SCSIRATE);
|
2283 |
|
|
}
|
2284 |
|
|
aic_outb(p, scsirate, TARG_SCSIRATE + tindex);
|
2285 |
|
|
p->transinfo[tindex].cur_period = period;
|
2286 |
|
|
p->transinfo[tindex].cur_offset = offset;
|
2287 |
|
|
if ( !(type & AHC_TRANS_QUITE) &&
|
2288 |
|
|
(aic7xxx_verbose & VERBOSE_NEGOTIATION) &&
|
2289 |
|
|
(p->dev_flags[tindex] & DEVICE_PRINT_SDTR) )
|
2290 |
|
|
{
|
2291 |
|
|
if (offset)
|
2292 |
|
|
{
|
2293 |
|
|
int rate_mod = (scsirate & WIDEXFER) ? 1 : 0;
|
2294 |
|
|
|
2295 |
|
|
printk(INFO_LEAD "Synchronous at %s Mbyte/sec, "
|
2296 |
|
|
"offset %d.\n", p->host_no, channel, target, lun,
|
2297 |
|
|
syncrate->rate[rate_mod], offset);
|
2298 |
|
|
}
|
2299 |
|
|
else
|
2300 |
|
|
{
|
2301 |
|
|
printk(INFO_LEAD "Using asynchronous transfers.\n",
|
2302 |
|
|
p->host_no, channel, target, lun);
|
2303 |
|
|
}
|
2304 |
|
|
p->dev_flags[tindex] &= ~DEVICE_PRINT_SDTR;
|
2305 |
|
|
}
|
2306 |
|
|
}
|
2307 |
|
|
|
2308 |
|
|
if (type & AHC_TRANS_GOAL)
|
2309 |
|
|
{
|
2310 |
|
|
p->transinfo[tindex].goal_period = period;
|
2311 |
|
|
p->transinfo[tindex].goal_offset = offset;
|
2312 |
|
|
}
|
2313 |
|
|
|
2314 |
|
|
if (type & AHC_TRANS_USER)
|
2315 |
|
|
{
|
2316 |
|
|
p->transinfo[tindex].user_period = period;
|
2317 |
|
|
p->transinfo[tindex].user_offset = offset;
|
2318 |
|
|
}
|
2319 |
|
|
}
|
2320 |
|
|
|
2321 |
|
|
/*+F*************************************************************************
|
2322 |
|
|
* Function:
|
2323 |
|
|
* aic7xxx_set_width
|
2324 |
|
|
*
|
2325 |
|
|
* Description:
|
2326 |
|
|
* Set the actual width down in the card and in our host structs
|
2327 |
|
|
*-F*************************************************************************/
|
2328 |
|
|
static void
|
2329 |
|
|
aic7xxx_set_width(struct aic7xxx_host *p, int target, int channel, int lun,
|
2330 |
|
|
unsigned int width, unsigned int type)
|
2331 |
|
|
{
|
2332 |
|
|
unsigned char tindex;
|
2333 |
|
|
unsigned short target_mask;
|
2334 |
|
|
unsigned int old_width, new_offset;
|
2335 |
|
|
|
2336 |
|
|
tindex = target | (channel << 3);
|
2337 |
|
|
target_mask = 1 << tindex;
|
2338 |
|
|
|
2339 |
|
|
old_width = p->transinfo[tindex].cur_width;
|
2340 |
|
|
|
2341 |
|
|
if (p->features & AHC_ULTRA2)
|
2342 |
|
|
new_offset = MAX_OFFSET_ULTRA2;
|
2343 |
|
|
else if (width == MSG_EXT_WDTR_BUS_16_BIT)
|
2344 |
|
|
new_offset = MAX_OFFSET_16BIT;
|
2345 |
|
|
else
|
2346 |
|
|
new_offset = MAX_OFFSET_8BIT;
|
2347 |
|
|
|
2348 |
|
|
if (type & AHC_TRANS_CUR)
|
2349 |
|
|
{
|
2350 |
|
|
unsigned char scsirate;
|
2351 |
|
|
|
2352 |
|
|
scsirate = aic_inb(p, TARG_SCSIRATE + tindex);
|
2353 |
|
|
|
2354 |
|
|
scsirate &= ~WIDEXFER;
|
2355 |
|
|
if (width == MSG_EXT_WDTR_BUS_16_BIT)
|
2356 |
|
|
scsirate |= WIDEXFER;
|
2357 |
|
|
|
2358 |
|
|
aic_outb(p, scsirate, TARG_SCSIRATE + tindex);
|
2359 |
|
|
|
2360 |
|
|
if (type & AHC_TRANS_ACTIVE)
|
2361 |
|
|
aic_outb(p, scsirate, SCSIRATE);
|
2362 |
|
|
|
2363 |
|
|
p->transinfo[tindex].cur_width = width;
|
2364 |
|
|
|
2365 |
|
|
if ((aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
|
2366 |
|
|
(p->dev_flags[tindex] & DEVICE_PRINT_WDTR))
|
2367 |
|
|
{
|
2368 |
|
|
printk(INFO_LEAD "Using %s transfers\n", p->host_no, channel, target,
|
2369 |
|
|
lun, (scsirate & WIDEXFER) ? "Wide(16bit)" : "Narrow(8bit)" );
|
2370 |
|
|
p->dev_flags[tindex] &= ~DEVICE_PRINT_WDTR;
|
2371 |
|
|
}
|
2372 |
|
|
}
|
2373 |
|
|
|
2374 |
|
|
if (type & AHC_TRANS_GOAL)
|
2375 |
|
|
p->transinfo[tindex].goal_width = width;
|
2376 |
|
|
if (type & AHC_TRANS_USER)
|
2377 |
|
|
p->transinfo[tindex].user_width = width;
|
2378 |
|
|
|
2379 |
|
|
/*
|
2380 |
|
|
* Having just set the width, the SDTR should come next, and we need a valid
|
2381 |
|
|
* offset for the SDTR. So, we make sure we put a valid one in here now as
|
2382 |
|
|
* the goal_offset.
|
2383 |
|
|
*/
|
2384 |
|
|
if (p->transinfo[tindex].goal_offset)
|
2385 |
|
|
p->transinfo[tindex].goal_offset = new_offset;
|
2386 |
|
|
|
2387 |
|
|
}
|
2388 |
|
|
|
2389 |
|
|
/*+F*************************************************************************
|
2390 |
|
|
* Function:
|
2391 |
|
|
* scbq_init
|
2392 |
|
|
*
|
2393 |
|
|
* Description:
|
2394 |
|
|
* SCB queue initialization.
|
2395 |
|
|
*
|
2396 |
|
|
*-F*************************************************************************/
|
2397 |
|
|
static void
|
2398 |
|
|
scbq_init(volatile scb_queue_type *queue)
|
2399 |
|
|
{
|
2400 |
|
|
queue->head = NULL;
|
2401 |
|
|
queue->tail = NULL;
|
2402 |
|
|
}
|
2403 |
|
|
|
2404 |
|
|
/*+F*************************************************************************
|
2405 |
|
|
* Function:
|
2406 |
|
|
* scbq_insert_head
|
2407 |
|
|
*
|
2408 |
|
|
* Description:
|
2409 |
|
|
* Add an SCB to the head of the list.
|
2410 |
|
|
*
|
2411 |
|
|
*-F*************************************************************************/
|
2412 |
|
|
static inline void
|
2413 |
|
|
scbq_insert_head(volatile scb_queue_type *queue, struct aic7xxx_scb *scb)
|
2414 |
|
|
{
|
2415 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
|
2416 |
|
|
unsigned long cpu_flags;
|
2417 |
|
|
#endif
|
2418 |
|
|
|
2419 |
|
|
DRIVER_LOCK
|
2420 |
|
|
scb->q_next = queue->head;
|
2421 |
|
|
queue->head = scb;
|
2422 |
|
|
if (queue->tail == NULL) /* If list was empty, update tail. */
|
2423 |
|
|
queue->tail = queue->head;
|
2424 |
|
|
DRIVER_UNLOCK
|
2425 |
|
|
}
|
2426 |
|
|
|
2427 |
|
|
/*+F*************************************************************************
|
2428 |
|
|
* Function:
|
2429 |
|
|
* scbq_remove_head
|
2430 |
|
|
*
|
2431 |
|
|
* Description:
|
2432 |
|
|
* Remove an SCB from the head of the list.
|
2433 |
|
|
*
|
2434 |
|
|
*-F*************************************************************************/
|
2435 |
|
|
static inline struct aic7xxx_scb *
|
2436 |
|
|
scbq_remove_head(volatile scb_queue_type *queue)
|
2437 |
|
|
{
|
2438 |
|
|
struct aic7xxx_scb * scbp;
|
2439 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
|
2440 |
|
|
unsigned long cpu_flags;
|
2441 |
|
|
#endif
|
2442 |
|
|
|
2443 |
|
|
DRIVER_LOCK
|
2444 |
|
|
scbp = queue->head;
|
2445 |
|
|
if (queue->head != NULL)
|
2446 |
|
|
queue->head = queue->head->q_next;
|
2447 |
|
|
if (queue->head == NULL) /* If list is now empty, update tail. */
|
2448 |
|
|
queue->tail = NULL;
|
2449 |
|
|
DRIVER_UNLOCK
|
2450 |
|
|
return(scbp);
|
2451 |
|
|
}
|
2452 |
|
|
|
2453 |
|
|
/*+F*************************************************************************
|
2454 |
|
|
* Function:
|
2455 |
|
|
* scbq_remove
|
2456 |
|
|
*
|
2457 |
|
|
* Description:
|
2458 |
|
|
* Removes an SCB from the list.
|
2459 |
|
|
*
|
2460 |
|
|
*-F*************************************************************************/
|
2461 |
|
|
static inline void
|
2462 |
|
|
scbq_remove(volatile scb_queue_type *queue, struct aic7xxx_scb *scb)
|
2463 |
|
|
{
|
2464 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
|
2465 |
|
|
unsigned long cpu_flags;
|
2466 |
|
|
#endif
|
2467 |
|
|
|
2468 |
|
|
DRIVER_LOCK
|
2469 |
|
|
if (queue->head == scb)
|
2470 |
|
|
{
|
2471 |
|
|
/* At beginning of queue, remove from head. */
|
2472 |
|
|
scbq_remove_head(queue);
|
2473 |
|
|
}
|
2474 |
|
|
else
|
2475 |
|
|
{
|
2476 |
|
|
struct aic7xxx_scb *curscb = queue->head;
|
2477 |
|
|
|
2478 |
|
|
/*
|
2479 |
|
|
* Search until the next scb is the one we're looking for, or
|
2480 |
|
|
* we run out of queue.
|
2481 |
|
|
*/
|
2482 |
|
|
while ((curscb != NULL) && (curscb->q_next != scb))
|
2483 |
|
|
{
|
2484 |
|
|
curscb = curscb->q_next;
|
2485 |
|
|
}
|
2486 |
|
|
if (curscb != NULL)
|
2487 |
|
|
{
|
2488 |
|
|
/* Found it. */
|
2489 |
|
|
curscb->q_next = scb->q_next;
|
2490 |
|
|
if (scb->q_next == NULL)
|
2491 |
|
|
{
|
2492 |
|
|
/* Update the tail when removing the tail. */
|
2493 |
|
|
queue->tail = curscb;
|
2494 |
|
|
}
|
2495 |
|
|
}
|
2496 |
|
|
}
|
2497 |
|
|
DRIVER_UNLOCK
|
2498 |
|
|
}
|
2499 |
|
|
|
2500 |
|
|
/*+F*************************************************************************
|
2501 |
|
|
* Function:
|
2502 |
|
|
* scbq_insert_tail
|
2503 |
|
|
*
|
2504 |
|
|
* Description:
|
2505 |
|
|
* Add an SCB at the tail of the list.
|
2506 |
|
|
*
|
2507 |
|
|
*-F*************************************************************************/
|
2508 |
|
|
static inline void
|
2509 |
|
|
scbq_insert_tail(volatile scb_queue_type *queue, struct aic7xxx_scb *scb)
|
2510 |
|
|
{
|
2511 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
|
2512 |
|
|
unsigned long cpu_flags;
|
2513 |
|
|
#endif
|
2514 |
|
|
|
2515 |
|
|
DRIVER_LOCK
|
2516 |
|
|
scb->q_next = NULL;
|
2517 |
|
|
if (queue->tail != NULL) /* Add the scb at the end of the list. */
|
2518 |
|
|
queue->tail->q_next = scb;
|
2519 |
|
|
queue->tail = scb; /* Update the tail. */
|
2520 |
|
|
if (queue->head == NULL) /* If list was empty, update head. */
|
2521 |
|
|
queue->head = queue->tail;
|
2522 |
|
|
DRIVER_UNLOCK
|
2523 |
|
|
}
|
2524 |
|
|
|
2525 |
|
|
/*+F*************************************************************************
|
2526 |
|
|
* Function:
|
2527 |
|
|
* aic7xxx_match_scb
|
2528 |
|
|
*
|
2529 |
|
|
* Description:
|
2530 |
|
|
* Checks to see if an scb matches the target/channel as specified.
|
2531 |
|
|
* If target is ALL_TARGETS (-1), then we're looking for any device
|
2532 |
|
|
* on the specified channel; this happens when a channel is going
|
2533 |
|
|
* to be reset and all devices on that channel must be aborted.
|
2534 |
|
|
*-F*************************************************************************/
|
2535 |
|
|
static int
|
2536 |
|
|
aic7xxx_match_scb(struct aic7xxx_host *p, struct aic7xxx_scb *scb,
|
2537 |
|
|
int target, int channel, int lun, unsigned char tag)
|
2538 |
|
|
{
|
2539 |
|
|
int targ = (scb->hscb->target_channel_lun >> 4) & 0x0F;
|
2540 |
|
|
int chan = (scb->hscb->target_channel_lun >> 3) & 0x01;
|
2541 |
|
|
int slun = scb->hscb->target_channel_lun & 0x07;
|
2542 |
|
|
int match;
|
2543 |
|
|
|
2544 |
|
|
match = ((chan == channel) || (channel == ALL_CHANNELS));
|
2545 |
|
|
if (match != 0)
|
2546 |
|
|
match = ((targ == target) || (target == ALL_TARGETS));
|
2547 |
|
|
if (match != 0)
|
2548 |
|
|
match = ((lun == slun) || (lun == ALL_LUNS));
|
2549 |
|
|
if (match != 0)
|
2550 |
|
|
match = ((tag == scb->hscb->tag) || (tag == SCB_LIST_NULL));
|
2551 |
|
|
|
2552 |
|
|
if (aic7xxx_verbose & (VERBOSE_ABORT_PROCESS | VERBOSE_RESET_PROCESS))
|
2553 |
|
|
{
|
2554 |
|
|
printk(KERN_INFO "(scsi%d:%d:%d:%d:tag%d) %s search criteria"
|
2555 |
|
|
" (scsi%d:%d:%d:%d:tag%d)\n", p->host_no, CTL_OF_SCB(scb),
|
2556 |
|
|
scb->hscb->tag, (match) ? "matches" : "doesn't match",
|
2557 |
|
|
p->host_no, channel, target, lun, tag);
|
2558 |
|
|
}
|
2559 |
|
|
|
2560 |
|
|
return (match);
|
2561 |
|
|
}
|
2562 |
|
|
|
2563 |
|
|
/*+F*************************************************************************
|
2564 |
|
|
* Function:
|
2565 |
|
|
* aic7xxx_add_curscb_to_free_list
|
2566 |
|
|
*
|
2567 |
|
|
* Description:
|
2568 |
|
|
* Adds the current scb (in SCBPTR) to the list of free SCBs.
|
2569 |
|
|
*-F*************************************************************************/
|
2570 |
|
|
static void
|
2571 |
|
|
aic7xxx_add_curscb_to_free_list(struct aic7xxx_host *p)
|
2572 |
|
|
{
|
2573 |
|
|
/*
|
2574 |
|
|
* Invalidate the tag so that aic7xxx_find_scb doesn't think
|
2575 |
|
|
* it's active
|
2576 |
|
|
*/
|
2577 |
|
|
aic_outb(p, SCB_LIST_NULL, SCB_TAG);
|
2578 |
|
|
aic_outb(p, 0, SCB_CONTROL);
|
2579 |
|
|
|
2580 |
|
|
aic_outb(p, aic_inb(p, FREE_SCBH), SCB_NEXT);
|
2581 |
|
|
aic_outb(p, aic_inb(p, SCBPTR), FREE_SCBH);
|
2582 |
|
|
}
|
2583 |
|
|
|
2584 |
|
|
/*+F*************************************************************************
|
2585 |
|
|
* Function:
|
2586 |
|
|
* aic7xxx_rem_scb_from_disc_list
|
2587 |
|
|
*
|
2588 |
|
|
* Description:
|
2589 |
|
|
* Removes the current SCB from the disconnected list and adds it
|
2590 |
|
|
* to the free list.
|
2591 |
|
|
*-F*************************************************************************/
|
2592 |
|
|
static unsigned char
|
2593 |
|
|
aic7xxx_rem_scb_from_disc_list(struct aic7xxx_host *p, unsigned char scbptr)
|
2594 |
|
|
{
|
2595 |
|
|
unsigned char next;
|
2596 |
|
|
unsigned char prev;
|
2597 |
|
|
|
2598 |
|
|
aic_outb(p, scbptr, SCBPTR);
|
2599 |
|
|
next = aic_inb(p, SCB_NEXT);
|
2600 |
|
|
prev = aic_inb(p, SCB_PREV);
|
2601 |
|
|
aic7xxx_add_curscb_to_free_list(p);
|
2602 |
|
|
|
2603 |
|
|
if (prev != SCB_LIST_NULL)
|
2604 |
|
|
{
|
2605 |
|
|
aic_outb(p, prev, SCBPTR);
|
2606 |
|
|
aic_outb(p, next, SCB_NEXT);
|
2607 |
|
|
}
|
2608 |
|
|
else
|
2609 |
|
|
{
|
2610 |
|
|
aic_outb(p, next, DISCONNECTED_SCBH);
|
2611 |
|
|
}
|
2612 |
|
|
|
2613 |
|
|
if (next != SCB_LIST_NULL)
|
2614 |
|
|
{
|
2615 |
|
|
aic_outb(p, next, SCBPTR);
|
2616 |
|
|
aic_outb(p, prev, SCB_PREV);
|
2617 |
|
|
}
|
2618 |
|
|
return next;
|
2619 |
|
|
}
|
2620 |
|
|
|
2621 |
|
|
/*+F*************************************************************************
|
2622 |
|
|
* Function:
|
2623 |
|
|
* aic7xxx_busy_target
|
2624 |
|
|
*
|
2625 |
|
|
* Description:
|
2626 |
|
|
* Set the specified target busy.
|
2627 |
|
|
*-F*************************************************************************/
|
2628 |
|
|
static inline void
|
2629 |
|
|
aic7xxx_busy_target(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
|
2630 |
|
|
{
|
2631 |
|
|
p->untagged_scbs[scb->hscb->target_channel_lun] = scb->hscb->tag;
|
2632 |
|
|
}
|
2633 |
|
|
|
2634 |
|
|
/*+F*************************************************************************
|
2635 |
|
|
* Function:
|
2636 |
|
|
* aic7xxx_index_busy_target
|
2637 |
|
|
*
|
2638 |
|
|
* Description:
|
2639 |
|
|
* Returns the index of the busy target, and optionally sets the
|
2640 |
|
|
* target inactive.
|
2641 |
|
|
*-F*************************************************************************/
|
2642 |
|
|
static inline unsigned char
|
2643 |
|
|
aic7xxx_index_busy_target(struct aic7xxx_host *p, unsigned char tcl,
|
2644 |
|
|
int unbusy)
|
2645 |
|
|
{
|
2646 |
|
|
unsigned char busy_scbid;
|
2647 |
|
|
|
2648 |
|
|
busy_scbid = p->untagged_scbs[tcl];
|
2649 |
|
|
if (unbusy)
|
2650 |
|
|
{
|
2651 |
|
|
p->untagged_scbs[tcl] = SCB_LIST_NULL;
|
2652 |
|
|
}
|
2653 |
|
|
return (busy_scbid);
|
2654 |
|
|
}
|
2655 |
|
|
|
2656 |
|
|
/*+F*************************************************************************
|
2657 |
|
|
* Function:
|
2658 |
|
|
* aic7xxx_find_scb
|
2659 |
|
|
*
|
2660 |
|
|
* Description:
|
2661 |
|
|
* Look through the SCB array of the card and attempt to find the
|
2662 |
|
|
* hardware SCB that corresponds to the passed in SCB. Return
|
2663 |
|
|
* SCB_LIST_NULL if unsuccessful. This routine assumes that the
|
2664 |
|
|
* card is already paused.
|
2665 |
|
|
*-F*************************************************************************/
|
2666 |
|
|
static unsigned char
|
2667 |
|
|
aic7xxx_find_scb(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
|
2668 |
|
|
{
|
2669 |
|
|
unsigned char saved_scbptr;
|
2670 |
|
|
unsigned char curindex;
|
2671 |
|
|
|
2672 |
|
|
saved_scbptr = aic_inb(p, SCBPTR);
|
2673 |
|
|
curindex = 0;
|
2674 |
|
|
for (curindex = 0; curindex < p->scb_data->maxhscbs; curindex++)
|
2675 |
|
|
{
|
2676 |
|
|
aic_outb(p, curindex, SCBPTR);
|
2677 |
|
|
if (aic_inb(p, SCB_TAG) == scb->hscb->tag)
|
2678 |
|
|
{
|
2679 |
|
|
break;
|
2680 |
|
|
}
|
2681 |
|
|
}
|
2682 |
|
|
aic_outb(p, saved_scbptr, SCBPTR);
|
2683 |
|
|
if (curindex >= p->scb_data->maxhscbs)
|
2684 |
|
|
{
|
2685 |
|
|
curindex = SCB_LIST_NULL;
|
2686 |
|
|
}
|
2687 |
|
|
|
2688 |
|
|
return (curindex);
|
2689 |
|
|
}
|
2690 |
|
|
|
2691 |
|
|
/*+F*************************************************************************
|
2692 |
|
|
* Function:
|
2693 |
|
|
* aic7xxx_allocate_scb
|
2694 |
|
|
*
|
2695 |
|
|
* Description:
|
2696 |
|
|
* Get an SCB from the free list or by allocating a new one.
|
2697 |
|
|
*-F*************************************************************************/
|
2698 |
|
|
static int
|
2699 |
|
|
aic7xxx_allocate_scb(struct aic7xxx_host *p)
|
2700 |
|
|
{
|
2701 |
|
|
struct aic7xxx_scb *scbp = NULL;
|
2702 |
|
|
int scb_size = sizeof(struct aic7xxx_scb) +
|
2703 |
|
|
sizeof (struct hw_scatterlist) * AIC7XXX_MAX_SG;
|
2704 |
|
|
int i;
|
2705 |
|
|
int step = PAGE_SIZE / 1024;
|
2706 |
|
|
unsigned long scb_count = 0;
|
2707 |
|
|
struct hw_scatterlist *hsgp;
|
2708 |
|
|
struct aic7xxx_scb *scb_ap;
|
2709 |
|
|
unsigned long temp;
|
2710 |
|
|
|
2711 |
|
|
|
2712 |
|
|
if (p->scb_data->numscbs < p->scb_data->maxscbs)
|
2713 |
|
|
{
|
2714 |
|
|
/*
|
2715 |
|
|
* Calculate the optimal number of SCBs to allocate.
|
2716 |
|
|
*
|
2717 |
|
|
* NOTE: This formula works because the sizeof(sg_array) is always
|
2718 |
|
|
* 1024. Therefore, scb_size * i would always be > PAGE_SIZE *
|
2719 |
|
|
* (i/step). The (i-1) allows the left hand side of the equation
|
2720 |
|
|
* to grow into the right hand side to a point of near perfect
|
2721 |
|
|
* efficiency since scb_size * (i -1) is growing slightly faster
|
2722 |
|
|
* than the right hand side. If the number of SG array elements
|
2723 |
|
|
* is changed, this function may not be near so efficient any more.
|
2724 |
|
|
*/
|
2725 |
|
|
for ( i=step;; i *= 2 )
|
2726 |
|
|
{
|
2727 |
|
|
if ( (scb_size * (i-1)) >= ( (PAGE_SIZE * (i/step)) - 64 ) )
|
2728 |
|
|
{
|
2729 |
|
|
i /= 2;
|
2730 |
|
|
break;
|
2731 |
|
|
}
|
2732 |
|
|
}
|
2733 |
|
|
scb_count = MIN( (i-1), p->scb_data->maxscbs - p->scb_data->numscbs);
|
2734 |
|
|
scb_ap = (struct aic7xxx_scb *)kmalloc(scb_size * scb_count, GFP_ATOMIC);
|
2735 |
|
|
if (scb_ap != NULL)
|
2736 |
|
|
{
|
2737 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
2738 |
|
|
if (aic7xxx_verbose > 0xffff)
|
2739 |
|
|
{
|
2740 |
|
|
if (p->scb_data->numscbs == 0)
|
2741 |
|
|
printk(INFO_LEAD "Allocating initial %ld SCB structures.\n",
|
2742 |
|
|
p->host_no, -1, -1, -1, scb_count);
|
2743 |
|
|
else
|
2744 |
|
|
printk(INFO_LEAD "Allocating %ld additional SCB structures.\n",
|
2745 |
|
|
p->host_no, -1, -1, -1, scb_count);
|
2746 |
|
|
}
|
2747 |
|
|
#endif
|
2748 |
|
|
memset(scb_ap, 0, scb_count * scb_size);
|
2749 |
|
|
temp = (unsigned long) &scb_ap[scb_count];
|
2750 |
|
|
temp += 1023;
|
2751 |
|
|
temp &= ~1023;
|
2752 |
|
|
hsgp = (struct hw_scatterlist *)temp;
|
2753 |
|
|
for (i=0; i < scb_count; i++)
|
2754 |
|
|
{
|
2755 |
|
|
scbp = &scb_ap[i];
|
2756 |
|
|
scbp->hscb = &p->scb_data->hscbs[p->scb_data->numscbs];
|
2757 |
|
|
scbp->sg_list = &hsgp[i * AIC7XXX_MAX_SG];
|
2758 |
|
|
memset(scbp->hscb, 0, sizeof(struct aic7xxx_hwscb));
|
2759 |
|
|
scbp->hscb->tag = p->scb_data->numscbs;
|
2760 |
|
|
/*
|
2761 |
|
|
* Place in the scb array; never is removed
|
2762 |
|
|
*/
|
2763 |
|
|
p->scb_data->scb_array[p->scb_data->numscbs++] = scbp;
|
2764 |
|
|
scbq_insert_head(&p->scb_data->free_scbs, scbp);
|
2765 |
|
|
}
|
2766 |
|
|
scbp->kmalloc_ptr = scb_ap;
|
2767 |
|
|
}
|
2768 |
|
|
else
|
2769 |
|
|
{
|
2770 |
|
|
return(0);
|
2771 |
|
|
}
|
2772 |
|
|
}
|
2773 |
|
|
return(scb_count);
|
2774 |
|
|
}
|
2775 |
|
|
|
2776 |
|
|
/*+F*************************************************************************
|
2777 |
|
|
* Function:
|
2778 |
|
|
* aic7xxx_queue_cmd_complete
|
2779 |
|
|
*
|
2780 |
|
|
* Description:
|
2781 |
|
|
* Due to race conditions present in the SCSI subsystem, it is easier
|
2782 |
|
|
* to queue completed commands, then call scsi_done() on them when
|
2783 |
|
|
* we're finished. This function queues the completed commands.
|
2784 |
|
|
*-F*************************************************************************/
|
2785 |
|
|
static void
|
2786 |
|
|
aic7xxx_queue_cmd_complete(struct aic7xxx_host *p, Scsi_Cmnd *cmd)
|
2787 |
|
|
{
|
2788 |
|
|
cmd->host_scribble = (char *)p->completeq.head;
|
2789 |
|
|
p->completeq.head = cmd;
|
2790 |
|
|
}
|
2791 |
|
|
|
2792 |
|
|
/*+F*************************************************************************
|
2793 |
|
|
* Function:
|
2794 |
|
|
* aic7xxx_done_cmds_complete
|
2795 |
|
|
*
|
2796 |
|
|
* Description:
|
2797 |
|
|
* Process the completed command queue.
|
2798 |
|
|
*-F*************************************************************************/
|
2799 |
|
|
static void
|
2800 |
|
|
aic7xxx_done_cmds_complete(struct aic7xxx_host *p)
|
2801 |
|
|
{
|
2802 |
|
|
Scsi_Cmnd *cmd;
|
2803 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
|
2804 |
|
|
unsigned int cpu_flags = 0;
|
2805 |
|
|
#endif
|
2806 |
|
|
|
2807 |
|
|
DRIVER_LOCK
|
2808 |
|
|
while (p->completeq.head != NULL)
|
2809 |
|
|
{
|
2810 |
|
|
cmd = p->completeq.head;
|
2811 |
|
|
p->completeq.head = (Scsi_Cmnd *)cmd->host_scribble;
|
2812 |
|
|
cmd->host_scribble = NULL;
|
2813 |
|
|
cmd->scsi_done(cmd);
|
2814 |
|
|
}
|
2815 |
|
|
DRIVER_UNLOCK
|
2816 |
|
|
}
|
2817 |
|
|
|
2818 |
|
|
/*+F*************************************************************************
|
2819 |
|
|
* Function:
|
2820 |
|
|
* aic7xxx_free_scb
|
2821 |
|
|
*
|
2822 |
|
|
* Description:
|
2823 |
|
|
* Free the scb and insert into the free scb list.
|
2824 |
|
|
*-F*************************************************************************/
|
2825 |
|
|
static void
|
2826 |
|
|
aic7xxx_free_scb(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
|
2827 |
|
|
{
|
2828 |
|
|
|
2829 |
|
|
scb->flags = SCB_FREE;
|
2830 |
|
|
scb->cmd = NULL;
|
2831 |
|
|
scb->sg_count = 0;
|
2832 |
|
|
scb->sg_length = 0;
|
2833 |
|
|
scb->tag_action = 0;
|
2834 |
|
|
scb->hscb->control = 0;
|
2835 |
|
|
scb->hscb->target_status = 0;
|
2836 |
|
|
scb->hscb->target_channel_lun = SCB_LIST_NULL;
|
2837 |
|
|
|
2838 |
|
|
scbq_insert_head(&p->scb_data->free_scbs, scb);
|
2839 |
|
|
}
|
2840 |
|
|
|
2841 |
|
|
/*+F*************************************************************************
|
2842 |
|
|
* Function:
|
2843 |
|
|
* aic7xxx_done
|
2844 |
|
|
*
|
2845 |
|
|
* Description:
|
2846 |
|
|
* Calls the higher level scsi done function and frees the scb.
|
2847 |
|
|
*-F*************************************************************************/
|
2848 |
|
|
static void
|
2849 |
|
|
aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
|
2850 |
|
|
{
|
2851 |
|
|
Scsi_Cmnd *cmd = scb->cmd;
|
2852 |
|
|
int tindex = TARGET_INDEX(cmd);
|
2853 |
|
|
struct aic7xxx_scb *scbp;
|
2854 |
|
|
unsigned char queue_depth;
|
2855 |
|
|
|
2856 |
|
|
if (scb->flags & SCB_RECOVERY_SCB)
|
2857 |
|
|
{
|
2858 |
|
|
p->flags &= ~AHC_ABORT_PENDING;
|
2859 |
|
|
}
|
2860 |
|
|
if (scb->flags & SCB_RESET)
|
2861 |
|
|
{
|
2862 |
|
|
cmd->result = (DID_RESET << 16) | (cmd->result & 0xffff);
|
2863 |
|
|
}
|
2864 |
|
|
else if (scb->flags & SCB_ABORT)
|
2865 |
|
|
{
|
2866 |
|
|
cmd->result = (DID_RESET << 16) | (cmd->result & 0xffff);
|
2867 |
|
|
}
|
2868 |
|
|
else if (!(p->dev_flags[tindex] & DEVICE_SCANNED))
|
2869 |
|
|
{
|
2870 |
|
|
if ( (cmd->cmnd[0] == INQUIRY) && (cmd->result == DID_OK) )
|
2871 |
|
|
{
|
2872 |
|
|
char *buffer;
|
2873 |
|
|
|
2874 |
|
|
p->dev_flags[tindex] |= DEVICE_PRESENT;
|
2875 |
|
|
if(cmd->use_sg)
|
2876 |
|
|
{
|
2877 |
|
|
struct scatterlist *sg;
|
2878 |
|
|
|
2879 |
|
|
sg = (struct scatterlist *)cmd->request_buffer;
|
2880 |
|
|
buffer = (char *)sg[0].address;
|
2881 |
|
|
}
|
2882 |
|
|
else
|
2883 |
|
|
{
|
2884 |
|
|
buffer = (char *)cmd->request_buffer;
|
2885 |
|
|
}
|
2886 |
|
|
#define WIDE_INQUIRY_BITS 0x60
|
2887 |
|
|
#define SYNC_INQUIRY_BITS 0x10
|
2888 |
|
|
if ( (buffer[7] & WIDE_INQUIRY_BITS) &&
|
2889 |
|
|
(p->features & AHC_WIDE) )
|
2890 |
|
|
{
|
2891 |
|
|
p->needwdtr |= (1<<tindex);
|
2892 |
|
|
p->needwdtr_copy |= (1<<tindex);
|
2893 |
|
|
if ( (p->flags & AHC_SEEPROM_FOUND) &&
|
2894 |
|
|
(p->transinfo[tindex].user_width != MSG_EXT_WDTR_BUS_16_BIT) )
|
2895 |
|
|
p->transinfo[tindex].goal_width = MSG_EXT_WDTR_BUS_8_BIT;
|
2896 |
|
|
else
|
2897 |
|
|
p->transinfo[tindex].goal_width = MSG_EXT_WDTR_BUS_16_BIT;
|
2898 |
|
|
}
|
2899 |
|
|
else
|
2900 |
|
|
{
|
2901 |
|
|
p->needwdtr &= ~(1<<tindex);
|
2902 |
|
|
p->needwdtr_copy &= ~(1<<tindex);
|
2903 |
|
|
pause_sequencer(p);
|
2904 |
|
|
aic7xxx_set_width(p, cmd->target, cmd->channel, cmd->lun,
|
2905 |
|
|
MSG_EXT_WDTR_BUS_8_BIT, (AHC_TRANS_ACTIVE |
|
2906 |
|
|
AHC_TRANS_GOAL |
|
2907 |
|
|
AHC_TRANS_CUR) );
|
2908 |
|
|
unpause_sequencer(p, FALSE);
|
2909 |
|
|
}
|
2910 |
|
|
if (buffer[7] & SYNC_INQUIRY_BITS)
|
2911 |
|
|
{
|
2912 |
|
|
p->needsdtr |= (1<<tindex);
|
2913 |
|
|
p->needsdtr_copy |= (1<<tindex);
|
2914 |
|
|
|
2915 |
|
|
if (p->flags & AHC_SEEPROM_FOUND)
|
2916 |
|
|
{
|
2917 |
|
|
p->transinfo[tindex].goal_period = p->transinfo[tindex].user_period;
|
2918 |
|
|
p->transinfo[tindex].goal_offset = p->transinfo[tindex].user_offset;
|
2919 |
|
|
}
|
2920 |
|
|
else
|
2921 |
|
|
{
|
2922 |
|
|
if (p->features & AHC_ULTRA2)
|
2923 |
|
|
{
|
2924 |
|
|
p->transinfo[tindex].goal_period =
|
2925 |
|
|
aic7xxx_syncrates[AHC_SYNCRATE_ULTRA2].period;
|
2926 |
|
|
}
|
2927 |
|
|
else if (p->features & AHC_ULTRA)
|
2928 |
|
|
{
|
2929 |
|
|
p->transinfo[tindex].goal_period =
|
2930 |
|
|
aic7xxx_syncrates[AHC_SYNCRATE_ULTRA].period;
|
2931 |
|
|
}
|
2932 |
|
|
else
|
2933 |
|
|
{
|
2934 |
|
|
p->transinfo[tindex].goal_period =
|
2935 |
|
|
aic7xxx_syncrates[AHC_SYNCRATE_FAST].period;
|
2936 |
|
|
}
|
2937 |
|
|
if (p->features & AHC_ULTRA2)
|
2938 |
|
|
p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2;
|
2939 |
|
|
else if (p->transinfo[tindex].goal_width == MSG_EXT_WDTR_BUS_16_BIT)
|
2940 |
|
|
p->transinfo[tindex].goal_offset = MAX_OFFSET_16BIT;
|
2941 |
|
|
else
|
2942 |
|
|
p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT;
|
2943 |
|
|
}
|
2944 |
|
|
}
|
2945 |
|
|
else
|
2946 |
|
|
{
|
2947 |
|
|
p->needsdtr &= ~(1<<tindex);
|
2948 |
|
|
p->needsdtr_copy &= ~(1<<tindex);
|
2949 |
|
|
p->transinfo[tindex].goal_period = 0;
|
2950 |
|
|
p->transinfo[tindex].goal_offset = 0;
|
2951 |
|
|
}
|
2952 |
|
|
p->dev_flags[tindex] |= DEVICE_SCANNED;
|
2953 |
|
|
p->dev_flags[tindex] |= DEVICE_PRINT_WDTR | DEVICE_PRINT_SDTR;
|
2954 |
|
|
#undef WIDE_INQUIRY_BITS
|
2955 |
|
|
#undef SYNC_INQUIRY_BITS
|
2956 |
|
|
}
|
2957 |
|
|
}
|
2958 |
|
|
else if ((scb->flags & (SCB_MSGOUT_WDTR | SCB_MSGOUT_SDTR)) != 0)
|
2959 |
|
|
{
|
2960 |
|
|
unsigned short mask;
|
2961 |
|
|
int message_error = FALSE;
|
2962 |
|
|
|
2963 |
|
|
mask = 0x01 << tindex;
|
2964 |
|
|
|
2965 |
|
|
/*
|
2966 |
|
|
* Check to see if we get an invalid message or a message error
|
2967 |
|
|
* after failing to negotiate a wide or sync transfer message.
|
2968 |
|
|
*/
|
2969 |
|
|
if ((scb->flags & SCB_SENSE) &&
|
2970 |
|
|
((scb->cmd->sense_buffer[12] == 0x43) || /* INVALID_MESSAGE */
|
2971 |
|
|
(scb->cmd->sense_buffer[12] == 0x49))) /* MESSAGE_ERROR */
|
2972 |
|
|
{
|
2973 |
|
|
message_error = TRUE;
|
2974 |
|
|
}
|
2975 |
|
|
|
2976 |
|
|
if (scb->flags & SCB_MSGOUT_WDTR)
|
2977 |
|
|
{
|
2978 |
|
|
p->wdtr_pending &= ~mask;
|
2979 |
|
|
if (message_error)
|
2980 |
|
|
{
|
2981 |
|
|
if ( (aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
|
2982 |
|
|
(p->dev_flags[tindex] & DEVICE_PRINT_WDTR) )
|
2983 |
|
|
{
|
2984 |
|
|
printk(INFO_LEAD "Device failed to complete Wide Negotiation "
|
2985 |
|
|
"processing and\n", p->host_no, CTL_OF_SCB(scb));
|
2986 |
|
|
printk(INFO_LEAD "returned a sense error code for invalid message, "
|
2987 |
|
|
"disabling future\n", p->host_no, CTL_OF_SCB(scb));
|
2988 |
|
|
printk(INFO_LEAD "Wide negotiation to this device.\n", p->host_no,
|
2989 |
|
|
CTL_OF_SCB(scb));
|
2990 |
|
|
p->dev_flags[tindex] &= ~DEVICE_PRINT_WDTR;
|
2991 |
|
|
}
|
2992 |
|
|
p->needwdtr &= ~mask;
|
2993 |
|
|
p->needwdtr_copy &= ~mask;
|
2994 |
|
|
}
|
2995 |
|
|
}
|
2996 |
|
|
if (scb->flags & SCB_MSGOUT_SDTR)
|
2997 |
|
|
{
|
2998 |
|
|
p->sdtr_pending &= ~mask;
|
2999 |
|
|
if (message_error)
|
3000 |
|
|
{
|
3001 |
|
|
if ( (aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
|
3002 |
|
|
(p->dev_flags[tindex] & DEVICE_PRINT_SDTR) )
|
3003 |
|
|
{
|
3004 |
|
|
printk(INFO_LEAD "Device failed to complete Sync Negotiation "
|
3005 |
|
|
"processing and\n", p->host_no, CTL_OF_SCB(scb));
|
3006 |
|
|
printk(INFO_LEAD "returned a sense error code for invalid message, "
|
3007 |
|
|
"disabling future\n", p->host_no, CTL_OF_SCB(scb));
|
3008 |
|
|
printk(INFO_LEAD "Sync negotiation to this device.\n", p->host_no,
|
3009 |
|
|
CTL_OF_SCB(scb));
|
3010 |
|
|
p->dev_flags[tindex] &= ~DEVICE_PRINT_SDTR;
|
3011 |
|
|
}
|
3012 |
|
|
p->needsdtr &= ~mask;
|
3013 |
|
|
p->needsdtr_copy &= ~mask;
|
3014 |
|
|
}
|
3015 |
|
|
}
|
3016 |
|
|
}
|
3017 |
|
|
queue_depth = p->dev_temp_queue_depth[tindex];
|
3018 |
|
|
if (queue_depth >= p->dev_active_cmds[tindex])
|
3019 |
|
|
{
|
3020 |
|
|
scbp = scbq_remove_head(&p->delayed_scbs[tindex]);
|
3021 |
|
|
if (scbp)
|
3022 |
|
|
{
|
3023 |
|
|
if (queue_depth == 1)
|
3024 |
|
|
{
|
3025 |
|
|
/*
|
3026 |
|
|
* Give extra preference to untagged devices, such as CD-R devices
|
3027 |
|
|
* This makes it more likely that a drive *won't* stuff up while
|
3028 |
|
|
* waiting on data at a critical time, such as CD-R writing and
|
3029 |
|
|
* audio CD ripping operations. Should also benefit tape drives.
|
3030 |
|
|
*/
|
3031 |
|
|
scbq_insert_head(&p->waiting_scbs, scbp);
|
3032 |
|
|
}
|
3033 |
|
|
else
|
3034 |
|
|
{
|
3035 |
|
|
scbq_insert_tail(&p->waiting_scbs, scbp);
|
3036 |
|
|
}
|
3037 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
3038 |
|
|
if (aic7xxx_verbose > 0xffff)
|
3039 |
|
|
printk(INFO_LEAD "Moving SCB from delayed to waiting queue.\n",
|
3040 |
|
|
p->host_no, CTL_OF_SCB(scbp));
|
3041 |
|
|
#endif
|
3042 |
|
|
if (queue_depth > p->dev_active_cmds[tindex])
|
3043 |
|
|
{
|
3044 |
|
|
scbp = scbq_remove_head(&p->delayed_scbs[tindex]);
|
3045 |
|
|
if (scbp)
|
3046 |
|
|
scbq_insert_tail(&p->waiting_scbs, scbp);
|
3047 |
|
|
}
|
3048 |
|
|
}
|
3049 |
|
|
}
|
3050 |
|
|
if ( !(scb->tag_action) && (p->tagenable & (1<<tindex)) )
|
3051 |
|
|
{
|
3052 |
|
|
p->dev_temp_queue_depth[tindex] = p->dev_max_queue_depth[tindex];
|
3053 |
|
|
}
|
3054 |
|
|
p->dev_active_cmds[tindex]--;
|
3055 |
|
|
p->activescbs--;
|
3056 |
|
|
|
3057 |
|
|
/*
|
3058 |
|
|
* If this was an untagged I/O, unbusy the target so the sequencer won't
|
3059 |
|
|
* mistake things later
|
3060 |
|
|
*/
|
3061 |
|
|
if (aic7xxx_index_busy_target(p, scb->hscb->target_channel_lun, FALSE) ==
|
3062 |
|
|
scb->hscb->tag)
|
3063 |
|
|
{
|
3064 |
|
|
aic7xxx_index_busy_target(p, scb->hscb->target_channel_lun, TRUE);
|
3065 |
|
|
}
|
3066 |
|
|
|
3067 |
|
|
{
|
3068 |
|
|
int actual;
|
3069 |
|
|
|
3070 |
|
|
/*
|
3071 |
|
|
* XXX: we should actually know how much actually transferred
|
3072 |
|
|
* XXX: for each command, but apparently that's too difficult.
|
3073 |
|
|
*
|
3074 |
|
|
* We set a lower limit of 512 bytes on the transfer length. We
|
3075 |
|
|
* ignore anything less than this because we don't have a real
|
3076 |
|
|
* reason to count it. Read/Writes to tapes are usually about 20K
|
3077 |
|
|
* and disks are a minimum of 512 bytes unless you want to count
|
3078 |
|
|
* non-read/write commands (such as TEST_UNIT_READY) which we don't
|
3079 |
|
|
*/
|
3080 |
|
|
actual = scb->sg_length;
|
3081 |
|
|
if ((actual >= 512) && (((cmd->result >> 16) & 0xf) == DID_OK))
|
3082 |
|
|
{
|
3083 |
|
|
struct aic7xxx_xferstats *sp;
|
3084 |
|
|
#ifdef AIC7XXX_PROC_STATS
|
3085 |
|
|
long *ptr;
|
3086 |
|
|
int x;
|
3087 |
|
|
#endif /* AIC7XXX_PROC_STATS */
|
3088 |
|
|
|
3089 |
|
|
sp = &p->stats[TARGET_INDEX(cmd)];
|
3090 |
|
|
|
3091 |
|
|
/*
|
3092 |
|
|
* For block devices, cmd->request.cmd is always == either READ or
|
3093 |
|
|
* WRITE. For character devices, this isn't always set properly, so
|
3094 |
|
|
* we check data_cmnd[0]. This catches the conditions for st.c, but
|
3095 |
|
|
* I'm still not sure if request.cmd is valid for sg devices.
|
3096 |
|
|
*/
|
3097 |
|
|
if ( (cmd->request.cmd == WRITE) || (cmd->data_cmnd[0] == WRITE_6) ||
|
3098 |
|
|
(cmd->data_cmnd[0] == WRITE_FILEMARKS) )
|
3099 |
|
|
{
|
3100 |
|
|
sp->w_total++;
|
3101 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
3102 |
|
|
if ( (sp->w_total > 16) && (aic7xxx_verbose > 0xffff) )
|
3103 |
|
|
aic7xxx_verbose &= 0xffff;
|
3104 |
|
|
#endif
|
3105 |
|
|
#ifdef AIC7XXX_PROC_STATS
|
3106 |
|
|
ptr = sp->w_bins;
|
3107 |
|
|
#endif /* AIC7XXX_PROC_STATS */
|
3108 |
|
|
}
|
3109 |
|
|
else
|
3110 |
|
|
{
|
3111 |
|
|
sp->r_total++;
|
3112 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
3113 |
|
|
if ( (sp->r_total > 16) && (aic7xxx_verbose > 0xffff) )
|
3114 |
|
|
aic7xxx_verbose &= 0xffff;
|
3115 |
|
|
#endif
|
3116 |
|
|
#ifdef AIC7XXX_PROC_STATS
|
3117 |
|
|
ptr = sp->r_bins;
|
3118 |
|
|
#endif /* AIC7XXX_PROC_STATS */
|
3119 |
|
|
}
|
3120 |
|
|
#ifdef AIC7XXX_PROC_STATS
|
3121 |
|
|
x = -10;
|
3122 |
|
|
while(actual)
|
3123 |
|
|
{
|
3124 |
|
|
actual >>= 1;
|
3125 |
|
|
x++;
|
3126 |
|
|
}
|
3127 |
|
|
if (x < 0)
|
3128 |
|
|
{
|
3129 |
|
|
ptr[0]++;
|
3130 |
|
|
}
|
3131 |
|
|
else if (x > 7)
|
3132 |
|
|
{
|
3133 |
|
|
ptr[7]++;
|
3134 |
|
|
}
|
3135 |
|
|
else
|
3136 |
|
|
{
|
3137 |
|
|
ptr[x]++;
|
3138 |
|
|
}
|
3139 |
|
|
#endif /* AIC7XXX_PROC_STATS */
|
3140 |
|
|
}
|
3141 |
|
|
}
|
3142 |
|
|
aic7xxx_free_scb(p, scb);
|
3143 |
|
|
aic7xxx_queue_cmd_complete(p, cmd);
|
3144 |
|
|
|
3145 |
|
|
}
|
3146 |
|
|
|
3147 |
|
|
/*+F*************************************************************************
|
3148 |
|
|
* Function:
|
3149 |
|
|
* aic7xxx_run_done_queue
|
3150 |
|
|
*
|
3151 |
|
|
* Description:
|
3152 |
|
|
* Calls the aic7xxx_done() for the Scsi_Cmnd of each scb in the
|
3153 |
|
|
* aborted list, and adds each scb to the free list. If complete
|
3154 |
|
|
* is TRUE, we also process the commands complete list.
|
3155 |
|
|
*-F*************************************************************************/
|
3156 |
|
|
static void
|
3157 |
|
|
aic7xxx_run_done_queue(struct aic7xxx_host *p, /*complete*/ int complete)
|
3158 |
|
|
{
|
3159 |
|
|
struct aic7xxx_scb *scb;
|
3160 |
|
|
int i, found = 0;
|
3161 |
|
|
|
3162 |
|
|
for (i = 0; i < p->scb_data->numscbs; i++)
|
3163 |
|
|
{
|
3164 |
|
|
scb = p->scb_data->scb_array[i];
|
3165 |
|
|
if (scb->flags & SCB_QUEUED_FOR_DONE)
|
3166 |
|
|
{
|
3167 |
|
|
if (aic7xxx_verbose & (VERBOSE_ABORT_PROCESS | VERBOSE_RESET_PROCESS))
|
3168 |
|
|
printk(INFO_LEAD "Aborting scb %d\n",
|
3169 |
|
|
p->host_no, CTL_OF_SCB(scb), scb->hscb->tag);
|
3170 |
|
|
found++;
|
3171 |
|
|
aic7xxx_done(p, scb);
|
3172 |
|
|
}
|
3173 |
|
|
}
|
3174 |
|
|
if (aic7xxx_verbose & (VERBOSE_ABORT_RETURN | VERBOSE_RESET_RETURN))
|
3175 |
|
|
{
|
3176 |
|
|
printk(INFO_LEAD "%d commands found and queued for "
|
3177 |
|
|
"completion.\n", p->host_no, -1, -1, -1, found);
|
3178 |
|
|
}
|
3179 |
|
|
if (complete)
|
3180 |
|
|
{
|
3181 |
|
|
aic7xxx_done_cmds_complete(p);
|
3182 |
|
|
}
|
3183 |
|
|
}
|
3184 |
|
|
|
3185 |
|
|
/*+F*************************************************************************
|
3186 |
|
|
* Function:
|
3187 |
|
|
* aic7xxx_abort_waiting_scb
|
3188 |
|
|
*
|
3189 |
|
|
* Description:
|
3190 |
|
|
* Manipulate the waiting for selection list and return the
|
3191 |
|
|
* scb that follows the one that we remove.
|
3192 |
|
|
*-F*************************************************************************/
|
3193 |
|
|
static unsigned char
|
3194 |
|
|
aic7xxx_abort_waiting_scb(struct aic7xxx_host *p, struct aic7xxx_scb *scb,
|
3195 |
|
|
unsigned char scbpos, unsigned char prev)
|
3196 |
|
|
{
|
3197 |
|
|
unsigned char curscb, next;
|
3198 |
|
|
|
3199 |
|
|
/*
|
3200 |
|
|
* Select the SCB we want to abort and pull the next pointer out of it.
|
3201 |
|
|
*/
|
3202 |
|
|
curscb = aic_inb(p, SCBPTR);
|
3203 |
|
|
aic_outb(p, scbpos, SCBPTR);
|
3204 |
|
|
next = aic_inb(p, SCB_NEXT);
|
3205 |
|
|
|
3206 |
|
|
aic7xxx_add_curscb_to_free_list(p);
|
3207 |
|
|
|
3208 |
|
|
/*
|
3209 |
|
|
* Update the waiting list
|
3210 |
|
|
*/
|
3211 |
|
|
if (prev == SCB_LIST_NULL)
|
3212 |
|
|
{
|
3213 |
|
|
/*
|
3214 |
|
|
* First in the list
|
3215 |
|
|
*/
|
3216 |
|
|
aic_outb(p, next, WAITING_SCBH);
|
3217 |
|
|
}
|
3218 |
|
|
else
|
3219 |
|
|
{
|
3220 |
|
|
/*
|
3221 |
|
|
* Select the scb that pointed to us and update its next pointer.
|
3222 |
|
|
*/
|
3223 |
|
|
aic_outb(p, prev, SCBPTR);
|
3224 |
|
|
aic_outb(p, next, SCB_NEXT);
|
3225 |
|
|
}
|
3226 |
|
|
/*
|
3227 |
|
|
* Point us back at the original scb position and inform the SCSI
|
3228 |
|
|
* system that the command has been aborted.
|
3229 |
|
|
*/
|
3230 |
|
|
aic_outb(p, curscb, SCBPTR);
|
3231 |
|
|
return (next);
|
3232 |
|
|
}
|
3233 |
|
|
|
3234 |
|
|
/*+F*************************************************************************
|
3235 |
|
|
* Function:
|
3236 |
|
|
* aic7xxx_search_qinfifo
|
3237 |
|
|
*
|
3238 |
|
|
* Description:
|
3239 |
|
|
* Search the queue-in FIFO for matching SCBs and conditionally
|
3240 |
|
|
* requeue. Returns the number of matching SCBs.
|
3241 |
|
|
*-F*************************************************************************/
|
3242 |
|
|
static int
|
3243 |
|
|
aic7xxx_search_qinfifo(struct aic7xxx_host *p, int target, int channel,
|
3244 |
|
|
int lun, unsigned char tag, int flags, int requeue,
|
3245 |
|
|
volatile scb_queue_type *queue)
|
3246 |
|
|
{
|
3247 |
|
|
int found;
|
3248 |
|
|
unsigned char qinpos, qintail;
|
3249 |
|
|
struct aic7xxx_scb *scbp;
|
3250 |
|
|
|
3251 |
|
|
found = 0;
|
3252 |
|
|
qinpos = aic_inb(p, QINPOS);
|
3253 |
|
|
qintail = p->qinfifonext;
|
3254 |
|
|
|
3255 |
|
|
p->qinfifonext = qinpos;
|
3256 |
|
|
|
3257 |
|
|
while (qinpos != qintail)
|
3258 |
|
|
{
|
3259 |
|
|
scbp = p->scb_data->scb_array[p->qinfifo[qinpos++]];
|
3260 |
|
|
if (aic7xxx_match_scb(p, scbp, target, channel, lun, tag))
|
3261 |
|
|
{
|
3262 |
|
|
/*
|
3263 |
|
|
* We found an scb that needs to be removed.
|
3264 |
|
|
*/
|
3265 |
|
|
if (requeue && (queue != NULL))
|
3266 |
|
|
{
|
3267 |
|
|
if (scbp->flags & SCB_WAITINGQ)
|
3268 |
|
|
{
|
3269 |
|
|
scbq_remove(queue, scbp);
|
3270 |
|
|
scbq_remove(&p->waiting_scbs, scbp);
|
3271 |
|
|
scbq_remove(&p->delayed_scbs[TARGET_INDEX(scbp->cmd)], scbp);
|
3272 |
|
|
p->dev_active_cmds[TARGET_INDEX(scbp->cmd)]++;
|
3273 |
|
|
p->activescbs++;
|
3274 |
|
|
}
|
3275 |
|
|
scbq_insert_tail(queue, scbp);
|
3276 |
|
|
p->dev_active_cmds[TARGET_INDEX(scbp->cmd)]--;
|
3277 |
|
|
p->activescbs--;
|
3278 |
|
|
scbp->flags |= SCB_WAITINGQ;
|
3279 |
|
|
if ( !(scbp->tag_action & TAG_ENB) )
|
3280 |
|
|
{
|
3281 |
|
|
aic7xxx_index_busy_target(p, scbp->hscb->target_channel_lun,
|
3282 |
|
|
TRUE);
|
3283 |
|
|
}
|
3284 |
|
|
}
|
3285 |
|
|
else if (requeue)
|
3286 |
|
|
{
|
3287 |
|
|
p->qinfifo[p->qinfifonext++] = scbp->hscb->tag;
|
3288 |
|
|
}
|
3289 |
|
|
else
|
3290 |
|
|
{
|
3291 |
|
|
/*
|
3292 |
|
|
* Preserve any SCB_RECOVERY_SCB flags on this scb then set the
|
3293 |
|
|
* flags we were called with, presumeably so aic7xxx_run_done_queue
|
3294 |
|
|
* can find this scb
|
3295 |
|
|
*/
|
3296 |
|
|
scbp->flags = flags | (scbp->flags & SCB_RECOVERY_SCB);
|
3297 |
|
|
if (aic7xxx_index_busy_target(p, scbp->hscb->target_channel_lun,
|
3298 |
|
|
FALSE) == scbp->hscb->tag)
|
3299 |
|
|
{
|
3300 |
|
|
aic7xxx_index_busy_target(p, scbp->hscb->target_channel_lun,
|
3301 |
|
|
TRUE);
|
3302 |
|
|
}
|
3303 |
|
|
}
|
3304 |
|
|
found++;
|
3305 |
|
|
}
|
3306 |
|
|
else
|
3307 |
|
|
{
|
3308 |
|
|
p->qinfifo[p->qinfifonext++] = scbp->hscb->tag;
|
3309 |
|
|
}
|
3310 |
|
|
}
|
3311 |
|
|
/*
|
3312 |
|
|
* Now that we've done the work, clear out any left over commands in the
|
3313 |
|
|
* qinfifo and update the KERNEL_QINPOS down on the card.
|
3314 |
|
|
*
|
3315 |
|
|
* NOTE: This routine expect the sequencer to already be paused when
|
3316 |
|
|
* it is run....make sure it's that way!
|
3317 |
|
|
*/
|
3318 |
|
|
qinpos = p->qinfifonext;
|
3319 |
|
|
while(qinpos != qintail)
|
3320 |
|
|
{
|
3321 |
|
|
p->qinfifo[qinpos++] = SCB_LIST_NULL;
|
3322 |
|
|
}
|
3323 |
|
|
if (p->features & AHC_QUEUE_REGS)
|
3324 |
|
|
aic_outb(p, p->qinfifonext, HNSCB_QOFF);
|
3325 |
|
|
else
|
3326 |
|
|
aic_outb(p, p->qinfifonext, KERNEL_QINPOS);
|
3327 |
|
|
|
3328 |
|
|
return (found);
|
3329 |
|
|
}
|
3330 |
|
|
|
3331 |
|
|
/*+F*************************************************************************
|
3332 |
|
|
* Function:
|
3333 |
|
|
* aic7xxx_scb_on_qoutfifo
|
3334 |
|
|
*
|
3335 |
|
|
* Description:
|
3336 |
|
|
* Is the scb that was passed to us currently on the qoutfifo?
|
3337 |
|
|
*-F*************************************************************************/
|
3338 |
|
|
static int
|
3339 |
|
|
aic7xxx_scb_on_qoutfifo(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
|
3340 |
|
|
{
|
3341 |
|
|
int i=0;
|
3342 |
|
|
|
3343 |
|
|
while(p->qoutfifo[(p->qoutfifonext + i) & 0xff ] != SCB_LIST_NULL)
|
3344 |
|
|
{
|
3345 |
|
|
if(p->qoutfifo[(p->qoutfifonext + i) & 0xff ] == scb->hscb->tag)
|
3346 |
|
|
return TRUE;
|
3347 |
|
|
else
|
3348 |
|
|
i++;
|
3349 |
|
|
}
|
3350 |
|
|
return FALSE;
|
3351 |
|
|
}
|
3352 |
|
|
|
3353 |
|
|
|
3354 |
|
|
/*+F*************************************************************************
|
3355 |
|
|
* Function:
|
3356 |
|
|
* aic7xxx_reset_device
|
3357 |
|
|
*
|
3358 |
|
|
* Description:
|
3359 |
|
|
* The device at the given target/channel has been reset. Abort
|
3360 |
|
|
* all active and queued scbs for that target/channel. This function
|
3361 |
|
|
* need not worry about linked next pointers because if was a MSG_ABORT_TAG
|
3362 |
|
|
* then we had a tagged command (no linked next), if it was MSG_ABORT or
|
3363 |
|
|
* MSG_BUS_DEV_RESET then the device won't know about any commands any more
|
3364 |
|
|
* and no busy commands will exist, and if it was a bus reset, then nothing
|
3365 |
|
|
* knows about any linked next commands any more. In all cases, we don't
|
3366 |
|
|
* need to worry about the linked next or busy scb, we just need to clear
|
3367 |
|
|
* them.
|
3368 |
|
|
*-F*************************************************************************/
|
3369 |
|
|
static void
|
3370 |
|
|
aic7xxx_reset_device(struct aic7xxx_host *p, int target, int channel,
|
3371 |
|
|
int lun, unsigned char tag)
|
3372 |
|
|
{
|
3373 |
|
|
struct aic7xxx_scb *scbp;
|
3374 |
|
|
unsigned char active_scb, tcl;
|
3375 |
|
|
int i = 0, j, init_lists = FALSE;
|
3376 |
|
|
|
3377 |
|
|
/*
|
3378 |
|
|
* Restore this when we're done
|
3379 |
|
|
*/
|
3380 |
|
|
active_scb = aic_inb(p, SCBPTR);
|
3381 |
|
|
|
3382 |
|
|
if (aic7xxx_verbose & (VERBOSE_RESET_PROCESS | VERBOSE_ABORT_PROCESS))
|
3383 |
|
|
printk(INFO_LEAD "Reset device, active_scb %d\n",
|
3384 |
|
|
p->host_no, channel, target, lun, active_scb);
|
3385 |
|
|
/*
|
3386 |
|
|
* Deal with the busy target and linked next issues.
|
3387 |
|
|
*/
|
3388 |
|
|
{
|
3389 |
|
|
int min_target, max_target;
|
3390 |
|
|
struct aic7xxx_scb *scbp, *prev_scbp;
|
3391 |
|
|
|
3392 |
|
|
/* Make all targets 'relative' to bus A. */
|
3393 |
|
|
if (target == ALL_TARGETS)
|
3394 |
|
|
{
|
3395 |
|
|
switch (channel)
|
3396 |
|
|
{
|
3397 |
|
|
case 0:
|
3398 |
|
|
min_target = 0;
|
3399 |
|
|
max_target = (p->features & AHC_WIDE) ? 15 : 7;
|
3400 |
|
|
break;
|
3401 |
|
|
case 1:
|
3402 |
|
|
min_target = 8;
|
3403 |
|
|
max_target = 15;
|
3404 |
|
|
break;
|
3405 |
|
|
case ALL_CHANNELS:
|
3406 |
|
|
default:
|
3407 |
|
|
min_target = 0;
|
3408 |
|
|
max_target = (p->features & (AHC_TWIN|AHC_WIDE)) ? 15 : 7;
|
3409 |
|
|
break;
|
3410 |
|
|
}
|
3411 |
|
|
}
|
3412 |
|
|
else
|
3413 |
|
|
{
|
3414 |
|
|
min_target = target | (channel << 3);
|
3415 |
|
|
max_target = min_target;
|
3416 |
|
|
}
|
3417 |
|
|
|
3418 |
|
|
|
3419 |
|
|
for (i = min_target; i <= max_target; i++)
|
3420 |
|
|
{
|
3421 |
|
|
if ( i == p->scsi_id )
|
3422 |
|
|
{
|
3423 |
|
|
continue;
|
3424 |
|
|
}
|
3425 |
|
|
if (aic7xxx_verbose & (VERBOSE_ABORT_PROCESS | VERBOSE_RESET_PROCESS))
|
3426 |
|
|
printk(INFO_LEAD "Cleaning up status information "
|
3427 |
|
|
"and delayed_scbs.\n", p->host_no, channel, i, lun);
|
3428 |
|
|
p->dev_flags[i] &= ~BUS_DEVICE_RESET_PENDING;
|
3429 |
|
|
if ( tag == SCB_LIST_NULL )
|
3430 |
|
|
{
|
3431 |
|
|
p->dev_flags[i] |= DEVICE_PRINT_WDTR | DEVICE_PRINT_SDTR |
|
3432 |
|
|
DEVICE_RESET_DELAY;
|
3433 |
|
|
p->dev_expires[i] = jiffies + (4 * HZ);
|
3434 |
|
|
p->dev_timer_active |= (0x01 << i);
|
3435 |
|
|
p->dev_last_queue_full_count[i] = 0;
|
3436 |
|
|
p->dev_last_queue_full[i] = 0;
|
3437 |
|
|
p->dev_temp_queue_depth[i] =
|
3438 |
|
|
p->dev_max_queue_depth[i];
|
3439 |
|
|
}
|
3440 |
|
|
for(j=0; j<MAX_LUNS; j++)
|
3441 |
|
|
{
|
3442 |
|
|
if (channel == 1)
|
3443 |
|
|
tcl = ((i << 4) & 0x70) | (channel << 3) | j;
|
3444 |
|
|
else
|
3445 |
|
|
tcl = (i << 4) | (channel << 3) | j;
|
3446 |
|
|
if ( (aic7xxx_index_busy_target(p, tcl, FALSE) == tag) ||
|
3447 |
|
|
(tag == SCB_LIST_NULL) )
|
3448 |
|
|
aic7xxx_index_busy_target(p, tcl, /* unbusy */ TRUE);
|
3449 |
|
|
}
|
3450 |
|
|
j = 0;
|
3451 |
|
|
prev_scbp = NULL;
|
3452 |
|
|
scbp = p->delayed_scbs[i].head;
|
3453 |
|
|
while ( (scbp != NULL) && (j++ <= (p->scb_data->numscbs + 1)) )
|
3454 |
|
|
{
|
3455 |
|
|
prev_scbp = scbp;
|
3456 |
|
|
scbp = scbp->q_next;
|
3457 |
|
|
if ( prev_scbp == scbp )
|
3458 |
|
|
{
|
3459 |
|
|
if (aic7xxx_verbose & (VERBOSE_ABORT | VERBOSE_RESET))
|
3460 |
|
|
printk(WARN_LEAD "Yikes!! scb->q_next == scb "
|
3461 |
|
|
"in the delayed_scbs queue!\n", p->host_no, channel, i, lun);
|
3462 |
|
|
scbp = NULL;
|
3463 |
|
|
prev_scbp->q_next = NULL;
|
3464 |
|
|
p->delayed_scbs[i].tail = prev_scbp;
|
3465 |
|
|
}
|
3466 |
|
|
if (aic7xxx_match_scb(p, prev_scbp, target, channel, lun, tag))
|
3467 |
|
|
{
|
3468 |
|
|
scbq_remove(&p->delayed_scbs[i], prev_scbp);
|
3469 |
|
|
if (prev_scbp->flags & SCB_WAITINGQ)
|
3470 |
|
|
{
|
3471 |
|
|
p->dev_active_cmds[i]++;
|
3472 |
|
|
p->activescbs++;
|
3473 |
|
|
}
|
3474 |
|
|
prev_scbp->flags &= ~(SCB_ACTIVE | SCB_WAITINGQ);
|
3475 |
|
|
prev_scbp->flags |= SCB_RESET | SCB_QUEUED_FOR_DONE;
|
3476 |
|
|
}
|
3477 |
|
|
}
|
3478 |
|
|
if ( j > (p->scb_data->maxscbs + 1) )
|
3479 |
|
|
{
|
3480 |
|
|
if (aic7xxx_verbose & (VERBOSE_ABORT | VERBOSE_RESET))
|
3481 |
|
|
printk(WARN_LEAD "Yikes!! There's a loop in the "
|
3482 |
|
|
"delayed_scbs queue!\n", p->host_no, channel, i, lun);
|
3483 |
|
|
scbq_init(&p->delayed_scbs[i]);
|
3484 |
|
|
}
|
3485 |
|
|
if ( !(p->dev_timer_active & (0x01 << MAX_TARGETS)) ||
|
3486 |
|
|
time_after_eq(p->dev_timer.expires, p->dev_expires[i]) )
|
3487 |
|
|
{
|
3488 |
|
|
del_timer(&p->dev_timer);
|
3489 |
|
|
p->dev_timer.expires = p->dev_expires[i];
|
3490 |
|
|
add_timer(&p->dev_timer);
|
3491 |
|
|
p->dev_timer_active |= (0x01 << MAX_TARGETS);
|
3492 |
|
|
}
|
3493 |
|
|
}
|
3494 |
|
|
}
|
3495 |
|
|
|
3496 |
|
|
if (aic7xxx_verbose & (VERBOSE_ABORT_PROCESS | VERBOSE_RESET_PROCESS))
|
3497 |
|
|
printk(INFO_LEAD "Cleaning QINFIFO.\n", p->host_no, channel, target, lun );
|
3498 |
|
|
aic7xxx_search_qinfifo(p, target, channel, lun, tag,
|
3499 |
|
|
SCB_RESET | SCB_QUEUED_FOR_DONE, /* requeue */ FALSE, NULL);
|
3500 |
|
|
|
3501 |
|
|
/*
|
3502 |
|
|
* Search the waiting_scbs queue for matches, this catches any SCB_QUEUED
|
3503 |
|
|
* ABORT/RESET commands.
|
3504 |
|
|
*/
|
3505 |
|
|
if (aic7xxx_verbose & (VERBOSE_ABORT_PROCESS | VERBOSE_RESET_PROCESS))
|
3506 |
|
|
printk(INFO_LEAD "Cleaning waiting_scbs.\n", p->host_no, channel,
|
3507 |
|
|
target, lun );
|
3508 |
|
|
{
|
3509 |
|
|
struct aic7xxx_scb *scbp, *prev_scbp;
|
3510 |
|
|
|
3511 |
|
|
j = 0;
|
3512 |
|
|
prev_scbp = NULL;
|
3513 |
|
|
scbp = p->waiting_scbs.head;
|
3514 |
|
|
while ( (scbp != NULL) && (j++ <= (p->scb_data->numscbs + 1)) )
|
3515 |
|
|
{
|
3516 |
|
|
prev_scbp = scbp;
|
3517 |
|
|
scbp = scbp->q_next;
|
3518 |
|
|
if ( prev_scbp == scbp )
|
3519 |
|
|
{
|
3520 |
|
|
if (aic7xxx_verbose & (VERBOSE_ABORT | VERBOSE_RESET))
|
3521 |
|
|
printk(WARN_LEAD "Yikes!! scb->q_next == scb "
|
3522 |
|
|
"in the waiting_scbs queue!\n", p->host_no, CTL_OF_SCB(scbp));
|
3523 |
|
|
scbp = NULL;
|
3524 |
|
|
prev_scbp->q_next = NULL;
|
3525 |
|
|
p->waiting_scbs.tail = prev_scbp;
|
3526 |
|
|
}
|
3527 |
|
|
if (aic7xxx_match_scb(p, prev_scbp, target, channel, lun, tag))
|
3528 |
|
|
{
|
3529 |
|
|
scbq_remove(&p->waiting_scbs, prev_scbp);
|
3530 |
|
|
if (prev_scbp->flags & SCB_WAITINGQ)
|
3531 |
|
|
{
|
3532 |
|
|
p->dev_active_cmds[TARGET_INDEX(prev_scbp->cmd)]++;
|
3533 |
|
|
p->activescbs++;
|
3534 |
|
|
}
|
3535 |
|
|
prev_scbp->flags &= ~(SCB_ACTIVE | SCB_WAITINGQ);
|
3536 |
|
|
prev_scbp->flags |= SCB_RESET | SCB_QUEUED_FOR_DONE;
|
3537 |
|
|
}
|
3538 |
|
|
}
|
3539 |
|
|
if ( j > (p->scb_data->maxscbs + 1) )
|
3540 |
|
|
{
|
3541 |
|
|
if (aic7xxx_verbose & (VERBOSE_ABORT | VERBOSE_RESET))
|
3542 |
|
|
printk(WARN_LEAD "Yikes!! There's a loop in the "
|
3543 |
|
|
"waiting_scbs queue!\n", p->host_no, channel, target, lun);
|
3544 |
|
|
scbq_init(&p->waiting_scbs);
|
3545 |
|
|
}
|
3546 |
|
|
}
|
3547 |
|
|
|
3548 |
|
|
|
3549 |
|
|
/*
|
3550 |
|
|
* Search waiting for selection list.
|
3551 |
|
|
*/
|
3552 |
|
|
if (aic7xxx_verbose & (VERBOSE_ABORT_PROCESS | VERBOSE_RESET_PROCESS))
|
3553 |
|
|
printk(INFO_LEAD "Cleaning waiting for selection "
|
3554 |
|
|
"list.\n", p->host_no, channel, target, lun);
|
3555 |
|
|
{
|
3556 |
|
|
unsigned char next, prev, scb_index;
|
3557 |
|
|
|
3558 |
|
|
next = aic_inb(p, WAITING_SCBH); /* Start at head of list. */
|
3559 |
|
|
prev = SCB_LIST_NULL;
|
3560 |
|
|
j = 0;
|
3561 |
|
|
while ( (next != SCB_LIST_NULL) && (j++ <= (p->scb_data->maxscbs + 1)) )
|
3562 |
|
|
{
|
3563 |
|
|
aic_outb(p, next, SCBPTR);
|
3564 |
|
|
scb_index = aic_inb(p, SCB_TAG);
|
3565 |
|
|
if (scb_index >= p->scb_data->numscbs)
|
3566 |
|
|
{
|
3567 |
|
|
/*
|
3568 |
|
|
* No aic7xxx_verbose check here.....we want to see this since it
|
3569 |
|
|
* means either the kernel driver or the sequencer screwed things up
|
3570 |
|
|
*/
|
3571 |
|
|
printk(WARN_LEAD "Waiting List inconsistency; SCB index=%d, "
|
3572 |
|
|
"numscbs=%d\n", p->host_no, channel, target, lun, scb_index,
|
3573 |
|
|
p->scb_data->numscbs);
|
3574 |
|
|
next = aic_inb(p, SCB_NEXT);
|
3575 |
|
|
aic7xxx_add_curscb_to_free_list(p);
|
3576 |
|
|
}
|
3577 |
|
|
else
|
3578 |
|
|
{
|
3579 |
|
|
scbp = p->scb_data->scb_array[scb_index];
|
3580 |
|
|
if (aic7xxx_match_scb(p, scbp, target, channel, lun, tag))
|
3581 |
|
|
{
|
3582 |
|
|
next = aic7xxx_abort_waiting_scb(p, scbp, next, prev);
|
3583 |
|
|
if (scbp->flags & SCB_WAITINGQ)
|
3584 |
|
|
{
|
3585 |
|
|
p->dev_active_cmds[TARGET_INDEX(scbp->cmd)]++;
|
3586 |
|
|
p->activescbs++;
|
3587 |
|
|
}
|
3588 |
|
|
scbp->flags &= ~(SCB_ACTIVE | SCB_WAITINGQ);
|
3589 |
|
|
scbp->flags |= SCB_RESET | SCB_QUEUED_FOR_DONE;
|
3590 |
|
|
if (prev == SCB_LIST_NULL)
|
3591 |
|
|
{
|
3592 |
|
|
/*
|
3593 |
|
|
* This is either the first scb on the waiting list, or we
|
3594 |
|
|
* have already yanked the first and haven't left any behind.
|
3595 |
|
|
* Either way, we need to turn off the selection hardware if
|
3596 |
|
|
* it isn't already off.
|
3597 |
|
|
*/
|
3598 |
|
|
aic_outb(p, aic_inb(p, SCSISEQ) & ~ENSELO, SCSISEQ);
|
3599 |
|
|
aic_outb(p, CLRSELTIMEO, CLRSINT1);
|
3600 |
|
|
}
|
3601 |
|
|
}
|
3602 |
|
|
else
|
3603 |
|
|
{
|
3604 |
|
|
prev = next;
|
3605 |
|
|
next = aic_inb(p, SCB_NEXT);
|
3606 |
|
|
}
|
3607 |
|
|
}
|
3608 |
|
|
}
|
3609 |
|
|
if ( j > (p->scb_data->maxscbs + 1) )
|
3610 |
|
|
{
|
3611 |
|
|
printk(WARN_LEAD "Yikes!! There is a loop in the waiting for "
|
3612 |
|
|
"selection list!\n", p->host_no, channel, target, lun);
|
3613 |
|
|
init_lists = TRUE;
|
3614 |
|
|
}
|
3615 |
|
|
}
|
3616 |
|
|
|
3617 |
|
|
/*
|
3618 |
|
|
* Go through disconnected list and remove any entries we have queued
|
3619 |
|
|
* for completion, zeroing their control byte too.
|
3620 |
|
|
*/
|
3621 |
|
|
if (aic7xxx_verbose & (VERBOSE_ABORT_PROCESS | VERBOSE_RESET_PROCESS))
|
3622 |
|
|
printk(INFO_LEAD "Cleaning disconnected scbs "
|
3623 |
|
|
"list.\n", p->host_no, channel, target, lun);
|
3624 |
|
|
if (p->flags & AHC_PAGESCBS)
|
3625 |
|
|
{
|
3626 |
|
|
unsigned char next, prev, scb_index;
|
3627 |
|
|
|
3628 |
|
|
next = aic_inb(p, DISCONNECTED_SCBH);
|
3629 |
|
|
prev = SCB_LIST_NULL;
|
3630 |
|
|
j = 0;
|
3631 |
|
|
while ( (next != SCB_LIST_NULL) && (j++ <= (p->scb_data->maxscbs + 1)) )
|
3632 |
|
|
{
|
3633 |
|
|
aic_outb(p, next, SCBPTR);
|
3634 |
|
|
scb_index = aic_inb(p, SCB_TAG);
|
3635 |
|
|
if (scb_index > p->scb_data->numscbs)
|
3636 |
|
|
{
|
3637 |
|
|
printk(WARN_LEAD "Disconnected List inconsistency; SCB index=%d, "
|
3638 |
|
|
"numscbs=%d\n", p->host_no, channel, target, lun, scb_index,
|
3639 |
|
|
p->scb_data->numscbs);
|
3640 |
|
|
next = aic7xxx_rem_scb_from_disc_list(p, next);
|
3641 |
|
|
}
|
3642 |
|
|
else
|
3643 |
|
|
{
|
3644 |
|
|
scbp = p->scb_data->scb_array[scb_index];
|
3645 |
|
|
if (aic7xxx_match_scb(p, scbp, target, channel, lun, tag))
|
3646 |
|
|
{
|
3647 |
|
|
next = aic7xxx_rem_scb_from_disc_list(p, next);
|
3648 |
|
|
if (scbp->flags & SCB_WAITINGQ)
|
3649 |
|
|
{
|
3650 |
|
|
p->dev_active_cmds[TARGET_INDEX(scbp->cmd)]++;
|
3651 |
|
|
p->activescbs++;
|
3652 |
|
|
}
|
3653 |
|
|
scbp->flags &= ~(SCB_ACTIVE | SCB_WAITINGQ);
|
3654 |
|
|
scbp->flags |= SCB_RESET | SCB_QUEUED_FOR_DONE;
|
3655 |
|
|
scbp->hscb->control = 0;
|
3656 |
|
|
}
|
3657 |
|
|
else
|
3658 |
|
|
{
|
3659 |
|
|
prev = next;
|
3660 |
|
|
next = aic_inb(p, SCB_NEXT);
|
3661 |
|
|
}
|
3662 |
|
|
}
|
3663 |
|
|
}
|
3664 |
|
|
if ( j > (p->scb_data->maxscbs + 1) )
|
3665 |
|
|
{
|
3666 |
|
|
printk(WARN_LEAD "Yikes!! There is a loop in the disconnected list!\n",
|
3667 |
|
|
p->host_no, channel, target, lun);
|
3668 |
|
|
init_lists = TRUE;
|
3669 |
|
|
}
|
3670 |
|
|
}
|
3671 |
|
|
|
3672 |
|
|
/*
|
3673 |
|
|
* Walk the free list making sure no entries on the free list have
|
3674 |
|
|
* a valid SCB_TAG value or SCB_CONTROL byte.
|
3675 |
|
|
*/
|
3676 |
|
|
if (p->flags & AHC_PAGESCBS)
|
3677 |
|
|
{
|
3678 |
|
|
unsigned char next;
|
3679 |
|
|
|
3680 |
|
|
j = 0;
|
3681 |
|
|
next = aic_inb(p, FREE_SCBH);
|
3682 |
|
|
if ( (next >= p->scb_data->maxhscbs) && (next != SCB_LIST_NULL) )
|
3683 |
|
|
{
|
3684 |
|
|
printk(WARN_LEAD "Bogus FREE_SCBH!.\n", p->host_no, channel,
|
3685 |
|
|
target, lun);
|
3686 |
|
|
init_lists = TRUE;
|
3687 |
|
|
next = SCB_LIST_NULL;
|
3688 |
|
|
}
|
3689 |
|
|
while ( (next != SCB_LIST_NULL) && (j++ <= (p->scb_data->maxscbs + 1)) )
|
3690 |
|
|
{
|
3691 |
|
|
aic_outb(p, next, SCBPTR);
|
3692 |
|
|
if (aic_inb(p, SCB_TAG) < p->scb_data->numscbs)
|
3693 |
|
|
{
|
3694 |
|
|
printk(WARN_LEAD "Free list inconsistency!.\n", p->host_no, channel,
|
3695 |
|
|
target, lun);
|
3696 |
|
|
init_lists = TRUE;
|
3697 |
|
|
next = SCB_LIST_NULL;
|
3698 |
|
|
}
|
3699 |
|
|
else
|
3700 |
|
|
{
|
3701 |
|
|
aic_outb(p, SCB_LIST_NULL, SCB_TAG);
|
3702 |
|
|
aic_outb(p, 0, SCB_CONTROL);
|
3703 |
|
|
next = aic_inb(p, SCB_NEXT);
|
3704 |
|
|
}
|
3705 |
|
|
}
|
3706 |
|
|
if ( j > (p->scb_data->maxscbs + 1) )
|
3707 |
|
|
{
|
3708 |
|
|
printk(WARN_LEAD "Yikes!! There is a loop in the free list!\n",
|
3709 |
|
|
p->host_no, channel, target, lun);
|
3710 |
|
|
init_lists = TRUE;
|
3711 |
|
|
}
|
3712 |
|
|
}
|
3713 |
|
|
|
3714 |
|
|
/*
|
3715 |
|
|
* Go through the hardware SCB array looking for commands that
|
3716 |
|
|
* were active but not on any list.
|
3717 |
|
|
*/
|
3718 |
|
|
if (init_lists)
|
3719 |
|
|
{
|
3720 |
|
|
aic_outb(p, SCB_LIST_NULL, FREE_SCBH);
|
3721 |
|
|
aic_outb(p, SCB_LIST_NULL, WAITING_SCBH);
|
3722 |
|
|
aic_outb(p, SCB_LIST_NULL, DISCONNECTED_SCBH);
|
3723 |
|
|
}
|
3724 |
|
|
for (i = p->scb_data->maxhscbs - 1; i >= 0; i--)
|
3725 |
|
|
{
|
3726 |
|
|
unsigned char scbid;
|
3727 |
|
|
|
3728 |
|
|
aic_outb(p, i, SCBPTR);
|
3729 |
|
|
if (init_lists)
|
3730 |
|
|
{
|
3731 |
|
|
aic_outb(p, SCB_LIST_NULL, SCB_TAG);
|
3732 |
|
|
aic_outb(p, SCB_LIST_NULL, SCB_NEXT);
|
3733 |
|
|
aic_outb(p, SCB_LIST_NULL, SCB_PREV);
|
3734 |
|
|
aic_outb(p, 0, SCB_CONTROL);
|
3735 |
|
|
aic7xxx_add_curscb_to_free_list(p);
|
3736 |
|
|
}
|
3737 |
|
|
else
|
3738 |
|
|
{
|
3739 |
|
|
scbid = aic_inb(p, SCB_TAG);
|
3740 |
|
|
if (scbid < p->scb_data->numscbs)
|
3741 |
|
|
{
|
3742 |
|
|
scbp = p->scb_data->scb_array[scbid];
|
3743 |
|
|
if (aic7xxx_match_scb(p, scbp, target, channel, lun, tag))
|
3744 |
|
|
{
|
3745 |
|
|
aic_outb(p, 0, SCB_CONTROL);
|
3746 |
|
|
aic_outb(p, SCB_LIST_NULL, SCB_TAG);
|
3747 |
|
|
aic7xxx_add_curscb_to_free_list(p);
|
3748 |
|
|
}
|
3749 |
|
|
}
|
3750 |
|
|
}
|
3751 |
|
|
}
|
3752 |
|
|
|
3753 |
|
|
/*
|
3754 |
|
|
* Go through the entire SCB array now and look for commands for
|
3755 |
|
|
* for this target that are stillactive. These are other (most likely
|
3756 |
|
|
* tagged) commands that were disconnected when the reset occurred.
|
3757 |
|
|
* Any commands we find here we know this about, it wasn't on any queue,
|
3758 |
|
|
* it wasn't in the qinfifo, it wasn't in the disconnected or waiting
|
3759 |
|
|
* lists, so it really must have been a paged out SCB. In that case,
|
3760 |
|
|
* we shouldn't need to bother with updating any counters, just mark
|
3761 |
|
|
* the correct flags and go on.
|
3762 |
|
|
*/
|
3763 |
|
|
for (i = 0; i < p->scb_data->numscbs; i++)
|
3764 |
|
|
{
|
3765 |
|
|
scbp = p->scb_data->scb_array[i];
|
3766 |
|
|
if ((scbp->flags & SCB_ACTIVE) &&
|
3767 |
|
|
aic7xxx_match_scb(p, scbp, target, channel, lun, tag) &&
|
3768 |
|
|
!aic7xxx_scb_on_qoutfifo(p, scbp))
|
3769 |
|
|
{
|
3770 |
|
|
if (scbp->flags & SCB_WAITINGQ)
|
3771 |
|
|
{
|
3772 |
|
|
scbq_remove(&p->waiting_scbs, scbp);
|
3773 |
|
|
scbq_remove(&p->delayed_scbs[TARGET_INDEX(scbp->cmd)], scbp);
|
3774 |
|
|
p->dev_active_cmds[TARGET_INDEX(scbp->cmd)]++;
|
3775 |
|
|
p->activescbs++;
|
3776 |
|
|
}
|
3777 |
|
|
scbp->flags |= SCB_RESET | SCB_QUEUED_FOR_DONE;
|
3778 |
|
|
scbp->flags &= ~(SCB_ACTIVE | SCB_WAITINGQ);
|
3779 |
|
|
}
|
3780 |
|
|
}
|
3781 |
|
|
|
3782 |
|
|
aic_outb(p, active_scb, SCBPTR);
|
3783 |
|
|
}
|
3784 |
|
|
|
3785 |
|
|
|
3786 |
|
|
/*+F*************************************************************************
|
3787 |
|
|
* Function:
|
3788 |
|
|
* aic7xxx_clear_intstat
|
3789 |
|
|
*
|
3790 |
|
|
* Description:
|
3791 |
|
|
* Clears the interrupt status.
|
3792 |
|
|
*-F*************************************************************************/
|
3793 |
|
|
static void
|
3794 |
|
|
aic7xxx_clear_intstat(struct aic7xxx_host *p)
|
3795 |
|
|
{
|
3796 |
|
|
/* Clear any interrupt conditions this may have caused. */
|
3797 |
|
|
aic_outb(p, CLRSELDO | CLRSELDI | CLRSELINGO, CLRSINT0);
|
3798 |
|
|
aic_outb(p, CLRSELTIMEO | CLRATNO | CLRSCSIRSTI | CLRBUSFREE | CLRSCSIPERR |
|
3799 |
|
|
CLRPHASECHG | CLRREQINIT, CLRSINT1);
|
3800 |
|
|
aic_outb(p, CLRSCSIINT | CLRSEQINT | CLRBRKADRINT | CLRPARERR, CLRINT);
|
3801 |
|
|
}
|
3802 |
|
|
|
3803 |
|
|
/*+F*************************************************************************
|
3804 |
|
|
* Function:
|
3805 |
|
|
* aic7xxx_reset_current_bus
|
3806 |
|
|
*
|
3807 |
|
|
* Description:
|
3808 |
|
|
* Reset the current SCSI bus.
|
3809 |
|
|
*-F*************************************************************************/
|
3810 |
|
|
static void
|
3811 |
|
|
aic7xxx_reset_current_bus(struct aic7xxx_host *p)
|
3812 |
|
|
{
|
3813 |
|
|
|
3814 |
|
|
/* Disable reset interrupts. */
|
3815 |
|
|
aic_outb(p, aic_inb(p, SIMODE1) & ~ENSCSIRST, SIMODE1);
|
3816 |
|
|
|
3817 |
|
|
/* Turn off the bus' current operations, after all, we shouldn't have any
|
3818 |
|
|
* valid commands left to cause a RSELI and SELO once we've tossed the
|
3819 |
|
|
* bus away with this reset, so we might as well shut down the sequencer
|
3820 |
|
|
* until the bus is restarted as oppossed to saving the current settings
|
3821 |
|
|
* and restoring them (which makes no sense to me). */
|
3822 |
|
|
|
3823 |
|
|
/* Turn on the bus reset. */
|
3824 |
|
|
aic_outb(p, aic_inb(p, SCSISEQ) | SCSIRSTO, SCSISEQ);
|
3825 |
|
|
while ( (aic_inb(p, SCSISEQ) & SCSIRSTO) == 0)
|
3826 |
|
|
mdelay(5);
|
3827 |
|
|
|
3828 |
|
|
mdelay(10);
|
3829 |
|
|
|
3830 |
|
|
/* Turn off the bus reset. */
|
3831 |
|
|
aic_outb(p, 0, SCSISEQ);
|
3832 |
|
|
mdelay(5);
|
3833 |
|
|
|
3834 |
|
|
aic7xxx_clear_intstat(p);
|
3835 |
|
|
/* Re-enable reset interrupts. */
|
3836 |
|
|
aic_outb(p, aic_inb(p, SIMODE1) | ENSCSIRST, SIMODE1);
|
3837 |
|
|
|
3838 |
|
|
}
|
3839 |
|
|
|
3840 |
|
|
/*+F*************************************************************************
|
3841 |
|
|
* Function:
|
3842 |
|
|
* aic7xxx_reset_channel
|
3843 |
|
|
*
|
3844 |
|
|
* Description:
|
3845 |
|
|
* Reset the channel.
|
3846 |
|
|
*-F*************************************************************************/
|
3847 |
|
|
static void
|
3848 |
|
|
aic7xxx_reset_channel(struct aic7xxx_host *p, int channel, int initiate_reset)
|
3849 |
|
|
{
|
3850 |
|
|
unsigned long offset_min, offset_max;
|
3851 |
|
|
unsigned char sblkctl;
|
3852 |
|
|
int cur_channel;
|
3853 |
|
|
|
3854 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
|
3855 |
|
|
printk(INFO_LEAD "Reset channel called, %s initiate reset.\n",
|
3856 |
|
|
p->host_no, channel, -1, -1, (initiate_reset==TRUE) ? "will" : "won't" );
|
3857 |
|
|
|
3858 |
|
|
|
3859 |
|
|
if (channel == 1)
|
3860 |
|
|
{
|
3861 |
|
|
p->needsdtr |= (p->needsdtr_copy & 0xFF00);
|
3862 |
|
|
p->sdtr_pending &= 0x00FF;
|
3863 |
|
|
offset_min = 8;
|
3864 |
|
|
offset_max = 16;
|
3865 |
|
|
}
|
3866 |
|
|
else
|
3867 |
|
|
{
|
3868 |
|
|
if (p->features & AHC_WIDE)
|
3869 |
|
|
{
|
3870 |
|
|
p->needsdtr = p->needsdtr_copy;
|
3871 |
|
|
p->needwdtr = p->needwdtr_copy;
|
3872 |
|
|
p->sdtr_pending = 0x0;
|
3873 |
|
|
p->wdtr_pending = 0x0;
|
3874 |
|
|
offset_min = 0;
|
3875 |
|
|
offset_max = 16;
|
3876 |
|
|
}
|
3877 |
|
|
else
|
3878 |
|
|
{
|
3879 |
|
|
/* Channel A */
|
3880 |
|
|
p->needsdtr |= (p->needsdtr_copy & 0x00FF);
|
3881 |
|
|
p->sdtr_pending &= 0xFF00;
|
3882 |
|
|
offset_min = 0;
|
3883 |
|
|
offset_max = 8;
|
3884 |
|
|
}
|
3885 |
|
|
}
|
3886 |
|
|
|
3887 |
|
|
while (offset_min < offset_max)
|
3888 |
|
|
{
|
3889 |
|
|
/*
|
3890 |
|
|
* Revert to async/narrow transfers until we renegotiate.
|
3891 |
|
|
*/
|
3892 |
|
|
aic_outb(p, 0, TARG_SCSIRATE + offset_min);
|
3893 |
|
|
if (p->features & AHC_ULTRA2)
|
3894 |
|
|
{
|
3895 |
|
|
aic_outb(p, 0, TARG_OFFSET + offset_min);
|
3896 |
|
|
}
|
3897 |
|
|
offset_min++;
|
3898 |
|
|
}
|
3899 |
|
|
|
3900 |
|
|
/*
|
3901 |
|
|
* Reset the bus and unpause/restart the controller
|
3902 |
|
|
*/
|
3903 |
|
|
sblkctl = aic_inb(p, SBLKCTL);
|
3904 |
|
|
if ( (p->chip & AHC_CHIPID_MASK) == AHC_AIC7770 )
|
3905 |
|
|
cur_channel = (sblkctl & SELBUSB) >> 3;
|
3906 |
|
|
else
|
3907 |
|
|
cur_channel = 0;
|
3908 |
|
|
if ( (cur_channel != channel) && (p->features & AHC_TWIN) )
|
3909 |
|
|
{
|
3910 |
|
|
/*
|
3911 |
|
|
* Case 1: Command for another bus is active
|
3912 |
|
|
*/
|
3913 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
|
3914 |
|
|
printk(INFO_LEAD "Stealthily resetting idle channel.\n", p->host_no,
|
3915 |
|
|
channel, -1, -1);
|
3916 |
|
|
/*
|
3917 |
|
|
* Stealthily reset the other bus without upsetting the current bus.
|
3918 |
|
|
*/
|
3919 |
|
|
aic_outb(p, sblkctl ^ SELBUSB, SBLKCTL);
|
3920 |
|
|
aic_outb(p, aic_inb(p, SIMODE1) & ~ENBUSFREE, SIMODE1);
|
3921 |
|
|
if (initiate_reset)
|
3922 |
|
|
{
|
3923 |
|
|
aic7xxx_reset_current_bus(p);
|
3924 |
|
|
}
|
3925 |
|
|
aic_outb(p, aic_inb(p, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP), SCSISEQ);
|
3926 |
|
|
aic7xxx_clear_intstat(p);
|
3927 |
|
|
aic_outb(p, sblkctl, SBLKCTL);
|
3928 |
|
|
}
|
3929 |
|
|
else
|
3930 |
|
|
{
|
3931 |
|
|
/*
|
3932 |
|
|
* Case 2: A command from this bus is active or we're idle.
|
3933 |
|
|
*/
|
3934 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
|
3935 |
|
|
printk(INFO_LEAD "Resetting currently active channel.\n", p->host_no,
|
3936 |
|
|
channel, -1, -1);
|
3937 |
|
|
aic_outb(p, aic_inb(p, SIMODE1) & ~(ENBUSFREE|ENREQINIT),
|
3938 |
|
|
SIMODE1);
|
3939 |
|
|
p->flags &= ~AHC_HANDLING_REQINITS;
|
3940 |
|
|
p->msg_type = MSG_TYPE_NONE;
|
3941 |
|
|
p->msg_len = 0;
|
3942 |
|
|
if (initiate_reset)
|
3943 |
|
|
{
|
3944 |
|
|
aic7xxx_reset_current_bus(p);
|
3945 |
|
|
}
|
3946 |
|
|
aic_outb(p, aic_inb(p, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP), SCSISEQ);
|
3947 |
|
|
aic7xxx_clear_intstat(p);
|
3948 |
|
|
}
|
3949 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_RETURN)
|
3950 |
|
|
printk(INFO_LEAD "Channel reset\n", p->host_no, channel, -1, -1);
|
3951 |
|
|
/*
|
3952 |
|
|
* Clean up all the state information for the pending transactions
|
3953 |
|
|
* on this bus.
|
3954 |
|
|
*/
|
3955 |
|
|
aic7xxx_reset_device(p, ALL_TARGETS, channel, ALL_LUNS, SCB_LIST_NULL);
|
3956 |
|
|
|
3957 |
|
|
if ( !(p->features & AHC_TWIN) )
|
3958 |
|
|
{
|
3959 |
|
|
restart_sequencer(p);
|
3960 |
|
|
}
|
3961 |
|
|
|
3962 |
|
|
return;
|
3963 |
|
|
}
|
3964 |
|
|
|
3965 |
|
|
/*+F*************************************************************************
|
3966 |
|
|
* Function:
|
3967 |
|
|
* aic7xxx_run_waiting_queues
|
3968 |
|
|
*
|
3969 |
|
|
* Description:
|
3970 |
|
|
* Scan the awaiting_scbs queue downloading and starting as many
|
3971 |
|
|
* scbs as we can.
|
3972 |
|
|
*-F*************************************************************************/
|
3973 |
|
|
static void
|
3974 |
|
|
aic7xxx_run_waiting_queues(struct aic7xxx_host *p)
|
3975 |
|
|
{
|
3976 |
|
|
struct aic7xxx_scb *scb;
|
3977 |
|
|
int tindex;
|
3978 |
|
|
int sent;
|
3979 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
|
3980 |
|
|
unsigned long cpu_flags = 0;
|
3981 |
|
|
#endif
|
3982 |
|
|
|
3983 |
|
|
|
3984 |
|
|
if (p->waiting_scbs.head == NULL)
|
3985 |
|
|
return;
|
3986 |
|
|
|
3987 |
|
|
sent = 0;
|
3988 |
|
|
|
3989 |
|
|
/*
|
3990 |
|
|
* First handle SCBs that are waiting but have been assigned a slot.
|
3991 |
|
|
*/
|
3992 |
|
|
DRIVER_LOCK
|
3993 |
|
|
while ((scb = scbq_remove_head(&p->waiting_scbs)) != NULL)
|
3994 |
|
|
{
|
3995 |
|
|
tindex = TARGET_INDEX(scb->cmd);
|
3996 |
|
|
if ( !scb->tag_action && (p->tagenable & (1<<tindex)) )
|
3997 |
|
|
{
|
3998 |
|
|
p->dev_temp_queue_depth[tindex] = 1;
|
3999 |
|
|
}
|
4000 |
|
|
if ( (p->dev_active_cmds[tindex] >=
|
4001 |
|
|
p->dev_temp_queue_depth[tindex]) ||
|
4002 |
|
|
(p->dev_flags[tindex] & (DEVICE_RESET_DELAY|DEVICE_WAS_BUSY)) ||
|
4003 |
|
|
(p->flags & AHC_RESET_DELAY) )
|
4004 |
|
|
{
|
4005 |
|
|
scbq_insert_tail(&p->delayed_scbs[tindex], scb);
|
4006 |
|
|
}
|
4007 |
|
|
else
|
4008 |
|
|
{
|
4009 |
|
|
scb->flags &= ~SCB_WAITINGQ;
|
4010 |
|
|
p->dev_active_cmds[tindex]++;
|
4011 |
|
|
p->activescbs++;
|
4012 |
|
|
if ( !(scb->tag_action) )
|
4013 |
|
|
{
|
4014 |
|
|
aic7xxx_busy_target(p, scb);
|
4015 |
|
|
}
|
4016 |
|
|
p->qinfifo[p->qinfifonext++] = scb->hscb->tag;
|
4017 |
|
|
sent++;
|
4018 |
|
|
}
|
4019 |
|
|
}
|
4020 |
|
|
if (sent)
|
4021 |
|
|
{
|
4022 |
|
|
if (p->features & AHC_QUEUE_REGS)
|
4023 |
|
|
aic_outb(p, p->qinfifonext, HNSCB_QOFF);
|
4024 |
|
|
else
|
4025 |
|
|
{
|
4026 |
|
|
pause_sequencer(p);
|
4027 |
|
|
aic_outb(p, p->qinfifonext, KERNEL_QINPOS);
|
4028 |
|
|
unpause_sequencer(p, FALSE);
|
4029 |
|
|
}
|
4030 |
|
|
if (p->activescbs > p->max_activescbs)
|
4031 |
|
|
p->max_activescbs = p->activescbs;
|
4032 |
|
|
}
|
4033 |
|
|
DRIVER_UNLOCK
|
4034 |
|
|
}
|
4035 |
|
|
|
4036 |
|
|
#ifdef CONFIG_PCI
|
4037 |
|
|
|
4038 |
|
|
#define DPE 0x80
|
4039 |
|
|
#define SSE 0x40
|
4040 |
|
|
#define RMA 0x20
|
4041 |
|
|
#define RTA 0x10
|
4042 |
|
|
#define STA 0x08
|
4043 |
|
|
#define DPR 0x01
|
4044 |
|
|
|
4045 |
|
|
/*+F*************************************************************************
|
4046 |
|
|
* Function:
|
4047 |
|
|
* aic7xxx_pci_intr
|
4048 |
|
|
*
|
4049 |
|
|
* Description:
|
4050 |
|
|
* Check the scsi card for PCI errors and clear the interrupt
|
4051 |
|
|
*
|
4052 |
|
|
* NOTE: If you don't have this function and a 2940 card encounters
|
4053 |
|
|
* a PCI error condition, the machine will end up locked as the
|
4054 |
|
|
* interrupt handler gets slammed with non-stop PCI error interrupts
|
4055 |
|
|
*-F*************************************************************************/
|
4056 |
|
|
static void
|
4057 |
|
|
aic7xxx_pci_intr(struct aic7xxx_host *p)
|
4058 |
|
|
{
|
4059 |
|
|
unsigned char status1;
|
4060 |
|
|
|
4061 |
|
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
|
4062 |
|
|
pci_read_config_byte(p->pdev, PCI_STATUS + 1, &status1);
|
4063 |
|
|
#else
|
4064 |
|
|
pcibios_read_config_byte(p->pci_bus, p->pci_device_fn,
|
4065 |
|
|
PCI_STATUS + 1, &status1);
|
4066 |
|
|
#endif
|
4067 |
|
|
|
4068 |
|
|
if ( (status1 & DPE) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
|
4069 |
|
|
printk(WARN_LEAD "Data Parity Error during PCI address or PCI write"
|
4070 |
|
|
"phase.\n", p->host_no, -1, -1, -1);
|
4071 |
|
|
if ( (status1 & SSE) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
|
4072 |
|
|
printk(WARN_LEAD "Signal System Error Detected\n", p->host_no,
|
4073 |
|
|
-1, -1, -1);
|
4074 |
|
|
if ( (status1 & RMA) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
|
4075 |
|
|
printk(WARN_LEAD "Received a PCI Master Abort\n", p->host_no,
|
4076 |
|
|
-1, -1, -1);
|
4077 |
|
|
if ( (status1 & RTA) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
|
4078 |
|
|
printk(WARN_LEAD "Received a PCI Target Abort\n", p->host_no,
|
4079 |
|
|
-1, -1, -1);
|
4080 |
|
|
if ( (status1 & STA) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
|
4081 |
|
|
printk(WARN_LEAD "Signaled a PCI Target Abort\n", p->host_no,
|
4082 |
|
|
-1, -1, -1);
|
4083 |
|
|
if ( (status1 & DPR) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
|
4084 |
|
|
printk(WARN_LEAD "Data Parity Error has been reported via PCI pin "
|
4085 |
|
|
"PERR#\n", p->host_no, -1, -1, -1);
|
4086 |
|
|
|
4087 |
|
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
|
4088 |
|
|
pci_write_config_byte(p->pdev, PCI_STATUS + 1, status1);
|
4089 |
|
|
#else
|
4090 |
|
|
pcibios_write_config_byte(p->pci_bus, p->pci_device_fn,
|
4091 |
|
|
PCI_STATUS + 1, status1);
|
4092 |
|
|
#endif
|
4093 |
|
|
if (status1 & (DPR|RMA|RTA))
|
4094 |
|
|
aic_outb(p, CLRPARERR, CLRINT);
|
4095 |
|
|
|
4096 |
|
|
if ( (aic7xxx_panic_on_abort) && (p->spurious_int > 500) )
|
4097 |
|
|
aic7xxx_panic_abort(p, NULL);
|
4098 |
|
|
|
4099 |
|
|
}
|
4100 |
|
|
#endif /* CONFIG_PCI */
|
4101 |
|
|
|
4102 |
|
|
/*+F*************************************************************************
|
4103 |
|
|
* Function:
|
4104 |
|
|
* aic7xxx_timer
|
4105 |
|
|
*
|
4106 |
|
|
* Description:
|
4107 |
|
|
* Take expired extries off of delayed queues and place on waiting queue
|
4108 |
|
|
* then run waiting queue to start commands.
|
4109 |
|
|
***************************************************************************/
|
4110 |
|
|
static void
|
4111 |
|
|
aic7xxx_timer(struct aic7xxx_host *p)
|
4112 |
|
|
{
|
4113 |
|
|
int i, j;
|
4114 |
|
|
unsigned long cpu_flags = 0;
|
4115 |
|
|
struct aic7xxx_scb *scb;
|
4116 |
|
|
|
4117 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
|
4118 |
|
|
DRIVER_LOCK
|
4119 |
|
|
#else
|
4120 |
|
|
spin_lock_irqsave(&io_request_lock, cpu_flags);
|
4121 |
|
|
#endif
|
4122 |
|
|
p->dev_timer_active &= ~(0x01 << MAX_TARGETS);
|
4123 |
|
|
if ( (p->dev_timer_active & (0x01 << p->scsi_id)) &&
|
4124 |
|
|
time_after_eq(jiffies, p->dev_expires[p->scsi_id]) )
|
4125 |
|
|
{
|
4126 |
|
|
p->flags &= ~AHC_RESET_DELAY;
|
4127 |
|
|
p->dev_timer_active &= ~(0x01 << p->scsi_id);
|
4128 |
|
|
}
|
4129 |
|
|
for(i=0; i<MAX_TARGETS; i++)
|
4130 |
|
|
{
|
4131 |
|
|
if ( (i != p->scsi_id) &&
|
4132 |
|
|
(p->dev_timer_active & (0x01 << i)) &&
|
4133 |
|
|
time_after_eq(jiffies, p->dev_expires[i]) )
|
4134 |
|
|
{
|
4135 |
|
|
p->dev_timer_active &= ~(0x01 << i);
|
4136 |
|
|
p->dev_flags[i] &= ~(DEVICE_RESET_DELAY|DEVICE_WAS_BUSY);
|
4137 |
|
|
p->dev_temp_queue_depth[i] = p->dev_max_queue_depth[i];
|
4138 |
|
|
j = 0;
|
4139 |
|
|
while ( ((scb = scbq_remove_head(&p->delayed_scbs[i])) != NULL) &&
|
4140 |
|
|
(j++ < p->scb_data->numscbs) )
|
4141 |
|
|
{
|
4142 |
|
|
scbq_insert_tail(&p->waiting_scbs, scb);
|
4143 |
|
|
}
|
4144 |
|
|
if (j == p->scb_data->numscbs)
|
4145 |
|
|
{
|
4146 |
|
|
printk(INFO_LEAD "timer: Yikes, loop in delayed_scbs list.\n",
|
4147 |
|
|
p->host_no, 0, i, -1);
|
4148 |
|
|
scbq_init(&p->delayed_scbs[i]);
|
4149 |
|
|
scbq_init(&p->waiting_scbs);
|
4150 |
|
|
/*
|
4151 |
|
|
* Well, things are screwed now, wait for a reset to clean the junk
|
4152 |
|
|
* out.
|
4153 |
|
|
*/
|
4154 |
|
|
}
|
4155 |
|
|
}
|
4156 |
|
|
else if ( p->dev_timer_active & (0x01 << i) )
|
4157 |
|
|
{
|
4158 |
|
|
if ( p->dev_timer_active & (0x01 << MAX_TARGETS) )
|
4159 |
|
|
{
|
4160 |
|
|
if ( time_after_eq(p->dev_timer.expires, p->dev_expires[i]) )
|
4161 |
|
|
{
|
4162 |
|
|
p->dev_timer.expires = p->dev_expires[i];
|
4163 |
|
|
}
|
4164 |
|
|
}
|
4165 |
|
|
else
|
4166 |
|
|
{
|
4167 |
|
|
p->dev_timer.expires = p->dev_expires[i];
|
4168 |
|
|
p->dev_timer_active |= (0x01 << MAX_TARGETS);
|
4169 |
|
|
}
|
4170 |
|
|
}
|
4171 |
|
|
}
|
4172 |
|
|
if ( p->dev_timer_active & (0x01 << MAX_TARGETS) )
|
4173 |
|
|
{
|
4174 |
|
|
add_timer(&p->dev_timer);
|
4175 |
|
|
}
|
4176 |
|
|
|
4177 |
|
|
aic7xxx_run_waiting_queues(p);
|
4178 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
|
4179 |
|
|
DRIVER_UNLOCK
|
4180 |
|
|
#else
|
4181 |
|
|
spin_unlock_irqrestore(&io_request_lock, cpu_flags);
|
4182 |
|
|
#endif
|
4183 |
|
|
}
|
4184 |
|
|
|
4185 |
|
|
/*+F*************************************************************************
|
4186 |
|
|
* Function:
|
4187 |
|
|
* aic7xxx_construct_sdtr
|
4188 |
|
|
*
|
4189 |
|
|
* Description:
|
4190 |
|
|
* Constucts a synchronous data transfer message in the message
|
4191 |
|
|
* buffer on the sequencer.
|
4192 |
|
|
*-F*************************************************************************/
|
4193 |
|
|
static void
|
4194 |
|
|
aic7xxx_construct_sdtr(struct aic7xxx_host *p, unsigned char period,
|
4195 |
|
|
unsigned char offset)
|
4196 |
|
|
{
|
4197 |
|
|
p->msg_buf[p->msg_index++] = MSG_EXTENDED;
|
4198 |
|
|
p->msg_buf[p->msg_index++] = MSG_EXT_SDTR_LEN;
|
4199 |
|
|
p->msg_buf[p->msg_index++] = MSG_EXT_SDTR;
|
4200 |
|
|
p->msg_buf[p->msg_index++] = period;
|
4201 |
|
|
p->msg_buf[p->msg_index++] = offset;
|
4202 |
|
|
p->msg_len += 5;
|
4203 |
|
|
}
|
4204 |
|
|
|
4205 |
|
|
/*+F*************************************************************************
|
4206 |
|
|
* Function:
|
4207 |
|
|
* aic7xxx_construct_wdtr
|
4208 |
|
|
*
|
4209 |
|
|
* Description:
|
4210 |
|
|
* Constucts a wide data transfer message in the message buffer
|
4211 |
|
|
* on the sequencer.
|
4212 |
|
|
*-F*************************************************************************/
|
4213 |
|
|
static void
|
4214 |
|
|
aic7xxx_construct_wdtr(struct aic7xxx_host *p, unsigned char bus_width)
|
4215 |
|
|
{
|
4216 |
|
|
p->msg_buf[p->msg_index++] = MSG_EXTENDED;
|
4217 |
|
|
p->msg_buf[p->msg_index++] = MSG_EXT_WDTR_LEN;
|
4218 |
|
|
p->msg_buf[p->msg_index++] = MSG_EXT_WDTR;
|
4219 |
|
|
p->msg_buf[p->msg_index++] = bus_width;
|
4220 |
|
|
p->msg_len += 4;
|
4221 |
|
|
}
|
4222 |
|
|
|
4223 |
|
|
/*+F*************************************************************************
|
4224 |
|
|
* Function:
|
4225 |
|
|
* aic7xxx_calc_residual
|
4226 |
|
|
*
|
4227 |
|
|
* Description:
|
4228 |
|
|
* Calculate the residual data not yet transferred.
|
4229 |
|
|
*-F*************************************************************************/
|
4230 |
|
|
static void
|
4231 |
|
|
aic7xxx_calculate_residual (struct aic7xxx_host *p, struct aic7xxx_scb *scb)
|
4232 |
|
|
{
|
4233 |
|
|
struct aic7xxx_hwscb *hscb;
|
4234 |
|
|
Scsi_Cmnd *cmd;
|
4235 |
|
|
int actual, i;
|
4236 |
|
|
|
4237 |
|
|
cmd = scb->cmd;
|
4238 |
|
|
hscb = scb->hscb;
|
4239 |
|
|
|
4240 |
|
|
/*
|
4241 |
|
|
* Don't destroy valid residual information with
|
4242 |
|
|
* residual coming from a check sense operation.
|
4243 |
|
|
*/
|
4244 |
|
|
if (((scb->hscb->control & DISCONNECTED) == 0) &&
|
4245 |
|
|
(scb->flags & SCB_SENSE) == 0)
|
4246 |
|
|
{
|
4247 |
|
|
/*
|
4248 |
|
|
* We had an underflow. At this time, there's only
|
4249 |
|
|
* one other driver that bothers to check for this,
|
4250 |
|
|
* and cmd->underflow seems to be set rather half-
|
4251 |
|
|
* heartedly in the higher-level SCSI code.
|
4252 |
|
|
*/
|
4253 |
|
|
actual = scb->sg_length;
|
4254 |
|
|
for (i=1; i < hscb->residual_SG_segment_count; i++)
|
4255 |
|
|
{
|
4256 |
|
|
actual -= scb->sg_list[scb->sg_count - i].length;
|
4257 |
|
|
}
|
4258 |
|
|
actual -= (hscb->residual_data_count[2] << 16) |
|
4259 |
|
|
(hscb->residual_data_count[1] << 8) |
|
4260 |
|
|
hscb->residual_data_count[0];
|
4261 |
|
|
|
4262 |
|
|
if (actual < cmd->underflow)
|
4263 |
|
|
{
|
4264 |
|
|
if (aic7xxx_verbose & VERBOSE_MINOR_ERROR)
|
4265 |
|
|
printk(INFO_LEAD "Underflow - Wanted %u, %s %u, residual SG "
|
4266 |
|
|
"count %d.\n", p->host_no, CTL_OF_SCB(scb), cmd->underflow,
|
4267 |
|
|
(cmd->request.cmd == WRITE) ? "wrote" : "read", actual,
|
4268 |
|
|
hscb->residual_SG_segment_count);
|
4269 |
|
|
aic7xxx_error(cmd) = DID_RETRY_COMMAND;
|
4270 |
|
|
aic7xxx_status(cmd) = hscb->target_status;
|
4271 |
|
|
}
|
4272 |
|
|
}
|
4273 |
|
|
|
4274 |
|
|
/*
|
4275 |
|
|
* Clean out the residual information in the SCB for the
|
4276 |
|
|
* next consumer.
|
4277 |
|
|
*/
|
4278 |
|
|
hscb->residual_data_count[2] = 0;
|
4279 |
|
|
hscb->residual_data_count[1] = 0;
|
4280 |
|
|
hscb->residual_data_count[0] = 0;
|
4281 |
|
|
hscb->residual_SG_segment_count = 0;
|
4282 |
|
|
}
|
4283 |
|
|
|
4284 |
|
|
/*+F*************************************************************************
|
4285 |
|
|
* Function:
|
4286 |
|
|
* aic7xxx_handle_device_reset
|
4287 |
|
|
*
|
4288 |
|
|
* Description:
|
4289 |
|
|
* Interrupt handler for sequencer interrupts (SEQINT).
|
4290 |
|
|
*-F*************************************************************************/
|
4291 |
|
|
static void
|
4292 |
|
|
aic7xxx_handle_device_reset(struct aic7xxx_host *p, int target, int channel)
|
4293 |
|
|
{
|
4294 |
|
|
unsigned short targ_mask;
|
4295 |
|
|
unsigned char tindex = target;
|
4296 |
|
|
|
4297 |
|
|
tindex |= ((channel & 0x01) << 3);
|
4298 |
|
|
|
4299 |
|
|
targ_mask = (0x01 << tindex);
|
4300 |
|
|
/*
|
4301 |
|
|
* Go back to async/narrow transfers and renegotiate.
|
4302 |
|
|
*/
|
4303 |
|
|
p->needsdtr |= (p->needsdtr_copy & targ_mask);
|
4304 |
|
|
p->needwdtr |= (p->needwdtr_copy & targ_mask);
|
4305 |
|
|
p->sdtr_pending &= ~targ_mask;
|
4306 |
|
|
p->wdtr_pending &= ~targ_mask;
|
4307 |
|
|
aic_outb(p, 0, TARG_SCSIRATE + tindex);
|
4308 |
|
|
if (p->features & AHC_ULTRA2)
|
4309 |
|
|
aic_outb(p, 0, TARG_OFFSET + tindex);
|
4310 |
|
|
aic7xxx_reset_device(p, target, channel, ALL_LUNS, SCB_LIST_NULL);
|
4311 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
|
4312 |
|
|
printk(INFO_LEAD "Bus Device Reset delivered.\n", p->host_no, channel,
|
4313 |
|
|
target, -1);
|
4314 |
|
|
aic7xxx_run_done_queue(p, /*complete*/ FALSE);
|
4315 |
|
|
}
|
4316 |
|
|
|
4317 |
|
|
/*+F*************************************************************************
|
4318 |
|
|
* Function:
|
4319 |
|
|
* aic7xxx_handle_seqint
|
4320 |
|
|
*
|
4321 |
|
|
* Description:
|
4322 |
|
|
* Interrupt handler for sequencer interrupts (SEQINT).
|
4323 |
|
|
*-F*************************************************************************/
|
4324 |
|
|
static void
|
4325 |
|
|
aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat)
|
4326 |
|
|
{
|
4327 |
|
|
struct aic7xxx_scb *scb;
|
4328 |
|
|
unsigned short target_mask;
|
4329 |
|
|
unsigned char target, lun, tindex;
|
4330 |
|
|
unsigned char queue_flag = FALSE;
|
4331 |
|
|
char channel;
|
4332 |
|
|
|
4333 |
|
|
target = ((aic_inb(p, SAVED_TCL) >> 4) & 0x0f);
|
4334 |
|
|
if ( (p->chip & AHC_CHIPID_MASK) == AHC_AIC7770 )
|
4335 |
|
|
channel = (aic_inb(p, SBLKCTL) & SELBUSB) >> 3;
|
4336 |
|
|
else
|
4337 |
|
|
channel = 0;
|
4338 |
|
|
tindex = target + (channel << 3);
|
4339 |
|
|
lun = aic_inb(p, SAVED_TCL) & 0x07;
|
4340 |
|
|
target_mask = (0x01 << tindex);
|
4341 |
|
|
|
4342 |
|
|
/*
|
4343 |
|
|
* Go ahead and clear the SEQINT now, that avoids any interrupt race
|
4344 |
|
|
* conditions later on in case we enable some other interrupt.
|
4345 |
|
|
*/
|
4346 |
|
|
aic_outb(p, CLRSEQINT, CLRINT);
|
4347 |
|
|
switch (intstat & SEQINT_MASK)
|
4348 |
|
|
{
|
4349 |
|
|
case NO_MATCH:
|
4350 |
|
|
{
|
4351 |
|
|
aic_outb(p, aic_inb(p, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP),
|
4352 |
|
|
SCSISEQ);
|
4353 |
|
|
printk(WARN_LEAD "No active SCB for reconnecting target - Issuing "
|
4354 |
|
|
"BUS DEVICE RESET.\n", p->host_no, channel, target, lun);
|
4355 |
|
|
printk(WARN_LEAD " SAVED_TCL=0x%x, ARG_1=0x%x, SEQADDR=0x%x\n",
|
4356 |
|
|
p->host_no, channel, target, lun,
|
4357 |
|
|
aic_inb(p, SAVED_TCL), aic_inb(p, ARG_1),
|
4358 |
|
|
(aic_inb(p, SEQADDR1) << 8) | aic_inb(p, SEQADDR0));
|
4359 |
|
|
}
|
4360 |
|
|
break;
|
4361 |
|
|
|
4362 |
|
|
case SEND_REJECT:
|
4363 |
|
|
{
|
4364 |
|
|
if (aic7xxx_verbose & VERBOSE_MINOR_ERROR)
|
4365 |
|
|
printk(INFO_LEAD "Rejecting unknown message (0x%x) received from "
|
4366 |
|
|
"target, SEQ_FLAGS=0x%x\n", p->host_no, channel, target, lun,
|
4367 |
|
|
aic_inb(p, ACCUM), aic_inb(p, SEQ_FLAGS));
|
4368 |
|
|
}
|
4369 |
|
|
break;
|
4370 |
|
|
|
4371 |
|
|
case NO_IDENT:
|
4372 |
|
|
{
|
4373 |
|
|
/*
|
4374 |
|
|
* The reconnecting target either did not send an identify
|
4375 |
|
|
* message, or did, but we didn't find an SCB to match and
|
4376 |
|
|
* before it could respond to our ATN/abort, it hit a dataphase.
|
4377 |
|
|
* The only safe thing to do is to blow it away with a bus
|
4378 |
|
|
* reset.
|
4379 |
|
|
*/
|
4380 |
|
|
if (aic7xxx_verbose & (VERBOSE_SEQINT | VERBOSE_RESET_MID))
|
4381 |
|
|
printk(INFO_LEAD "Target did not send an IDENTIFY message; "
|
4382 |
|
|
"LASTPHASE 0x%x, SAVED_TCL 0x%x\n", p->host_no, channel, target,
|
4383 |
|
|
lun, aic_inb(p, LASTPHASE), aic_inb(p, SAVED_TCL));
|
4384 |
|
|
|
4385 |
|
|
aic7xxx_reset_channel(p, channel, /*initiate reset*/ TRUE);
|
4386 |
|
|
aic7xxx_run_done_queue(p, FALSE);
|
4387 |
|
|
|
4388 |
|
|
}
|
4389 |
|
|
break;
|
4390 |
|
|
|
4391 |
|
|
case BAD_PHASE:
|
4392 |
|
|
if (aic_inb(p, LASTPHASE) == P_BUSFREE)
|
4393 |
|
|
{
|
4394 |
|
|
if (aic7xxx_verbose & VERBOSE_SEQINT)
|
4395 |
|
|
printk(INFO_LEAD "Missed busfree.\n", p->host_no, channel,
|
4396 |
|
|
target, lun);
|
4397 |
|
|
restart_sequencer(p);
|
4398 |
|
|
}
|
4399 |
|
|
else
|
4400 |
|
|
{
|
4401 |
|
|
if (aic7xxx_verbose & VERBOSE_SEQINT)
|
4402 |
|
|
printk(INFO_LEAD "Unknown scsi bus phase, continuing\n", p->host_no,
|
4403 |
|
|
channel, target, lun);
|
4404 |
|
|
}
|
4405 |
|
|
break;
|
4406 |
|
|
|
4407 |
|
|
case EXTENDED_MSG:
|
4408 |
|
|
{
|
4409 |
|
|
p->msg_type = MSG_TYPE_INITIATOR_MSGIN;
|
4410 |
|
|
p->msg_len = 0;
|
4411 |
|
|
p->msg_index = 0;
|
4412 |
|
|
|
4413 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
4414 |
|
|
if (aic7xxx_verbose > 0xffff)
|
4415 |
|
|
printk(INFO_LEAD "Enabling REQINITs for MSG_IN\n", p->host_no,
|
4416 |
|
|
channel, target, lun);
|
4417 |
|
|
#endif
|
4418 |
|
|
|
4419 |
|
|
/*
|
4420 |
|
|
* To actually receive the message, simply turn on
|
4421 |
|
|
* REQINIT interrupts and let our interrupt handler
|
4422 |
|
|
* do the rest (REQINIT should already be true).
|
4423 |
|
|
*/
|
4424 |
|
|
p->flags |= AHC_HANDLING_REQINITS;
|
4425 |
|
|
aic_outb(p, aic_inb(p, SIMODE1) | ENREQINIT, SIMODE1);
|
4426 |
|
|
|
4427 |
|
|
/*
|
4428 |
|
|
* We don't want the sequencer unpaused yet so we return early
|
4429 |
|
|
*/
|
4430 |
|
|
return;
|
4431 |
|
|
}
|
4432 |
|
|
|
4433 |
|
|
case REJECT_MSG:
|
4434 |
|
|
{
|
4435 |
|
|
/*
|
4436 |
|
|
* What we care about here is if we had an outstanding SDTR
|
4437 |
|
|
* or WDTR message for this target. If we did, this is a
|
4438 |
|
|
* signal that the target is refusing negotiation.
|
4439 |
|
|
*/
|
4440 |
|
|
unsigned char scb_index;
|
4441 |
|
|
unsigned char last_msg;
|
4442 |
|
|
|
4443 |
|
|
scb_index = aic_inb(p, SCB_TAG);
|
4444 |
|
|
scb = p->scb_data->scb_array[scb_index];
|
4445 |
|
|
last_msg = aic_inb(p, LAST_MSG);
|
4446 |
|
|
|
4447 |
|
|
if ( (last_msg == MSG_IDENTIFYFLAG) &&
|
4448 |
|
|
(scb->tag_action) &&
|
4449 |
|
|
!(scb->flags & SCB_MSGOUT_BITS) )
|
4450 |
|
|
{
|
4451 |
|
|
if (scb->tag_action == MSG_ORDERED_Q_TAG)
|
4452 |
|
|
{
|
4453 |
|
|
/*
|
4454 |
|
|
* OK...the device seems able to accept tagged commands, but
|
4455 |
|
|
* not ordered tag commands, only simple tag commands. So, we
|
4456 |
|
|
* disable ordered tag commands and go on with life just like
|
4457 |
|
|
* normal.
|
4458 |
|
|
*/
|
4459 |
|
|
p->orderedtag &= ~target_mask;
|
4460 |
|
|
scb->tag_action = MSG_SIMPLE_Q_TAG;
|
4461 |
|
|
scb->hscb->control &= ~SCB_TAG_TYPE;
|
4462 |
|
|
scb->hscb->control |= MSG_SIMPLE_Q_TAG;
|
4463 |
|
|
aic_outb(p, scb->hscb->control, SCB_CONTROL);
|
4464 |
|
|
/*
|
4465 |
|
|
* OK..we set the tag type to simple tag command, now we re-assert
|
4466 |
|
|
* ATNO and hope this will take us into the identify phase again
|
4467 |
|
|
* so we can resend the tag type and info to the device.
|
4468 |
|
|
*/
|
4469 |
|
|
aic_outb(p, MSG_IDENTIFYFLAG, MSG_OUT);
|
4470 |
|
|
aic_outb(p, aic_inb(p, SCSISIGI) | ATNO, SCSISIGO);
|
4471 |
|
|
}
|
4472 |
|
|
else if (scb->tag_action == MSG_SIMPLE_Q_TAG)
|
4473 |
|
|
{
|
4474 |
|
|
unsigned char i, reset = 0;
|
4475 |
|
|
struct aic7xxx_scb *scbp;
|
4476 |
|
|
int old_verbose;
|
4477 |
|
|
/*
|
4478 |
|
|
* Hmmmm....the device is flaking out on tagged commands. The
|
4479 |
|
|
* bad thing is that we already have tagged commands enabled in
|
4480 |
|
|
* the device struct in the mid level code. We also have a queue
|
4481 |
|
|
* set according to the tagged queue depth. Gonna have to live
|
4482 |
|
|
* with it by controlling our queue depth internally and making
|
4483 |
|
|
* sure we don't set the tagged command flag any more.
|
4484 |
|
|
*/
|
4485 |
|
|
p->tagenable &= ~target_mask;
|
4486 |
|
|
p->orderedtag &= ~target_mask;
|
4487 |
|
|
p->dev_max_queue_depth[tindex] =
|
4488 |
|
|
p->dev_temp_queue_depth[tindex] = 1;
|
4489 |
|
|
/*
|
4490 |
|
|
* We set this command up as a bus device reset. However, we have
|
4491 |
|
|
* to clear the tag type as it's causing us problems. We shouldnt
|
4492 |
|
|
* have to worry about any other commands being active, since if
|
4493 |
|
|
* the device is refusing tagged commands, this should be the
|
4494 |
|
|
* first tagged command sent to the device, however, we do have
|
4495 |
|
|
* to worry about any other tagged commands that may already be
|
4496 |
|
|
* in the qinfifo. The easiest way to do this, is to issue a BDR,
|
4497 |
|
|
* send all the commands back to the mid level code, then let them
|
4498 |
|
|
* come back and get rebuilt as untagged commands.
|
4499 |
|
|
*/
|
4500 |
|
|
scb->tag_action = 0;
|
4501 |
|
|
scb->hscb->control &= ~(TAG_ENB | SCB_TAG_TYPE);
|
4502 |
|
|
aic_outb(p, scb->hscb->control, SCB_CONTROL);
|
4503 |
|
|
|
4504 |
|
|
old_verbose = aic7xxx_verbose;
|
4505 |
|
|
aic7xxx_verbose &= ~(VERBOSE_RESET|VERBOSE_ABORT);
|
4506 |
|
|
for (i=0; i!=p->scb_data->numscbs; i++)
|
4507 |
|
|
{
|
4508 |
|
|
scbp = p->scb_data->scb_array[i];
|
4509 |
|
|
if ((scbp->flags & SCB_ACTIVE) && (scbp != scb))
|
4510 |
|
|
{
|
4511 |
|
|
if (aic7xxx_match_scb(p, scbp, target, channel, lun, i))
|
4512 |
|
|
{
|
4513 |
|
|
aic7xxx_reset_device(p, target, channel, lun, i);
|
4514 |
|
|
reset++;
|
4515 |
|
|
}
|
4516 |
|
|
aic7xxx_run_done_queue(p, FALSE);
|
4517 |
|
|
}
|
4518 |
|
|
}
|
4519 |
|
|
aic7xxx_verbose = old_verbose;
|
4520 |
|
|
/*
|
4521 |
|
|
* Wait until after the for loop to set the busy index since
|
4522 |
|
|
* aic7xxx_reset_device will clear the busy index during its
|
4523 |
|
|
* operation.
|
4524 |
|
|
*/
|
4525 |
|
|
aic7xxx_busy_target(p, scb);
|
4526 |
|
|
printk(INFO_LEAD "Device is refusing tagged commands, using "
|
4527 |
|
|
"untagged I/O.\n", p->host_no, channel, target, lun);
|
4528 |
|
|
aic_outb(p, MSG_IDENTIFYFLAG, MSG_OUT);
|
4529 |
|
|
aic_outb(p, aic_inb(p, SCSISIGI) | ATNO, SCSISIGO);
|
4530 |
|
|
}
|
4531 |
|
|
}
|
4532 |
|
|
else if (scb->flags & SCB_MSGOUT_WDTR)
|
4533 |
|
|
{
|
4534 |
|
|
/*
|
4535 |
|
|
* note 8bit xfers and clear flag
|
4536 |
|
|
*/
|
4537 |
|
|
p->needwdtr &= ~target_mask;
|
4538 |
|
|
p->needwdtr_copy &= ~target_mask;
|
4539 |
|
|
p->wdtr_pending &= ~target_mask;
|
4540 |
|
|
scb->flags &= ~SCB_MSGOUT_BITS;
|
4541 |
|
|
aic7xxx_set_width(p, target, channel, lun, MSG_EXT_WDTR_BUS_8_BIT,
|
4542 |
|
|
(AHC_TRANS_ACTIVE|AHC_TRANS_GOAL|AHC_TRANS_CUR));
|
4543 |
|
|
aic7xxx_set_syncrate(p, NULL, target, channel, 0, 0,
|
4544 |
|
|
AHC_TRANS_ACTIVE|AHC_TRANS_CUR|AHC_TRANS_QUITE);
|
4545 |
|
|
if ( (p->needsdtr_copy & target_mask) &&
|
4546 |
|
|
!(p->sdtr_pending & target_mask) )
|
4547 |
|
|
{
|
4548 |
|
|
p->sdtr_pending |= target_mask;
|
4549 |
|
|
scb->flags |= SCB_MSGOUT_SDTR;
|
4550 |
|
|
aic_outb(p, HOST_MSG, MSG_OUT);
|
4551 |
|
|
aic_outb(p, aic_inb(p, SCSISIGO) | ATNO, SCSISIGO);
|
4552 |
|
|
}
|
4553 |
|
|
}
|
4554 |
|
|
else if (scb->flags & SCB_MSGOUT_SDTR)
|
4555 |
|
|
{
|
4556 |
|
|
/*
|
4557 |
|
|
* note asynch xfers and clear flag
|
4558 |
|
|
*/
|
4559 |
|
|
p->needsdtr &= ~target_mask;
|
4560 |
|
|
p->needsdtr_copy &= ~target_mask;
|
4561 |
|
|
p->sdtr_pending &= ~target_mask;
|
4562 |
|
|
scb->flags &= ~SCB_MSGOUT_SDTR;
|
4563 |
|
|
aic7xxx_set_syncrate(p, NULL, target, channel, 0, 0,
|
4564 |
|
|
(AHC_TRANS_CUR|AHC_TRANS_ACTIVE|AHC_TRANS_GOAL));
|
4565 |
|
|
}
|
4566 |
|
|
else if (aic7xxx_verbose & VERBOSE_SEQINT)
|
4567 |
|
|
{
|
4568 |
|
|
/*
|
4569 |
|
|
* Otherwise, we ignore it.
|
4570 |
|
|
*/
|
4571 |
|
|
printk(INFO_LEAD "Received MESSAGE_REJECT for unknown cause. "
|
4572 |
|
|
"Ignoring.\n", p->host_no, channel, target, lun);
|
4573 |
|
|
}
|
4574 |
|
|
}
|
4575 |
|
|
break;
|
4576 |
|
|
|
4577 |
|
|
case BAD_STATUS:
|
4578 |
|
|
{
|
4579 |
|
|
unsigned char scb_index;
|
4580 |
|
|
struct aic7xxx_hwscb *hscb;
|
4581 |
|
|
Scsi_Cmnd *cmd;
|
4582 |
|
|
|
4583 |
|
|
/* The sequencer will notify us when a command has an error that
|
4584 |
|
|
* would be of interest to the kernel. This allows us to leave
|
4585 |
|
|
* the sequencer running in the common case of command completes
|
4586 |
|
|
* without error. The sequencer will have DMA'd the SCB back
|
4587 |
|
|
* up to us, so we can reference the drivers SCB array.
|
4588 |
|
|
*
|
4589 |
|
|
* Set the default return value to 0 indicating not to send
|
4590 |
|
|
* sense. The sense code will change this if needed and this
|
4591 |
|
|
* reduces code duplication.
|
4592 |
|
|
*/
|
4593 |
|
|
aic_outb(p, 0, RETURN_1);
|
4594 |
|
|
scb_index = aic_inb(p, SCB_TAG);
|
4595 |
|
|
if (scb_index > p->scb_data->numscbs)
|
4596 |
|
|
{
|
4597 |
|
|
printk(WARN_LEAD "Invalid SCB during SEQINT 0x%02x, SCB_TAG %d.\n",
|
4598 |
|
|
p->host_no, channel, target, lun, intstat, scb_index);
|
4599 |
|
|
break;
|
4600 |
|
|
}
|
4601 |
|
|
scb = p->scb_data->scb_array[scb_index];
|
4602 |
|
|
hscb = scb->hscb;
|
4603 |
|
|
|
4604 |
|
|
if (!(scb->flags & SCB_ACTIVE) || (scb->cmd == NULL))
|
4605 |
|
|
{
|
4606 |
|
|
printk(WARN_LEAD "Invalid SCB during SEQINT 0x%x, scb %d, flags 0x%x,"
|
4607 |
|
|
" cmd 0x%lx.\n", p->host_no, channel, target, lun, intstat,
|
4608 |
|
|
scb_index, scb->flags, (unsigned long) scb->cmd);
|
4609 |
|
|
}
|
4610 |
|
|
else
|
4611 |
|
|
{
|
4612 |
|
|
cmd = scb->cmd;
|
4613 |
|
|
hscb->target_status = aic_inb(p, SCB_TARGET_STATUS);
|
4614 |
|
|
aic7xxx_status(cmd) = hscb->target_status;
|
4615 |
|
|
|
4616 |
|
|
cmd->result = hscb->target_status;
|
4617 |
|
|
|
4618 |
|
|
switch (status_byte(hscb->target_status))
|
4619 |
|
|
{
|
4620 |
|
|
case GOOD:
|
4621 |
|
|
if (aic7xxx_verbose & VERBOSE_SEQINT)
|
4622 |
|
|
printk(INFO_LEAD "Interrupted for status of GOOD???\n",
|
4623 |
|
|
p->host_no, CTL_OF_SCB(scb));
|
4624 |
|
|
break;
|
4625 |
|
|
|
4626 |
|
|
case COMMAND_TERMINATED:
|
4627 |
|
|
case CHECK_CONDITION:
|
4628 |
|
|
if ( !(scb->flags & SCB_SENSE) )
|
4629 |
|
|
{
|
4630 |
|
|
/*
|
4631 |
|
|
* XXX - How do we save the residual (if there is one).
|
4632 |
|
|
*/
|
4633 |
|
|
if ( hscb->residual_SG_segment_count != 0 )
|
4634 |
|
|
aic7xxx_calculate_residual(p, scb);
|
4635 |
|
|
|
4636 |
|
|
/*
|
4637 |
|
|
* Send a sense command to the requesting target.
|
4638 |
|
|
* XXX - revisit this and get rid of the memcopys.
|
4639 |
|
|
*/
|
4640 |
|
|
memcpy(&scb->sense_cmd[0], &generic_sense[0],
|
4641 |
|
|
sizeof(generic_sense));
|
4642 |
|
|
|
4643 |
|
|
scb->sense_cmd[1] = (cmd->lun << 5);
|
4644 |
|
|
scb->sense_cmd[4] = sizeof(cmd->sense_buffer);
|
4645 |
|
|
|
4646 |
|
|
scb->sg_list[0].address =
|
4647 |
|
|
cpu_to_le32(VIRT_TO_BUS(&cmd->sense_buffer[0]));
|
4648 |
|
|
scb->sg_list[0].length =
|
4649 |
|
|
cpu_to_le32(sizeof(cmd->sense_buffer));
|
4650 |
|
|
|
4651 |
|
|
/*
|
4652 |
|
|
* XXX - We should allow disconnection, but can't as it
|
4653 |
|
|
* might allow overlapped tagged commands.
|
4654 |
|
|
*/
|
4655 |
|
|
/* hscb->control &= DISCENB; */
|
4656 |
|
|
hscb->control = 0;
|
4657 |
|
|
hscb->target_status = 0;
|
4658 |
|
|
hscb->SG_list_pointer =
|
4659 |
|
|
cpu_to_le32(VIRT_TO_BUS(&scb->sg_list[0]));
|
4660 |
|
|
hscb->data_pointer = scb->sg_list[0].address;
|
4661 |
|
|
hscb->data_count = scb->sg_list[0].length;
|
4662 |
|
|
hscb->SCSI_cmd_pointer =
|
4663 |
|
|
cpu_to_le32(VIRT_TO_BUS(&scb->sense_cmd[0]));
|
4664 |
|
|
hscb->SCSI_cmd_length = COMMAND_SIZE(scb->sense_cmd[0]);
|
4665 |
|
|
hscb->residual_SG_segment_count = 0;
|
4666 |
|
|
hscb->residual_data_count[0] = 0;
|
4667 |
|
|
hscb->residual_data_count[1] = 0;
|
4668 |
|
|
hscb->residual_data_count[2] = 0;
|
4669 |
|
|
|
4670 |
|
|
scb->sg_count = hscb->SG_segment_count = 1;
|
4671 |
|
|
scb->sg_length = sizeof(cmd->sense_buffer);
|
4672 |
|
|
scb->tag_action = 0;
|
4673 |
|
|
/*
|
4674 |
|
|
* This problem could be caused if the target has lost power
|
4675 |
|
|
* or found some other way to loose the negotiation settings,
|
4676 |
|
|
* so if needed, we'll re-negotiate while doing the sense cmd.
|
4677 |
|
|
* However, if this SCB already was attempting to negotiate,
|
4678 |
|
|
* then we assume this isn't the problem and skip this part.
|
4679 |
|
|
*/
|
4680 |
|
|
#ifdef AIC7XXX_FAKE_NEGOTIATION_CMDS
|
4681 |
|
|
if ( (scb->cmd->cmnd[0] != TEST_UNIT_READY) &&
|
4682 |
|
|
(p->dev_flags[tindex] & DEVICE_SCANNED) &&
|
4683 |
|
|
!(p->wdtr_pending & target_mask) &&
|
4684 |
|
|
!(p->sdtr_pending & target_mask) )
|
4685 |
|
|
{
|
4686 |
|
|
p->needwdtr |= (p->needwdtr_copy & target_mask);
|
4687 |
|
|
p->needsdtr |= (p->needsdtr_copy & target_mask);
|
4688 |
|
|
}
|
4689 |
|
|
else if ( (scb->cmd == p->dev_wdtr_cmnd[tindex]) ||
|
4690 |
|
|
(scb->cmd == p->dev_sdtr_cmnd[tindex]) )
|
4691 |
|
|
{
|
4692 |
|
|
/*
|
4693 |
|
|
* This is already a negotiation command, so we must have
|
4694 |
|
|
* already done either WDTR or SDTR (or maybe both). So
|
4695 |
|
|
* we simply check sdtr_pending and needsdtr to see if we
|
4696 |
|
|
* should throw out SDTR on this command.
|
4697 |
|
|
*
|
4698 |
|
|
* Note: Don't check the needsdtr_copy here, instead just
|
4699 |
|
|
* check to see if WDTR wiped out our SDTR and set needsdtr.
|
4700 |
|
|
* Even if WDTR did wipe out SDTR and set needsdtr, if
|
4701 |
|
|
* parse_msg() then turned around and started our SDTR
|
4702 |
|
|
* in back to back fasion, then conclusion of that should
|
4703 |
|
|
* have negated any needsdtr setting. That's why we only
|
4704 |
|
|
* check needsdtr and sdtr_pending.
|
4705 |
|
|
*/
|
4706 |
|
|
scb->flags &= ~SCB_MSGOUT_BITS;
|
4707 |
|
|
if ( (scb->cmd == p->dev_wdtr_cmnd[tindex]) &&
|
4708 |
|
|
!(p->sdtr_pending & target_mask) &&
|
4709 |
|
|
(p->needsdtr & target_mask) )
|
4710 |
|
|
{
|
4711 |
|
|
p->sdtr_pending |= target_mask;
|
4712 |
|
|
hscb->control |= MK_MESSAGE;
|
4713 |
|
|
scb->flags |= SCB_MSGOUT_SDTR;
|
4714 |
|
|
}
|
4715 |
|
|
|
4716 |
|
|
/*
|
4717 |
|
|
* This is the important part though. We are getting sense
|
4718 |
|
|
* info back from this device. It's going into a fake
|
4719 |
|
|
* command. We need to put that into the real command
|
4720 |
|
|
* instead so that the mid level SCSI code can act upon it.
|
4721 |
|
|
* So, when we set up these fake commands, the next pointer
|
4722 |
|
|
* is used to point to the real command. Use that to change
|
4723 |
|
|
* the address of our sense_buffer[] to the real command.
|
4724 |
|
|
* However, don't do this if the real command is also a
|
4725 |
|
|
* TEST_UNIT_READY as it will most likely pull down its own
|
4726 |
|
|
* SENSE information anyway.
|
4727 |
|
|
*/
|
4728 |
|
|
if (cmd->next->cmnd[0] != TEST_UNIT_READY)
|
4729 |
|
|
{
|
4730 |
|
|
scb->sg_list[0].address =
|
4731 |
|
|
cpu_to_le32(VIRT_TO_BUS(&cmd->next->sense_buffer[0]));
|
4732 |
|
|
hscb->data_pointer = scb->sg_list[0].address;
|
4733 |
|
|
}
|
4734 |
|
|
}
|
4735 |
|
|
#else
|
4736 |
|
|
if ( (scb->cmd->cmnd[0] != TEST_UNIT_READY) &&
|
4737 |
|
|
!(scb->flags & SCB_MSGOUT_BITS) &&
|
4738 |
|
|
(scb->cmd->lun == 0) &&
|
4739 |
|
|
(p->dev_flags[TARGET_INDEX(scb->cmd)] & DEVICE_SCANNED) )
|
4740 |
|
|
{
|
4741 |
|
|
if ( (p->needwdtr_copy & target_mask) &&
|
4742 |
|
|
!(p->wdtr_pending & target_mask) &&
|
4743 |
|
|
!(p->sdtr_pending & target_mask) )
|
4744 |
|
|
{
|
4745 |
|
|
p->needwdtr |= target_mask;
|
4746 |
|
|
p->wdtr_pending |= target_mask;
|
4747 |
|
|
hscb->control |= MK_MESSAGE;
|
4748 |
|
|
scb->flags |= SCB_MSGOUT_WDTR;
|
4749 |
|
|
}
|
4750 |
|
|
if ( p->needsdtr_copy & target_mask )
|
4751 |
|
|
{
|
4752 |
|
|
p->needsdtr |= target_mask;
|
4753 |
|
|
if ( !(p->wdtr_pending & target_mask) &&
|
4754 |
|
|
!(p->sdtr_pending & target_mask) )
|
4755 |
|
|
{
|
4756 |
|
|
p->sdtr_pending |= target_mask;
|
4757 |
|
|
hscb->control |= MK_MESSAGE;
|
4758 |
|
|
scb->flags |= SCB_MSGOUT_SDTR;
|
4759 |
|
|
}
|
4760 |
|
|
}
|
4761 |
|
|
}
|
4762 |
|
|
else
|
4763 |
|
|
scb->flags &= ~SCB_MSGOUT_BITS;
|
4764 |
|
|
#endif /* AIC7XXX_FAKE_NEGOTIATION_CMDS */
|
4765 |
|
|
scb->flags |= SCB_SENSE;
|
4766 |
|
|
/*
|
4767 |
|
|
* Ensure the target is busy since this will be an
|
4768 |
|
|
* an untagged request.
|
4769 |
|
|
*/
|
4770 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
4771 |
|
|
if (aic7xxx_verbose > 0xffff)
|
4772 |
|
|
{
|
4773 |
|
|
if (scb->flags & SCB_MSGOUT_BITS)
|
4774 |
|
|
printk(INFO_LEAD "Requesting SENSE with %s\n", p->host_no,
|
4775 |
|
|
CTL_OF_SCB(scb), (scb->flags & SCB_MSGOUT_SDTR) ?
|
4776 |
|
|
"SDTR" : "WDTR");
|
4777 |
|
|
else
|
4778 |
|
|
printk(INFO_LEAD "Requesting SENSE, no MSG\n", p->host_no,
|
4779 |
|
|
CTL_OF_SCB(scb));
|
4780 |
|
|
}
|
4781 |
|
|
#endif
|
4782 |
|
|
aic7xxx_busy_target(p, scb);
|
4783 |
|
|
aic_outb(p, SEND_SENSE, RETURN_1);
|
4784 |
|
|
aic7xxx_error(cmd) = DID_OK;
|
4785 |
|
|
break;
|
4786 |
|
|
} /* first time sense, no errors */
|
4787 |
|
|
aic7xxx_error(cmd) = DID_OK;
|
4788 |
|
|
scb->flags &= ~SCB_SENSE;
|
4789 |
|
|
break;
|
4790 |
|
|
|
4791 |
|
|
case QUEUE_FULL:
|
4792 |
|
|
queue_flag = TRUE; /* Mark that this is a QUEUE_FULL and */
|
4793 |
|
|
case BUSY: /* drop through to here */
|
4794 |
|
|
{
|
4795 |
|
|
struct aic7xxx_scb *next_scbp, *prev_scbp;
|
4796 |
|
|
unsigned char active_hscb, next_hscb, prev_hscb, scb_index;
|
4797 |
|
|
/*
|
4798 |
|
|
* We have to look three places for queued commands:
|
4799 |
|
|
* 1: QINFIFO
|
4800 |
|
|
* 2: p->waiting_scbs queue
|
4801 |
|
|
* 3: WAITING_SCBS list on card (for commands that are started
|
4802 |
|
|
* but haven't yet made it to the device)
|
4803 |
|
|
*/
|
4804 |
|
|
aic7xxx_search_qinfifo(p, target, channel, lun,
|
4805 |
|
|
SCB_LIST_NULL, 0, TRUE,
|
4806 |
|
|
&p->delayed_scbs[tindex]);
|
4807 |
|
|
next_scbp = p->waiting_scbs.head;
|
4808 |
|
|
while ( next_scbp != NULL )
|
4809 |
|
|
{
|
4810 |
|
|
prev_scbp = next_scbp;
|
4811 |
|
|
next_scbp = next_scbp->q_next;
|
4812 |
|
|
if ( aic7xxx_match_scb(p, prev_scbp, target, channel, lun,
|
4813 |
|
|
SCB_LIST_NULL) )
|
4814 |
|
|
{
|
4815 |
|
|
scbq_remove(&p->waiting_scbs, prev_scbp);
|
4816 |
|
|
scbq_insert_tail(&p->delayed_scbs[tindex],
|
4817 |
|
|
prev_scbp);
|
4818 |
|
|
}
|
4819 |
|
|
}
|
4820 |
|
|
next_scbp = NULL;
|
4821 |
|
|
active_hscb = aic_inb(p, SCBPTR);
|
4822 |
|
|
prev_hscb = next_hscb = scb_index = SCB_LIST_NULL;
|
4823 |
|
|
next_hscb = aic_inb(p, WAITING_SCBH);
|
4824 |
|
|
while (next_hscb != SCB_LIST_NULL)
|
4825 |
|
|
{
|
4826 |
|
|
aic_outb(p, next_hscb, SCBPTR);
|
4827 |
|
|
scb_index = aic_inb(p, SCB_TAG);
|
4828 |
|
|
if (scb_index < p->scb_data->numscbs)
|
4829 |
|
|
{
|
4830 |
|
|
next_scbp = p->scb_data->scb_array[scb_index];
|
4831 |
|
|
if (aic7xxx_match_scb(p, next_scbp, target, channel, lun,
|
4832 |
|
|
SCB_LIST_NULL) )
|
4833 |
|
|
{
|
4834 |
|
|
if (next_scbp->flags & SCB_WAITINGQ)
|
4835 |
|
|
{
|
4836 |
|
|
p->dev_active_cmds[tindex]++;
|
4837 |
|
|
p->activescbs--;
|
4838 |
|
|
scbq_remove(&p->delayed_scbs[tindex], next_scbp);
|
4839 |
|
|
scbq_remove(&p->waiting_scbs, next_scbp);
|
4840 |
|
|
}
|
4841 |
|
|
scbq_insert_head(&p->delayed_scbs[tindex],
|
4842 |
|
|
next_scbp);
|
4843 |
|
|
next_scbp->flags |= SCB_WAITINGQ;
|
4844 |
|
|
p->dev_active_cmds[tindex]--;
|
4845 |
|
|
p->activescbs--;
|
4846 |
|
|
next_hscb = aic_inb(p, SCB_NEXT);
|
4847 |
|
|
aic_outb(p, 0, SCB_CONTROL);
|
4848 |
|
|
aic_outb(p, SCB_LIST_NULL, SCB_TAG);
|
4849 |
|
|
aic7xxx_add_curscb_to_free_list(p);
|
4850 |
|
|
if (prev_hscb == SCB_LIST_NULL)
|
4851 |
|
|
{
|
4852 |
|
|
/* We were first on the list,
|
4853 |
|
|
* so we kill the selection
|
4854 |
|
|
* hardware. Let the sequencer
|
4855 |
|
|
* re-init the hardware itself
|
4856 |
|
|
*/
|
4857 |
|
|
aic_outb(p, aic_inb(p, SCSISEQ) & ~ENSELO, SCSISEQ);
|
4858 |
|
|
aic_outb(p, CLRSELTIMEO, CLRSINT1);
|
4859 |
|
|
aic_outb(p, next_hscb, WAITING_SCBH);
|
4860 |
|
|
}
|
4861 |
|
|
else
|
4862 |
|
|
{
|
4863 |
|
|
aic_outb(p, prev_hscb, SCBPTR);
|
4864 |
|
|
aic_outb(p, next_hscb, SCB_NEXT);
|
4865 |
|
|
}
|
4866 |
|
|
}
|
4867 |
|
|
else
|
4868 |
|
|
{
|
4869 |
|
|
prev_hscb = next_hscb;
|
4870 |
|
|
next_hscb = aic_inb(p, SCB_NEXT);
|
4871 |
|
|
}
|
4872 |
|
|
} /* scb_index >= p->scb_data->numscbs */
|
4873 |
|
|
}
|
4874 |
|
|
aic_outb(p, active_hscb, SCBPTR);
|
4875 |
|
|
if (scb->flags & SCB_WAITINGQ)
|
4876 |
|
|
{
|
4877 |
|
|
scbq_remove(&p->delayed_scbs[tindex], scb);
|
4878 |
|
|
scbq_remove(&p->waiting_scbs, scb);
|
4879 |
|
|
p->dev_active_cmds[tindex]++;
|
4880 |
|
|
p->activescbs++;
|
4881 |
|
|
}
|
4882 |
|
|
scbq_insert_head(&p->delayed_scbs[tindex], scb);
|
4883 |
|
|
p->dev_active_cmds[tindex]--;
|
4884 |
|
|
p->activescbs--;
|
4885 |
|
|
scb->flags |= SCB_WAITINGQ | SCB_WAS_BUSY;
|
4886 |
|
|
|
4887 |
|
|
if ( !(p->dev_timer_active & (0x01 << tindex)) )
|
4888 |
|
|
{
|
4889 |
|
|
p->dev_timer_active |= (0x01 << tindex);
|
4890 |
|
|
if ( p->dev_active_cmds[tindex] )
|
4891 |
|
|
{
|
4892 |
|
|
p->dev_expires[tindex] = jiffies + HZ;
|
4893 |
|
|
}
|
4894 |
|
|
else
|
4895 |
|
|
{
|
4896 |
|
|
p->dev_expires[tindex] = jiffies + (HZ / 10);
|
4897 |
|
|
}
|
4898 |
|
|
if ( !(p->dev_timer_active & (0x01 << MAX_TARGETS)) )
|
4899 |
|
|
{
|
4900 |
|
|
p->dev_timer.expires = p->dev_expires[tindex];
|
4901 |
|
|
p->dev_timer_active |= (0x01 << MAX_TARGETS);
|
4902 |
|
|
add_timer(&p->dev_timer);
|
4903 |
|
|
}
|
4904 |
|
|
else if ( time_after_eq(p->dev_timer.expires,
|
4905 |
|
|
p->dev_expires[tindex]) )
|
4906 |
|
|
{
|
4907 |
|
|
del_timer(&p->dev_timer);
|
4908 |
|
|
p->dev_timer.expires = p->dev_expires[tindex];
|
4909 |
|
|
add_timer(&p->dev_timer);
|
4910 |
|
|
}
|
4911 |
|
|
}
|
4912 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
4913 |
|
|
if (aic7xxx_verbose & VERBOSE_MINOR_ERROR)
|
4914 |
|
|
{
|
4915 |
|
|
if (queue_flag)
|
4916 |
|
|
printk(INFO_LEAD "Queue full received; queue depth %d, "
|
4917 |
|
|
"active %d\n", p->host_no, CTL_OF_SCB(scb),
|
4918 |
|
|
p->dev_max_queue_depth[tindex],
|
4919 |
|
|
p->dev_active_cmds[tindex]);
|
4920 |
|
|
else
|
4921 |
|
|
printk(INFO_LEAD "Target busy\n", p->host_no, CTL_OF_SCB(scb));
|
4922 |
|
|
|
4923 |
|
|
}
|
4924 |
|
|
#endif
|
4925 |
|
|
if (queue_flag)
|
4926 |
|
|
{
|
4927 |
|
|
p->dev_temp_queue_depth[tindex] =
|
4928 |
|
|
p->dev_active_cmds[tindex];
|
4929 |
|
|
if ( p->dev_last_queue_full[tindex] !=
|
4930 |
|
|
p->dev_active_cmds[tindex] )
|
4931 |
|
|
{
|
4932 |
|
|
p->dev_last_queue_full[tindex] =
|
4933 |
|
|
p->dev_active_cmds[tindex];
|
4934 |
|
|
p->dev_last_queue_full_count[tindex] = 0;
|
4935 |
|
|
}
|
4936 |
|
|
else
|
4937 |
|
|
{
|
4938 |
|
|
p->dev_last_queue_full_count[tindex]++;
|
4939 |
|
|
}
|
4940 |
|
|
if ( (p->dev_last_queue_full_count[tindex] > 14) &&
|
4941 |
|
|
(p->dev_active_cmds[tindex] > 4) )
|
4942 |
|
|
{
|
4943 |
|
|
if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
|
4944 |
|
|
printk(INFO_LEAD "Queue depth reduced to %d\n", p->host_no,
|
4945 |
|
|
CTL_OF_SCB(scb), p->dev_active_cmds[tindex]);
|
4946 |
|
|
p->dev_max_queue_depth[tindex] =
|
4947 |
|
|
p->dev_active_cmds[tindex];
|
4948 |
|
|
p->dev_last_queue_full[tindex] = 0;
|
4949 |
|
|
p->dev_last_queue_full_count[tindex] = 0;
|
4950 |
|
|
}
|
4951 |
|
|
else
|
4952 |
|
|
{
|
4953 |
|
|
p->dev_flags[tindex] |= DEVICE_WAS_BUSY;
|
4954 |
|
|
}
|
4955 |
|
|
}
|
4956 |
|
|
break;
|
4957 |
|
|
}
|
4958 |
|
|
|
4959 |
|
|
default:
|
4960 |
|
|
if (aic7xxx_verbose & VERBOSE_SEQINT)
|
4961 |
|
|
printk(INFO_LEAD "Unexpected target status 0x%x.\n", p->host_no,
|
4962 |
|
|
CTL_OF_SCB(scb), scb->hscb->target_status);
|
4963 |
|
|
if (!aic7xxx_error(cmd))
|
4964 |
|
|
{
|
4965 |
|
|
aic7xxx_error(cmd) = DID_RETRY_COMMAND;
|
4966 |
|
|
}
|
4967 |
|
|
break;
|
4968 |
|
|
} /* end switch */
|
4969 |
|
|
} /* end else of */
|
4970 |
|
|
}
|
4971 |
|
|
break;
|
4972 |
|
|
|
4973 |
|
|
case AWAITING_MSG:
|
4974 |
|
|
{
|
4975 |
|
|
unsigned char scb_index, msg_out;
|
4976 |
|
|
|
4977 |
|
|
scb_index = aic_inb(p, SCB_TAG);
|
4978 |
|
|
msg_out = aic_inb(p, MSG_OUT);
|
4979 |
|
|
scb = p->scb_data->scb_array[scb_index];
|
4980 |
|
|
p->msg_index = p->msg_len = 0;
|
4981 |
|
|
/*
|
4982 |
|
|
* This SCB had a MK_MESSAGE set in its control byte informing
|
4983 |
|
|
* the sequencer that we wanted to send a special message to
|
4984 |
|
|
* this target.
|
4985 |
|
|
*/
|
4986 |
|
|
|
4987 |
|
|
if ( !(scb->flags & SCB_DEVICE_RESET) &&
|
4988 |
|
|
(aic_inb(p, MSG_OUT) == MSG_IDENTIFYFLAG) &&
|
4989 |
|
|
(scb->hscb->control & TAG_ENB) )
|
4990 |
|
|
{
|
4991 |
|
|
p->msg_buf[p->msg_index++] = scb->tag_action;
|
4992 |
|
|
p->msg_buf[p->msg_index++] = scb->hscb->tag;
|
4993 |
|
|
p->msg_len += 2;
|
4994 |
|
|
}
|
4995 |
|
|
|
4996 |
|
|
if (scb->flags & SCB_DEVICE_RESET)
|
4997 |
|
|
{
|
4998 |
|
|
p->msg_buf[p->msg_index++] = MSG_BUS_DEV_RESET;
|
4999 |
|
|
p->msg_len++;
|
5000 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
|
5001 |
|
|
printk(INFO_LEAD "Bus device reset mailed.\n",
|
5002 |
|
|
p->host_no, CTL_OF_SCB(scb));
|
5003 |
|
|
}
|
5004 |
|
|
else if (scb->flags & SCB_ABORT)
|
5005 |
|
|
{
|
5006 |
|
|
if (scb->tag_action)
|
5007 |
|
|
{
|
5008 |
|
|
p->msg_buf[p->msg_index++] = MSG_ABORT_TAG;
|
5009 |
|
|
}
|
5010 |
|
|
else
|
5011 |
|
|
{
|
5012 |
|
|
p->msg_buf[p->msg_index++] = MSG_ABORT;
|
5013 |
|
|
}
|
5014 |
|
|
p->msg_len++;
|
5015 |
|
|
if (aic7xxx_verbose & VERBOSE_ABORT_PROCESS)
|
5016 |
|
|
printk(INFO_LEAD "Abort message mailed.\n", p->host_no,
|
5017 |
|
|
CTL_OF_SCB(scb));
|
5018 |
|
|
}
|
5019 |
|
|
else if (scb->flags & SCB_MSGOUT_WDTR)
|
5020 |
|
|
{
|
5021 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
5022 |
|
|
if (aic7xxx_verbose > 0xffff)
|
5023 |
|
|
printk(INFO_LEAD "Sending WDTR message.\n", p->host_no,
|
5024 |
|
|
CTL_OF_SCB(scb));
|
5025 |
|
|
#endif
|
5026 |
|
|
aic7xxx_construct_wdtr(p,
|
5027 |
|
|
p->transinfo[TARGET_INDEX(scb->cmd)].goal_width);
|
5028 |
|
|
}
|
5029 |
|
|
else if (scb->flags & SCB_MSGOUT_SDTR)
|
5030 |
|
|
{
|
5031 |
|
|
unsigned int max_sync, period;
|
5032 |
|
|
/*
|
5033 |
|
|
* We need to set an accurate goal_offset instead of
|
5034 |
|
|
* the ridiculously high one we default to. We should
|
5035 |
|
|
* now know if we are wide. Plus, the WDTR code will
|
5036 |
|
|
* set our goal_offset for us as well.
|
5037 |
|
|
*/
|
5038 |
|
|
if (p->transinfo[tindex].goal_offset)
|
5039 |
|
|
{
|
5040 |
|
|
if (p->features & AHC_ULTRA2)
|
5041 |
|
|
p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2;
|
5042 |
|
|
else if (p->transinfo[tindex].cur_width == MSG_EXT_WDTR_BUS_16_BIT)
|
5043 |
|
|
p->transinfo[tindex].goal_offset = MAX_OFFSET_16BIT;
|
5044 |
|
|
else
|
5045 |
|
|
p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT;
|
5046 |
|
|
}
|
5047 |
|
|
/*
|
5048 |
|
|
* Now that the device is selected, use the bits in SBLKCTL and
|
5049 |
|
|
* SSTAT2 to determine the max sync rate for this device.
|
5050 |
|
|
*/
|
5051 |
|
|
if (p->features & AHC_ULTRA2)
|
5052 |
|
|
{
|
5053 |
|
|
if ( (aic_inb(p, SBLKCTL) & ENAB40) &&
|
5054 |
|
|
!(aic_inb(p, SSTAT2) & EXP_ACTIVE) )
|
5055 |
|
|
{
|
5056 |
|
|
max_sync = AHC_SYNCRATE_ULTRA2;
|
5057 |
|
|
}
|
5058 |
|
|
else
|
5059 |
|
|
{
|
5060 |
|
|
max_sync = AHC_SYNCRATE_ULTRA;
|
5061 |
|
|
}
|
5062 |
|
|
}
|
5063 |
|
|
else if (p->features & AHC_ULTRA)
|
5064 |
|
|
{
|
5065 |
|
|
max_sync = AHC_SYNCRATE_ULTRA;
|
5066 |
|
|
}
|
5067 |
|
|
else
|
5068 |
|
|
{
|
5069 |
|
|
max_sync = AHC_SYNCRATE_FAST;
|
5070 |
|
|
}
|
5071 |
|
|
period = p->transinfo[tindex].goal_period;
|
5072 |
|
|
aic7xxx_find_syncrate(p, &period, max_sync);
|
5073 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
5074 |
|
|
if (aic7xxx_verbose > 0xffff)
|
5075 |
|
|
printk(INFO_LEAD "Sending SDTR %d/%d message.\n", p->host_no,
|
5076 |
|
|
CTL_OF_SCB(scb),
|
5077 |
|
|
p->transinfo[tindex].goal_period,
|
5078 |
|
|
p->transinfo[tindex].goal_offset);
|
5079 |
|
|
#endif
|
5080 |
|
|
aic7xxx_construct_sdtr(p, period,
|
5081 |
|
|
p->transinfo[tindex].goal_offset);
|
5082 |
|
|
}
|
5083 |
|
|
else
|
5084 |
|
|
{
|
5085 |
|
|
sti();
|
5086 |
|
|
panic("aic7xxx: AWAITING_MSG for an SCB that does "
|
5087 |
|
|
"not have a waiting message.\n");
|
5088 |
|
|
}
|
5089 |
|
|
/*
|
5090 |
|
|
* We've set everything up to send our message, now to actually do
|
5091 |
|
|
* so we need to enable reqinit interrupts and let the interrupt
|
5092 |
|
|
* handler do the rest. We don't want to unpause the sequencer yet
|
5093 |
|
|
* though so we'll return early. We also have to make sure that
|
5094 |
|
|
* we clear the SEQINT *BEFORE* we set the REQINIT handler active
|
5095 |
|
|
* or else it's possible on VLB cards to loose the first REQINIT
|
5096 |
|
|
* interrupt. Edge triggered EISA cards could also loose this
|
5097 |
|
|
* interrupt, although PCI and level triggered cards should not
|
5098 |
|
|
* have this problem since they continually interrupt the kernel
|
5099 |
|
|
* until we take care of the situation.
|
5100 |
|
|
*/
|
5101 |
|
|
scb->flags |= SCB_MSGOUT_SENT;
|
5102 |
|
|
p->msg_index = 0;
|
5103 |
|
|
p->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
5104 |
|
|
p->flags |= AHC_HANDLING_REQINITS;
|
5105 |
|
|
aic_outb(p, aic_inb(p, SIMODE1) | ENREQINIT, SIMODE1);
|
5106 |
|
|
return;
|
5107 |
|
|
}
|
5108 |
|
|
break;
|
5109 |
|
|
|
5110 |
|
|
case DATA_OVERRUN:
|
5111 |
|
|
{
|
5112 |
|
|
unsigned char scb_index = aic_inb(p, SCB_TAG);
|
5113 |
|
|
unsigned char lastphase = aic_inb(p, LASTPHASE);
|
5114 |
|
|
unsigned int i;
|
5115 |
|
|
|
5116 |
|
|
scb = (p->scb_data->scb_array[scb_index]);
|
5117 |
|
|
/*
|
5118 |
|
|
* XXX - What do we really want to do on an overrun? The
|
5119 |
|
|
* mid-level SCSI code should handle this, but for now,
|
5120 |
|
|
* we'll just indicate that the command should retried.
|
5121 |
|
|
* If we retrieved sense info on this target, then the
|
5122 |
|
|
* base SENSE info should have been saved prior to the
|
5123 |
|
|
* overrun error. In that case, we return DID_OK and let
|
5124 |
|
|
* the mid level code pick up on the sense info. Otherwise
|
5125 |
|
|
* we return DID_ERROR so the command will get retried.
|
5126 |
|
|
*/
|
5127 |
|
|
if ( !(scb->flags & SCB_SENSE) )
|
5128 |
|
|
{
|
5129 |
|
|
printk(WARN_LEAD "Data overrun detected in %s phase, tag %d;\n",
|
5130 |
|
|
p->host_no, CTL_OF_SCB(scb),
|
5131 |
|
|
(lastphase == P_DATAIN) ? "Data-In" : "Data-Out", scb->hscb->tag);
|
5132 |
|
|
printk(KERN_WARNING " %s seen Data Phase. Length=%d, NumSGs=%d.\n",
|
5133 |
|
|
(aic_inb(p, SEQ_FLAGS) & DPHASE) ? "Have" : "Haven't",
|
5134 |
|
|
scb->sg_length, scb->sg_count);
|
5135 |
|
|
for (i = 0; i < scb->sg_count; i++)
|
5136 |
|
|
{
|
5137 |
|
|
printk(KERN_WARNING " sg[%d] - Addr 0x%x : Length %d\n",
|
5138 |
|
|
i,
|
5139 |
|
|
le32_to_cpu(scb->sg_list[i].address),
|
5140 |
|
|
le32_to_cpu(scb->sg_list[i].length) );
|
5141 |
|
|
}
|
5142 |
|
|
aic7xxx_error(scb->cmd) = DID_ERROR;
|
5143 |
|
|
}
|
5144 |
|
|
else
|
5145 |
|
|
printk(INFO_LEAD "Data Overrun during SEND_SENSE operation.\n",
|
5146 |
|
|
p->host_no, CTL_OF_SCB(scb));
|
5147 |
|
|
}
|
5148 |
|
|
break;
|
5149 |
|
|
|
5150 |
|
|
#if AIC7XXX_NOT_YET
|
5151 |
|
|
case TRACEPOINT:
|
5152 |
|
|
{
|
5153 |
|
|
printk(INFO_LEAD "Tracepoint #1 reached.\n", p->host_no, channel,
|
5154 |
|
|
target, lun);
|
5155 |
|
|
}
|
5156 |
|
|
break;
|
5157 |
|
|
|
5158 |
|
|
case TRACEPOINT2:
|
5159 |
|
|
{
|
5160 |
|
|
printk(INFO_LEAD "Tracepoint #2 reached.\n", p->host_no, channel,
|
5161 |
|
|
target, lun);
|
5162 |
|
|
}
|
5163 |
|
|
break;
|
5164 |
|
|
|
5165 |
|
|
/* XXX Fill these in later */
|
5166 |
|
|
case MSG_BUFFER_BUSY:
|
5167 |
|
|
printk("aic7xxx: Message buffer busy.\n");
|
5168 |
|
|
break;
|
5169 |
|
|
case MSGIN_PHASEMIS:
|
5170 |
|
|
printk("aic7xxx: Message-in phasemis.\n");
|
5171 |
|
|
break;
|
5172 |
|
|
#endif
|
5173 |
|
|
|
5174 |
|
|
default: /* unknown */
|
5175 |
|
|
printk(WARN_LEAD "Unknown SEQINT, INTSTAT 0x%x, SCSISIGI 0x%x.\n",
|
5176 |
|
|
p->host_no, channel, target, lun, intstat,
|
5177 |
|
|
aic_inb(p, SCSISIGI));
|
5178 |
|
|
break;
|
5179 |
|
|
}
|
5180 |
|
|
|
5181 |
|
|
/*
|
5182 |
|
|
* Clear the sequencer interrupt and unpause the sequencer.
|
5183 |
|
|
*/
|
5184 |
|
|
unpause_sequencer(p, /* unpause always */ TRUE);
|
5185 |
|
|
}
|
5186 |
|
|
|
5187 |
|
|
/*+F*************************************************************************
|
5188 |
|
|
* Function:
|
5189 |
|
|
* aic7xxx_parse_msg
|
5190 |
|
|
*
|
5191 |
|
|
* Description:
|
5192 |
|
|
* Parses incoming messages into actions on behalf of
|
5193 |
|
|
* aic7xxx_handle_reqinit
|
5194 |
|
|
*_F*************************************************************************/
|
5195 |
|
|
static int
|
5196 |
|
|
aic7xxx_parse_msg(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
|
5197 |
|
|
{
|
5198 |
|
|
int reject, reply, done;
|
5199 |
|
|
unsigned char target_scsirate, tindex;
|
5200 |
|
|
unsigned short target_mask;
|
5201 |
|
|
unsigned char target, channel, lun;
|
5202 |
|
|
|
5203 |
|
|
target = scb->cmd->target;
|
5204 |
|
|
channel = scb->cmd->channel;
|
5205 |
|
|
lun = scb->cmd->lun;
|
5206 |
|
|
reply = reject = done = FALSE;
|
5207 |
|
|
tindex = TARGET_INDEX(scb->cmd);
|
5208 |
|
|
target_scsirate = aic_inb(p, TARG_SCSIRATE + tindex);
|
5209 |
|
|
target_mask = (0x01 << tindex);
|
5210 |
|
|
|
5211 |
|
|
/*
|
5212 |
|
|
* Parse as much of the message as is availible,
|
5213 |
|
|
* rejecting it if we don't support it. When
|
5214 |
|
|
* the entire message is availible and has been
|
5215 |
|
|
* handled, return TRUE indicating that we have
|
5216 |
|
|
* parsed an entire message.
|
5217 |
|
|
*/
|
5218 |
|
|
|
5219 |
|
|
if (p->msg_buf[0] != MSG_EXTENDED)
|
5220 |
|
|
{
|
5221 |
|
|
reject = TRUE;
|
5222 |
|
|
}
|
5223 |
|
|
|
5224 |
|
|
/*
|
5225 |
|
|
* Just accept the length byte outright and perform
|
5226 |
|
|
* more checking once we know the message type.
|
5227 |
|
|
*/
|
5228 |
|
|
|
5229 |
|
|
if ( !reject && (p->msg_len > 2) )
|
5230 |
|
|
{
|
5231 |
|
|
switch(p->msg_buf[2])
|
5232 |
|
|
{
|
5233 |
|
|
case MSG_EXT_SDTR:
|
5234 |
|
|
{
|
5235 |
|
|
unsigned int period, offset;
|
5236 |
|
|
unsigned char maxsync, saved_offset;
|
5237 |
|
|
struct aic7xxx_syncrate *syncrate;
|
5238 |
|
|
|
5239 |
|
|
if (p->msg_buf[1] != MSG_EXT_SDTR_LEN)
|
5240 |
|
|
{
|
5241 |
|
|
reject = TRUE;
|
5242 |
|
|
break;
|
5243 |
|
|
}
|
5244 |
|
|
|
5245 |
|
|
if (p->msg_len < (MSG_EXT_SDTR_LEN + 2))
|
5246 |
|
|
{
|
5247 |
|
|
break;
|
5248 |
|
|
}
|
5249 |
|
|
|
5250 |
|
|
period = p->msg_buf[3];
|
5251 |
|
|
saved_offset = offset = p->msg_buf[4];
|
5252 |
|
|
|
5253 |
|
|
if (p->features & AHC_ULTRA2)
|
5254 |
|
|
{
|
5255 |
|
|
if ( (aic_inb(p, SBLKCTL) & ENAB40) &&
|
5256 |
|
|
!(aic_inb(p, SSTAT2) & EXP_ACTIVE) )
|
5257 |
|
|
{
|
5258 |
|
|
maxsync = AHC_SYNCRATE_ULTRA2;
|
5259 |
|
|
}
|
5260 |
|
|
else
|
5261 |
|
|
{
|
5262 |
|
|
maxsync = AHC_SYNCRATE_ULTRA;
|
5263 |
|
|
}
|
5264 |
|
|
}
|
5265 |
|
|
else if (p->features & AHC_ULTRA)
|
5266 |
|
|
{
|
5267 |
|
|
maxsync = AHC_SYNCRATE_ULTRA;
|
5268 |
|
|
}
|
5269 |
|
|
else
|
5270 |
|
|
{
|
5271 |
|
|
maxsync = AHC_SYNCRATE_FAST;
|
5272 |
|
|
}
|
5273 |
|
|
/*
|
5274 |
|
|
* We might have a device that is starting negotiation with us
|
5275 |
|
|
* before we can start up negotiation with it....be prepared to
|
5276 |
|
|
* have a device ask for a higher speed then we want to give it
|
5277 |
|
|
* in that case
|
5278 |
|
|
*/
|
5279 |
|
|
if ( (scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR)) !=
|
5280 |
|
|
(SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR) )
|
5281 |
|
|
{
|
5282 |
|
|
if (!(p->dev_flags[tindex] & DEVICE_SCANNED))
|
5283 |
|
|
{
|
5284 |
|
|
/*
|
5285 |
|
|
* Not only is the device starting this up, but it also hasn't
|
5286 |
|
|
* been scanned yet, so this would likely be our TUR or our
|
5287 |
|
|
* INQUIRY command at scan time, so we need to use the
|
5288 |
|
|
* settings from the SEEPROM if they existed. Of course, even
|
5289 |
|
|
* if we didn't find a SEEPROM, we stuffed default values into
|
5290 |
|
|
* the user settings anyway, so use those in all cases.
|
5291 |
|
|
*/
|
5292 |
|
|
p->transinfo[tindex].goal_period =
|
5293 |
|
|
p->transinfo[tindex].user_period;
|
5294 |
|
|
p->transinfo[tindex].goal_offset =
|
5295 |
|
|
p->transinfo[tindex].user_offset;
|
5296 |
|
|
p->needsdtr_copy |= target_mask;
|
5297 |
|
|
}
|
5298 |
|
|
if ( !p->transinfo[tindex].goal_offset )
|
5299 |
|
|
period = 255;
|
5300 |
|
|
if ( p->transinfo[tindex].goal_period > period )
|
5301 |
|
|
period = p->transinfo[tindex].goal_period;
|
5302 |
|
|
}
|
5303 |
|
|
|
5304 |
|
|
syncrate = aic7xxx_find_syncrate(p, &period, maxsync);
|
5305 |
|
|
aic7xxx_validate_offset(p, syncrate, &offset,
|
5306 |
|
|
target_scsirate & WIDEXFER);
|
5307 |
|
|
aic7xxx_set_syncrate(p, syncrate, target, channel, period,
|
5308 |
|
|
offset, AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
|
5309 |
|
|
|
5310 |
|
|
/*
|
5311 |
|
|
* Did we drop to async? If so, are we sending a reply? If we are,
|
5312 |
|
|
* then we have to make sure that the reply value reflects the proper
|
5313 |
|
|
* settings so we need to set the goal values according to what
|
5314 |
|
|
* we need to send.
|
5315 |
|
|
*/
|
5316 |
|
|
if ( (offset == 0) || (offset != saved_offset) ||
|
5317 |
|
|
((scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR)) !=
|
5318 |
|
|
(SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR) ) )
|
5319 |
|
|
{
|
5320 |
|
|
aic7xxx_set_syncrate(p, syncrate, target, channel, period,
|
5321 |
|
|
offset, AHC_TRANS_GOAL|AHC_TRANS_QUITE);
|
5322 |
|
|
if ( offset == 0 )
|
5323 |
|
|
{
|
5324 |
|
|
p->needsdtr_copy &= ~target_mask;
|
5325 |
|
|
}
|
5326 |
|
|
}
|
5327 |
|
|
|
5328 |
|
|
/*
|
5329 |
|
|
* Did we start this, if not, or if we went to low and had to
|
5330 |
|
|
* go async, then send an SDTR back to the target
|
5331 |
|
|
*/
|
5332 |
|
|
p->needsdtr &= ~target_mask;
|
5333 |
|
|
p->sdtr_pending &= ~target_mask;
|
5334 |
|
|
if ( ((scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR)) ==
|
5335 |
|
|
(SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR)) &&
|
5336 |
|
|
(offset == saved_offset) )
|
5337 |
|
|
{
|
5338 |
|
|
scb->flags &= ~SCB_MSGOUT_BITS;
|
5339 |
|
|
}
|
5340 |
|
|
else
|
5341 |
|
|
{
|
5342 |
|
|
scb->flags &= ~SCB_MSGOUT_BITS;
|
5343 |
|
|
scb->flags |= SCB_MSGOUT_SDTR;
|
5344 |
|
|
aic_outb(p, HOST_MSG, MSG_OUT);
|
5345 |
|
|
aic_outb(p, aic_inb(p, SCSISIGO) | ATNO, SCSISIGO);
|
5346 |
|
|
}
|
5347 |
|
|
done = TRUE;
|
5348 |
|
|
break;
|
5349 |
|
|
}
|
5350 |
|
|
case MSG_EXT_WDTR:
|
5351 |
|
|
{
|
5352 |
|
|
unsigned char bus_width;
|
5353 |
|
|
|
5354 |
|
|
if (p->msg_buf[1] != MSG_EXT_WDTR_LEN)
|
5355 |
|
|
{
|
5356 |
|
|
reject = TRUE;
|
5357 |
|
|
break;
|
5358 |
|
|
}
|
5359 |
|
|
|
5360 |
|
|
if (p->msg_len < (MSG_EXT_WDTR_LEN + 2))
|
5361 |
|
|
{
|
5362 |
|
|
break;
|
5363 |
|
|
}
|
5364 |
|
|
|
5365 |
|
|
bus_width = p->msg_buf[3];
|
5366 |
|
|
if ( (scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_WDTR)) ==
|
5367 |
|
|
(SCB_MSGOUT_SENT|SCB_MSGOUT_WDTR) )
|
5368 |
|
|
{
|
5369 |
|
|
switch(bus_width)
|
5370 |
|
|
{
|
5371 |
|
|
default:
|
5372 |
|
|
{
|
5373 |
|
|
reject = TRUE;
|
5374 |
|
|
if ( (aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
|
5375 |
|
|
((p->dev_flags[tindex] & DEVICE_PRINT_WDTR) ||
|
5376 |
|
|
(aic7xxx_verbose > 0xffff)) )
|
5377 |
|
|
{
|
5378 |
|
|
printk(INFO_LEAD "Requesting %d bit transfers, rejecting.\n",
|
5379 |
|
|
p->host_no, CTL_OF_SCB(scb), 8 * (0x01 << bus_width));
|
5380 |
|
|
p->dev_flags[tindex] &= ~DEVICE_PRINT_WDTR;
|
5381 |
|
|
}
|
5382 |
|
|
} /* We fall through on purpose */
|
5383 |
|
|
case MSG_EXT_WDTR_BUS_8_BIT:
|
5384 |
|
|
{
|
5385 |
|
|
bus_width = MSG_EXT_WDTR_BUS_8_BIT;
|
5386 |
|
|
p->needwdtr_copy &= ~target_mask;
|
5387 |
|
|
break;
|
5388 |
|
|
}
|
5389 |
|
|
case MSG_EXT_WDTR_BUS_16_BIT:
|
5390 |
|
|
{
|
5391 |
|
|
break;
|
5392 |
|
|
}
|
5393 |
|
|
}
|
5394 |
|
|
scb->flags &= ~SCB_MSGOUT_BITS;
|
5395 |
|
|
p->wdtr_pending &= ~target_mask;
|
5396 |
|
|
p->needwdtr &= ~target_mask;
|
5397 |
|
|
}
|
5398 |
|
|
else
|
5399 |
|
|
{
|
5400 |
|
|
scb->flags &= ~SCB_MSGOUT_BITS;
|
5401 |
|
|
scb->flags |= SCB_MSGOUT_WDTR;
|
5402 |
|
|
reply = TRUE;
|
5403 |
|
|
if ( !(p->dev_flags[tindex] & DEVICE_SCANNED) )
|
5404 |
|
|
{
|
5405 |
|
|
/*
|
5406 |
|
|
* Well, we now know the WDTR and SYNC caps of this device since
|
5407 |
|
|
* it contacted us first, mark it as such and copy the user stuff
|
5408 |
|
|
* over to the goal stuff.
|
5409 |
|
|
*/
|
5410 |
|
|
p->transinfo[tindex].goal_period =
|
5411 |
|
|
p->transinfo[tindex].user_period;
|
5412 |
|
|
p->transinfo[tindex].goal_offset =
|
5413 |
|
|
p->transinfo[tindex].user_offset;
|
5414 |
|
|
p->transinfo[tindex].goal_width =
|
5415 |
|
|
p->transinfo[tindex].user_width;
|
5416 |
|
|
p->needwdtr_copy |= target_mask;
|
5417 |
|
|
p->needsdtr_copy |= target_mask;
|
5418 |
|
|
}
|
5419 |
|
|
switch(bus_width)
|
5420 |
|
|
{
|
5421 |
|
|
default:
|
5422 |
|
|
{
|
5423 |
|
|
if ( (p->features & AHC_WIDE) &&
|
5424 |
|
|
(p->transinfo[tindex].goal_width ==
|
5425 |
|
|
MSG_EXT_WDTR_BUS_16_BIT) )
|
5426 |
|
|
{
|
5427 |
|
|
bus_width = MSG_EXT_WDTR_BUS_16_BIT;
|
5428 |
|
|
break;
|
5429 |
|
|
}
|
5430 |
|
|
} /* Fall through if we aren't a wide card */
|
5431 |
|
|
case MSG_EXT_WDTR_BUS_8_BIT:
|
5432 |
|
|
{
|
5433 |
|
|
p->needwdtr_copy &= ~target_mask;
|
5434 |
|
|
bus_width = MSG_EXT_WDTR_BUS_8_BIT;
|
5435 |
|
|
aic7xxx_set_width(p, target, channel, lun, bus_width,
|
5436 |
|
|
AHC_TRANS_GOAL|AHC_TRANS_QUITE);
|
5437 |
|
|
break;
|
5438 |
|
|
}
|
5439 |
|
|
}
|
5440 |
|
|
p->needwdtr &= ~target_mask;
|
5441 |
|
|
p->wdtr_pending &= ~target_mask;
|
5442 |
|
|
aic_outb(p, HOST_MSG, MSG_OUT);
|
5443 |
|
|
aic_outb(p, aic_inb(p, SCSISIGO) | ATNO, SCSISIGO);
|
5444 |
|
|
}
|
5445 |
|
|
aic7xxx_set_width(p, target, channel, lun, bus_width,
|
5446 |
|
|
AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
|
5447 |
|
|
|
5448 |
|
|
/*
|
5449 |
|
|
* By virtue of the SCSI spec, a WDTR message negates any existing
|
5450 |
|
|
* SDTR negotiations. So, even if needsdtr isn't marked for this
|
5451 |
|
|
* device, we still have to do a new SDTR message if the device
|
5452 |
|
|
* supports SDTR at all. Therefore, we check needsdtr_copy instead
|
5453 |
|
|
* of needstr.
|
5454 |
|
|
*/
|
5455 |
|
|
aic7xxx_set_syncrate(p, NULL, target, channel, 0, 0,
|
5456 |
|
|
AHC_TRANS_ACTIVE|AHC_TRANS_CUR|AHC_TRANS_QUITE);
|
5457 |
|
|
if ( (p->needsdtr_copy & target_mask) &&
|
5458 |
|
|
!(p->sdtr_pending & target_mask))
|
5459 |
|
|
{
|
5460 |
|
|
p->needsdtr |= target_mask;
|
5461 |
|
|
if ( !reject && !reply )
|
5462 |
|
|
{
|
5463 |
|
|
scb->flags &= ~SCB_MSGOUT_WDTR;
|
5464 |
|
|
if (p->transinfo[tindex].goal_period)
|
5465 |
|
|
{
|
5466 |
|
|
p->sdtr_pending |= target_mask;
|
5467 |
|
|
scb->flags |= SCB_MSGOUT_SDTR;
|
5468 |
|
|
aic_outb(p, HOST_MSG, MSG_OUT);
|
5469 |
|
|
aic_outb(p, aic_inb(p, SCSISIGO) | ATNO, SCSISIGO);
|
5470 |
|
|
}
|
5471 |
|
|
}
|
5472 |
|
|
}
|
5473 |
|
|
done = TRUE;
|
5474 |
|
|
break;
|
5475 |
|
|
}
|
5476 |
|
|
default:
|
5477 |
|
|
{
|
5478 |
|
|
reject = TRUE;
|
5479 |
|
|
break;
|
5480 |
|
|
}
|
5481 |
|
|
} /* end of switch(p->msg_type) */
|
5482 |
|
|
} /* end of if (!reject && (p->msg_len > 2)) */
|
5483 |
|
|
|
5484 |
|
|
if (reject)
|
5485 |
|
|
{
|
5486 |
|
|
aic_outb(p, MSG_MESSAGE_REJECT, MSG_OUT);
|
5487 |
|
|
aic_outb(p, aic_inb(p, SCSISIGO) | ATNO, SCSISIGO);
|
5488 |
|
|
done = TRUE;
|
5489 |
|
|
}
|
5490 |
|
|
return(done);
|
5491 |
|
|
}
|
5492 |
|
|
|
5493 |
|
|
|
5494 |
|
|
/*+F*************************************************************************
|
5495 |
|
|
* Function:
|
5496 |
|
|
* aic7xxx_handle_reqinit
|
5497 |
|
|
*
|
5498 |
|
|
* Description:
|
5499 |
|
|
* Interrupt handler for REQINIT interrupts (used to transfer messages to
|
5500 |
|
|
* and from devices).
|
5501 |
|
|
*_F*************************************************************************/
|
5502 |
|
|
static void
|
5503 |
|
|
aic7xxx_handle_reqinit(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
|
5504 |
|
|
{
|
5505 |
|
|
unsigned char lastbyte;
|
5506 |
|
|
unsigned char phasemis;
|
5507 |
|
|
int done = FALSE;
|
5508 |
|
|
|
5509 |
|
|
switch(p->msg_type)
|
5510 |
|
|
{
|
5511 |
|
|
case MSG_TYPE_INITIATOR_MSGOUT:
|
5512 |
|
|
{
|
5513 |
|
|
if (p->msg_len == 0)
|
5514 |
|
|
panic("aic7xxx: REQINIT with no active message!\n");
|
5515 |
|
|
|
5516 |
|
|
lastbyte = (p->msg_index == (p->msg_len - 1));
|
5517 |
|
|
phasemis = ( aic_inb(p, SCSISIGI) & PHASE_MASK) != P_MESGOUT;
|
5518 |
|
|
|
5519 |
|
|
if (lastbyte || phasemis)
|
5520 |
|
|
{
|
5521 |
|
|
/* Time to end the message */
|
5522 |
|
|
p->msg_len = 0;
|
5523 |
|
|
p->msg_type = MSG_TYPE_NONE;
|
5524 |
|
|
/*
|
5525 |
|
|
* NOTE-TO-MYSELF: If you clear the REQINIT after you
|
5526 |
|
|
* disable REQINITs, then cases of REJECT_MSG stop working
|
5527 |
|
|
* and hang the bus
|
5528 |
|
|
*/
|
5529 |
|
|
aic_outb(p, aic_inb(p, SIMODE1) & ~ENREQINIT, SIMODE1);
|
5530 |
|
|
aic_outb(p, CLRSCSIINT, CLRINT);
|
5531 |
|
|
p->flags &= ~AHC_HANDLING_REQINITS;
|
5532 |
|
|
|
5533 |
|
|
if (phasemis == 0)
|
5534 |
|
|
{
|
5535 |
|
|
aic_outb(p, p->msg_buf[p->msg_index], SINDEX);
|
5536 |
|
|
aic_outb(p, 0, RETURN_1);
|
5537 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
5538 |
|
|
if (aic7xxx_verbose > 0xffff)
|
5539 |
|
|
printk(INFO_LEAD "Completed sending of REQINIT message.\n",
|
5540 |
|
|
p->host_no, CTL_OF_SCB(scb));
|
5541 |
|
|
#endif
|
5542 |
|
|
}
|
5543 |
|
|
else
|
5544 |
|
|
{
|
5545 |
|
|
aic_outb(p, MSGOUT_PHASEMIS, RETURN_1);
|
5546 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
5547 |
|
|
if (aic7xxx_verbose > 0xffff)
|
5548 |
|
|
printk(INFO_LEAD "PHASEMIS while sending REQINIT message.\n",
|
5549 |
|
|
p->host_no, CTL_OF_SCB(scb));
|
5550 |
|
|
#endif
|
5551 |
|
|
}
|
5552 |
|
|
unpause_sequencer(p, TRUE);
|
5553 |
|
|
}
|
5554 |
|
|
else
|
5555 |
|
|
{
|
5556 |
|
|
/*
|
5557 |
|
|
* Present the byte on the bus (clearing REQINIT) but don't
|
5558 |
|
|
* unpause the sequencer.
|
5559 |
|
|
*/
|
5560 |
|
|
aic_outb(p, CLRREQINIT, CLRSINT1);
|
5561 |
|
|
aic_outb(p, CLRSCSIINT, CLRINT);
|
5562 |
|
|
aic_outb(p, p->msg_buf[p->msg_index++], SCSIDATL);
|
5563 |
|
|
}
|
5564 |
|
|
break;
|
5565 |
|
|
}
|
5566 |
|
|
case MSG_TYPE_INITIATOR_MSGIN:
|
5567 |
|
|
{
|
5568 |
|
|
phasemis = ( aic_inb(p, SCSISIGI) & PHASE_MASK ) != P_MESGIN;
|
5569 |
|
|
|
5570 |
|
|
if (phasemis == 0)
|
5571 |
|
|
{
|
5572 |
|
|
p->msg_len++;
|
5573 |
|
|
/* Pull the byte in without acking it */
|
5574 |
|
|
p->msg_buf[p->msg_index] = aic_inb(p, SCSIBUSL);
|
5575 |
|
|
done = aic7xxx_parse_msg(p, scb);
|
5576 |
|
|
/* Ack the byte */
|
5577 |
|
|
aic_outb(p, CLRREQINIT, CLRSINT1);
|
5578 |
|
|
aic_outb(p, CLRSCSIINT, CLRINT);
|
5579 |
|
|
aic_inb(p, SCSIDATL);
|
5580 |
|
|
p->msg_index++;
|
5581 |
|
|
}
|
5582 |
|
|
if (phasemis || done)
|
5583 |
|
|
{
|
5584 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
5585 |
|
|
if (aic7xxx_verbose > 0xffff)
|
5586 |
|
|
{
|
5587 |
|
|
if (phasemis)
|
5588 |
|
|
printk(INFO_LEAD "PHASEMIS while receiving REQINIT message.\n",
|
5589 |
|
|
p->host_no, CTL_OF_SCB(scb));
|
5590 |
|
|
else
|
5591 |
|
|
printk(INFO_LEAD "Completed receipt of REQINIT message.\n",
|
5592 |
|
|
p->host_no, CTL_OF_SCB(scb));
|
5593 |
|
|
}
|
5594 |
|
|
#endif
|
5595 |
|
|
/* Time to end our message session */
|
5596 |
|
|
p->msg_len = 0;
|
5597 |
|
|
p->msg_type = MSG_TYPE_NONE;
|
5598 |
|
|
aic_outb(p, aic_inb(p, SIMODE1) & ~ENREQINIT, SIMODE1);
|
5599 |
|
|
aic_outb(p, CLRSCSIINT, CLRINT);
|
5600 |
|
|
p->flags &= ~AHC_HANDLING_REQINITS;
|
5601 |
|
|
unpause_sequencer(p, TRUE);
|
5602 |
|
|
}
|
5603 |
|
|
break;
|
5604 |
|
|
}
|
5605 |
|
|
default:
|
5606 |
|
|
{
|
5607 |
|
|
panic("aic7xxx: Unknown REQINIT message type.\n");
|
5608 |
|
|
break;
|
5609 |
|
|
}
|
5610 |
|
|
} /* End of switch(p->msg_type) */
|
5611 |
|
|
}
|
5612 |
|
|
|
5613 |
|
|
/*+F*************************************************************************
|
5614 |
|
|
* Function:
|
5615 |
|
|
* aic7xxx_handle_scsiint
|
5616 |
|
|
*
|
5617 |
|
|
* Description:
|
5618 |
|
|
* Interrupt handler for SCSI interrupts (SCSIINT).
|
5619 |
|
|
*-F*************************************************************************/
|
5620 |
|
|
static void
|
5621 |
|
|
aic7xxx_handle_scsiint(struct aic7xxx_host *p, unsigned char intstat)
|
5622 |
|
|
{
|
5623 |
|
|
unsigned char scb_index;
|
5624 |
|
|
unsigned char status;
|
5625 |
|
|
struct aic7xxx_scb *scb;
|
5626 |
|
|
|
5627 |
|
|
scb_index = aic_inb(p, SCB_TAG);
|
5628 |
|
|
status = aic_inb(p, SSTAT1);
|
5629 |
|
|
|
5630 |
|
|
if (scb_index < p->scb_data->numscbs)
|
5631 |
|
|
{
|
5632 |
|
|
scb = p->scb_data->scb_array[scb_index];
|
5633 |
|
|
if ((scb->flags & SCB_ACTIVE) == 0)
|
5634 |
|
|
{
|
5635 |
|
|
scb = NULL;
|
5636 |
|
|
}
|
5637 |
|
|
}
|
5638 |
|
|
else
|
5639 |
|
|
{
|
5640 |
|
|
scb = NULL;
|
5641 |
|
|
}
|
5642 |
|
|
|
5643 |
|
|
|
5644 |
|
|
if ((status & SCSIRSTI) != 0)
|
5645 |
|
|
{
|
5646 |
|
|
int channel;
|
5647 |
|
|
|
5648 |
|
|
if ( (p->chip & AHC_CHIPID_MASK) == AHC_AIC7770 )
|
5649 |
|
|
channel = (aic_inb(p, SBLKCTL) & SELBUSB) >> 3;
|
5650 |
|
|
else
|
5651 |
|
|
channel = 0;
|
5652 |
|
|
|
5653 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET)
|
5654 |
|
|
printk(WARN_LEAD "Someone else reset the channel!!\n",
|
5655 |
|
|
p->host_no, channel, -1, -1);
|
5656 |
|
|
/*
|
5657 |
|
|
* Go through and abort all commands for the channel, but do not
|
5658 |
|
|
* reset the channel again.
|
5659 |
|
|
*/
|
5660 |
|
|
aic7xxx_reset_channel(p, channel, /* Initiate Reset */ FALSE);
|
5661 |
|
|
aic7xxx_run_done_queue(p, FALSE);
|
5662 |
|
|
scb = NULL;
|
5663 |
|
|
}
|
5664 |
|
|
else if ( ((status & BUSFREE) != 0) && ((status & SELTO) == 0) )
|
5665 |
|
|
{
|
5666 |
|
|
/*
|
5667 |
|
|
* First look at what phase we were last in. If it's message-out,
|
5668 |
|
|
* chances are pretty good that the bus free was in response to
|
5669 |
|
|
* one of our abort requests.
|
5670 |
|
|
*/
|
5671 |
|
|
unsigned char lastphase = aic_inb(p, LASTPHASE);
|
5672 |
|
|
unsigned char saved_tcl = aic_inb(p, SAVED_TCL);
|
5673 |
|
|
unsigned char target = (saved_tcl >> 4) & 0x0F;
|
5674 |
|
|
int channel;
|
5675 |
|
|
int printerror = TRUE;
|
5676 |
|
|
|
5677 |
|
|
if ( (p->chip & AHC_CHIPID_MASK) == AHC_AIC7770 )
|
5678 |
|
|
channel = (aic_inb(p, SBLKCTL) & SELBUSB) >> 3;
|
5679 |
|
|
else
|
5680 |
|
|
channel = 0;
|
5681 |
|
|
|
5682 |
|
|
aic_outb(p, aic_inb(p, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP),
|
5683 |
|
|
SCSISEQ);
|
5684 |
|
|
if (lastphase == P_MESGOUT)
|
5685 |
|
|
{
|
5686 |
|
|
unsigned char message;
|
5687 |
|
|
|
5688 |
|
|
message = aic_inb(p, SINDEX);
|
5689 |
|
|
|
5690 |
|
|
if ((message == MSG_ABORT) || (message == MSG_ABORT_TAG))
|
5691 |
|
|
{
|
5692 |
|
|
if (aic7xxx_verbose & VERBOSE_ABORT_PROCESS)
|
5693 |
|
|
printk(INFO_LEAD "SCB %d abort delivered.\n", p->host_no,
|
5694 |
|
|
CTL_OF_SCB(scb), scb->hscb->tag);
|
5695 |
|
|
aic7xxx_reset_device(p, target, channel, ALL_LUNS,
|
5696 |
|
|
(message == MSG_ABORT) ? SCB_LIST_NULL : scb->hscb->tag );
|
5697 |
|
|
aic7xxx_run_done_queue(p, FALSE);
|
5698 |
|
|
scb = NULL;
|
5699 |
|
|
printerror = 0;
|
5700 |
|
|
}
|
5701 |
|
|
else if (message == MSG_BUS_DEV_RESET)
|
5702 |
|
|
{
|
5703 |
|
|
aic7xxx_handle_device_reset(p, target, channel);
|
5704 |
|
|
scb = NULL;
|
5705 |
|
|
printerror = 0;
|
5706 |
|
|
}
|
5707 |
|
|
}
|
5708 |
|
|
if (printerror != 0)
|
5709 |
|
|
{
|
5710 |
|
|
if (scb != NULL)
|
5711 |
|
|
{
|
5712 |
|
|
unsigned char tag;
|
5713 |
|
|
|
5714 |
|
|
if ((scb->hscb->control & TAG_ENB) != 0)
|
5715 |
|
|
{
|
5716 |
|
|
tag = scb->hscb->tag;
|
5717 |
|
|
}
|
5718 |
|
|
else
|
5719 |
|
|
{
|
5720 |
|
|
tag = SCB_LIST_NULL;
|
5721 |
|
|
}
|
5722 |
|
|
aic7xxx_reset_device(p, target, channel, ALL_LUNS, tag);
|
5723 |
|
|
aic7xxx_run_done_queue(p, FALSE);
|
5724 |
|
|
}
|
5725 |
|
|
printk(INFO_LEAD "Unexpected busfree, LASTPHASE = 0x%x, "
|
5726 |
|
|
"SEQADDR = 0x%x\n", p->host_no, channel, target, -1, lastphase,
|
5727 |
|
|
(aic_inb(p, SEQADDR1) << 8) | aic_inb(p, SEQADDR0));
|
5728 |
|
|
scb = NULL;
|
5729 |
|
|
}
|
5730 |
|
|
aic_outb(p, MSG_NOOP, MSG_OUT);
|
5731 |
|
|
aic_outb(p, aic_inb(p, SIMODE1) & ~(ENBUSFREE|ENREQINIT),
|
5732 |
|
|
SIMODE1);
|
5733 |
|
|
p->flags &= ~AHC_HANDLING_REQINITS;
|
5734 |
|
|
aic_outb(p, CLRBUSFREE, CLRSINT1);
|
5735 |
|
|
aic_outb(p, CLRSCSIINT, CLRINT);
|
5736 |
|
|
restart_sequencer(p);
|
5737 |
|
|
unpause_sequencer(p, TRUE);
|
5738 |
|
|
}
|
5739 |
|
|
else if ((status & SELTO) != 0)
|
5740 |
|
|
{
|
5741 |
|
|
unsigned char scbptr;
|
5742 |
|
|
unsigned char nextscb;
|
5743 |
|
|
Scsi_Cmnd *cmd;
|
5744 |
|
|
|
5745 |
|
|
scbptr = aic_inb(p, WAITING_SCBH);
|
5746 |
|
|
if (scbptr > p->scb_data->maxhscbs)
|
5747 |
|
|
{
|
5748 |
|
|
/*
|
5749 |
|
|
* I'm still trying to track down exactly how this happens, but until
|
5750 |
|
|
* I find it, this code will make sure we aren't passing bogus values
|
5751 |
|
|
* into the SCBPTR register, even if that register will just wrap
|
5752 |
|
|
* things around, we still don't like having out of range variables.
|
5753 |
|
|
*
|
5754 |
|
|
* NOTE: Don't check the aic7xxx_verbose variable, I want this message
|
5755 |
|
|
* to always be displayed.
|
5756 |
|
|
*/
|
5757 |
|
|
printk(INFO_LEAD "Invalid WAITING_SCBH value %d, improvising.\n",
|
5758 |
|
|
p->host_no, -1, -1, -1, scbptr);
|
5759 |
|
|
if (p->scb_data->maxhscbs > 4)
|
5760 |
|
|
scbptr &= (p->scb_data->maxhscbs - 1);
|
5761 |
|
|
else
|
5762 |
|
|
scbptr &= 0x03;
|
5763 |
|
|
}
|
5764 |
|
|
aic_outb(p, scbptr, SCBPTR);
|
5765 |
|
|
scb_index = aic_inb(p, SCB_TAG);
|
5766 |
|
|
|
5767 |
|
|
scb = NULL;
|
5768 |
|
|
if (scb_index < p->scb_data->numscbs)
|
5769 |
|
|
{
|
5770 |
|
|
scb = p->scb_data->scb_array[scb_index];
|
5771 |
|
|
if ((scb->flags & SCB_ACTIVE) == 0)
|
5772 |
|
|
{
|
5773 |
|
|
scb = NULL;
|
5774 |
|
|
}
|
5775 |
|
|
}
|
5776 |
|
|
if (scb == NULL)
|
5777 |
|
|
{
|
5778 |
|
|
printk(WARN_LEAD "Referenced SCB %d not valid during SELTO.\n",
|
5779 |
|
|
p->host_no, -1, -1, -1, scb_index);
|
5780 |
|
|
printk(KERN_WARNING " SCSISEQ = 0x%x SEQADDR = 0x%x SSTAT0 = 0x%x "
|
5781 |
|
|
"SSTAT1 = 0x%x\n", aic_inb(p, SCSISEQ),
|
5782 |
|
|
aic_inb(p, SEQADDR0) | (aic_inb(p, SEQADDR1) << 8),
|
5783 |
|
|
aic_inb(p, SSTAT0), aic_inb(p, SSTAT1));
|
5784 |
|
|
if (aic7xxx_panic_on_abort)
|
5785 |
|
|
aic7xxx_panic_abort(p, NULL);
|
5786 |
|
|
}
|
5787 |
|
|
else
|
5788 |
|
|
{
|
5789 |
|
|
cmd = scb->cmd;
|
5790 |
|
|
cmd->result = (DID_TIME_OUT << 16);
|
5791 |
|
|
|
5792 |
|
|
/*
|
5793 |
|
|
* Clear out this hardware SCB
|
5794 |
|
|
*/
|
5795 |
|
|
aic_outb(p, 0, SCB_CONTROL);
|
5796 |
|
|
|
5797 |
|
|
/*
|
5798 |
|
|
* Clear out a few values in the card that are in an undetermined
|
5799 |
|
|
* state.
|
5800 |
|
|
*/
|
5801 |
|
|
aic_outb(p, MSG_NOOP, MSG_OUT);
|
5802 |
|
|
|
5803 |
|
|
/*
|
5804 |
|
|
* Shift the waiting for selection queue forward
|
5805 |
|
|
*/
|
5806 |
|
|
nextscb = aic_inb(p, SCB_NEXT);
|
5807 |
|
|
aic_outb(p, nextscb, WAITING_SCBH);
|
5808 |
|
|
|
5809 |
|
|
/*
|
5810 |
|
|
* Put this SCB back on the free list.
|
5811 |
|
|
*/
|
5812 |
|
|
aic7xxx_add_curscb_to_free_list(p);
|
5813 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
5814 |
|
|
if (aic7xxx_verbose > 0xffff)
|
5815 |
|
|
printk(INFO_LEAD "Selection Timeout.\n", p->host_no, CTL_OF_SCB(scb));
|
5816 |
|
|
#endif
|
5817 |
|
|
if (scb->flags & SCB_QUEUED_ABORT)
|
5818 |
|
|
{
|
5819 |
|
|
/*
|
5820 |
|
|
* We know that this particular SCB had to be the queued abort since
|
5821 |
|
|
* the disconnected SCB would have gotten a reconnect instead.
|
5822 |
|
|
* What we need to do then is to let the command timeout again so
|
5823 |
|
|
* we get a reset since this abort just failed.
|
5824 |
|
|
*/
|
5825 |
|
|
cmd->result = 0;
|
5826 |
|
|
scb = NULL;
|
5827 |
|
|
}
|
5828 |
|
|
}
|
5829 |
|
|
/*
|
5830 |
|
|
* Restarting the sequencer will stop the selection and make sure devices
|
5831 |
|
|
* are allowed to reselect in.
|
5832 |
|
|
*/
|
5833 |
|
|
aic_outb(p, 0, SCSISEQ);
|
5834 |
|
|
aic_outb(p, aic_inb(p, SIMODE1) & ~(ENREQINIT|ENBUSFREE), SIMODE1);
|
5835 |
|
|
p->flags &= ~AHC_HANDLING_REQINITS;
|
5836 |
|
|
aic_outb(p, CLRSELTIMEO | CLRBUSFREE, CLRSINT1);
|
5837 |
|
|
aic_outb(p, CLRSCSIINT, CLRINT);
|
5838 |
|
|
restart_sequencer(p);
|
5839 |
|
|
unpause_sequencer(p, TRUE);
|
5840 |
|
|
}
|
5841 |
|
|
else if (scb == NULL)
|
5842 |
|
|
{
|
5843 |
|
|
printk(WARN_LEAD "aic7xxx_isr - referenced scb not valid "
|
5844 |
|
|
"during scsiint 0x%x scb(%d)\n"
|
5845 |
|
|
" SIMODE0 0x%x, SIMODE1 0x%x, SSTAT0 0x%x, SEQADDR 0x%x\n",
|
5846 |
|
|
p->host_no, -1, -1, -1, status, scb_index, aic_inb(p, SIMODE0),
|
5847 |
|
|
aic_inb(p, SIMODE1), aic_inb(p, SSTAT0),
|
5848 |
|
|
(aic_inb(p, SEQADDR1) << 8) | aic_inb(p, SEQADDR0));
|
5849 |
|
|
/*
|
5850 |
|
|
* Turn off the interrupt and set status to zero, so that it
|
5851 |
|
|
* falls through the rest of the SCSIINT code.
|
5852 |
|
|
*/
|
5853 |
|
|
aic_outb(p, status, CLRSINT1);
|
5854 |
|
|
aic_outb(p, CLRSCSIINT, CLRINT);
|
5855 |
|
|
unpause_sequencer(p, /* unpause always */ TRUE);
|
5856 |
|
|
scb = NULL;
|
5857 |
|
|
}
|
5858 |
|
|
else if (status & SCSIPERR)
|
5859 |
|
|
{
|
5860 |
|
|
/*
|
5861 |
|
|
* Determine the bus phase and queue an appropriate message.
|
5862 |
|
|
*/
|
5863 |
|
|
char *phase;
|
5864 |
|
|
Scsi_Cmnd *cmd;
|
5865 |
|
|
unsigned char mesg_out = MSG_NOOP;
|
5866 |
|
|
unsigned char lastphase = aic_inb(p, LASTPHASE);
|
5867 |
|
|
|
5868 |
|
|
cmd = scb->cmd;
|
5869 |
|
|
switch (lastphase)
|
5870 |
|
|
{
|
5871 |
|
|
case P_DATAOUT:
|
5872 |
|
|
phase = "Data-Out";
|
5873 |
|
|
break;
|
5874 |
|
|
case P_DATAIN:
|
5875 |
|
|
phase = "Data-In";
|
5876 |
|
|
mesg_out = MSG_INITIATOR_DET_ERR;
|
5877 |
|
|
break;
|
5878 |
|
|
case P_COMMAND:
|
5879 |
|
|
phase = "Command";
|
5880 |
|
|
break;
|
5881 |
|
|
case P_MESGOUT:
|
5882 |
|
|
phase = "Message-Out";
|
5883 |
|
|
break;
|
5884 |
|
|
case P_STATUS:
|
5885 |
|
|
phase = "Status";
|
5886 |
|
|
mesg_out = MSG_INITIATOR_DET_ERR;
|
5887 |
|
|
break;
|
5888 |
|
|
case P_MESGIN:
|
5889 |
|
|
phase = "Message-In";
|
5890 |
|
|
mesg_out = MSG_PARITY_ERROR;
|
5891 |
|
|
break;
|
5892 |
|
|
default:
|
5893 |
|
|
phase = "unknown";
|
5894 |
|
|
break;
|
5895 |
|
|
}
|
5896 |
|
|
|
5897 |
|
|
/*
|
5898 |
|
|
* A parity error has occurred during a data
|
5899 |
|
|
* transfer phase. Flag it and continue.
|
5900 |
|
|
*/
|
5901 |
|
|
printk(WARN_LEAD "Parity error during %s phase.\n",
|
5902 |
|
|
p->host_no, CTL_OF_SCB(scb), phase);
|
5903 |
|
|
|
5904 |
|
|
/*
|
5905 |
|
|
* We've set the hardware to assert ATN if we get a parity
|
5906 |
|
|
* error on "in" phases, so all we need to do is stuff the
|
5907 |
|
|
* message buffer with the appropriate message. "In" phases
|
5908 |
|
|
* have set mesg_out to something other than MSG_NOP.
|
5909 |
|
|
*/
|
5910 |
|
|
if (mesg_out != MSG_NOOP)
|
5911 |
|
|
{
|
5912 |
|
|
aic_outb(p, mesg_out, MSG_OUT);
|
5913 |
|
|
scb = NULL;
|
5914 |
|
|
}
|
5915 |
|
|
aic_outb(p, CLRSCSIPERR, CLRSINT1);
|
5916 |
|
|
aic_outb(p, CLRSCSIINT, CLRINT);
|
5917 |
|
|
unpause_sequencer(p, /* unpause_always */ TRUE);
|
5918 |
|
|
}
|
5919 |
|
|
else if ( (status & REQINIT) &&
|
5920 |
|
|
(p->flags & AHC_HANDLING_REQINITS) )
|
5921 |
|
|
{
|
5922 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
5923 |
|
|
if (aic7xxx_verbose > 0xffff)
|
5924 |
|
|
printk(INFO_LEAD "Handling REQINIT, SSTAT1=0x%x.\n", p->host_no,
|
5925 |
|
|
CTL_OF_SCB(scb), aic_inb(p, SSTAT1));
|
5926 |
|
|
#endif
|
5927 |
|
|
aic7xxx_handle_reqinit(p, scb);
|
5928 |
|
|
return;
|
5929 |
|
|
}
|
5930 |
|
|
else
|
5931 |
|
|
{
|
5932 |
|
|
/*
|
5933 |
|
|
* We don't know what's going on. Turn off the
|
5934 |
|
|
* interrupt source and try to continue.
|
5935 |
|
|
*/
|
5936 |
|
|
if (aic7xxx_verbose & VERBOSE_SCSIINT)
|
5937 |
|
|
printk(INFO_LEAD "Unknown SCSIINT status, SSTAT1(0x%x).\n",
|
5938 |
|
|
p->host_no, -1, -1, -1, status);
|
5939 |
|
|
aic_outb(p, status, CLRSINT1);
|
5940 |
|
|
aic_outb(p, CLRSCSIINT, CLRINT);
|
5941 |
|
|
unpause_sequencer(p, /* unpause always */ TRUE);
|
5942 |
|
|
scb = NULL;
|
5943 |
|
|
}
|
5944 |
|
|
if (scb != NULL)
|
5945 |
|
|
{
|
5946 |
|
|
aic7xxx_done(p, scb);
|
5947 |
|
|
}
|
5948 |
|
|
}
|
5949 |
|
|
|
5950 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
5951 |
|
|
static void
|
5952 |
|
|
aic7xxx_check_scbs(struct aic7xxx_host *p, char *buffer)
|
5953 |
|
|
{
|
5954 |
|
|
unsigned char saved_scbptr, free_scbh, dis_scbh, wait_scbh, temp;
|
5955 |
|
|
int i, bogus, lost;
|
5956 |
|
|
static unsigned char scb_status[AIC7XXX_MAXSCB];
|
5957 |
|
|
|
5958 |
|
|
#define SCB_NO_LIST 0
|
5959 |
|
|
#define SCB_FREE_LIST 1
|
5960 |
|
|
#define SCB_WAITING_LIST 2
|
5961 |
|
|
#define SCB_DISCONNECTED_LIST 4
|
5962 |
|
|
#define SCB_CURRENTLY_ACTIVE 8
|
5963 |
|
|
|
5964 |
|
|
/*
|
5965 |
|
|
* Note, these checks will fail on a regular basis once the machine moves
|
5966 |
|
|
* beyond the bus scan phase. The problem is race conditions concerning
|
5967 |
|
|
* the scbs and where they are linked in. When you have 30 or so commands
|
5968 |
|
|
* outstanding on the bus, and run this twice with every interrupt, the
|
5969 |
|
|
* chances get pretty good that you'll catch the sequencer with an SCB
|
5970 |
|
|
* only partially linked in. Therefore, once we pass the scan phase
|
5971 |
|
|
* of the bus, we really should disable this function.
|
5972 |
|
|
*/
|
5973 |
|
|
bogus = FALSE;
|
5974 |
|
|
memset(&scb_status[0], 0, sizeof(scb_status));
|
5975 |
|
|
pause_sequencer(p);
|
5976 |
|
|
saved_scbptr = aic_inb(p, SCBPTR);
|
5977 |
|
|
if (saved_scbptr >= p->scb_data->maxhscbs)
|
5978 |
|
|
{
|
5979 |
|
|
printk("Bogus SCBPTR %d\n", saved_scbptr);
|
5980 |
|
|
bogus = TRUE;
|
5981 |
|
|
}
|
5982 |
|
|
scb_status[saved_scbptr] = SCB_CURRENTLY_ACTIVE;
|
5983 |
|
|
free_scbh = aic_inb(p, FREE_SCBH);
|
5984 |
|
|
if ( (free_scbh != SCB_LIST_NULL) &&
|
5985 |
|
|
(free_scbh >= p->scb_data->maxhscbs) )
|
5986 |
|
|
{
|
5987 |
|
|
printk("Bogus FREE_SCBH %d\n", free_scbh);
|
5988 |
|
|
bogus = TRUE;
|
5989 |
|
|
}
|
5990 |
|
|
else
|
5991 |
|
|
{
|
5992 |
|
|
temp = free_scbh;
|
5993 |
|
|
while( (temp != SCB_LIST_NULL) && (temp < p->scb_data->maxhscbs) )
|
5994 |
|
|
{
|
5995 |
|
|
if(scb_status[temp] & 0x07)
|
5996 |
|
|
{
|
5997 |
|
|
printk("HSCB %d on multiple lists, status 0x%02x", temp,
|
5998 |
|
|
scb_status[temp] | SCB_FREE_LIST);
|
5999 |
|
|
bogus = TRUE;
|
6000 |
|
|
}
|
6001 |
|
|
scb_status[temp] |= SCB_FREE_LIST;
|
6002 |
|
|
aic_outb(p, temp, SCBPTR);
|
6003 |
|
|
temp = aic_inb(p, SCB_NEXT);
|
6004 |
|
|
}
|
6005 |
|
|
}
|
6006 |
|
|
|
6007 |
|
|
dis_scbh = aic_inb(p, DISCONNECTED_SCBH);
|
6008 |
|
|
if ( (dis_scbh != SCB_LIST_NULL) &&
|
6009 |
|
|
(dis_scbh >= p->scb_data->maxhscbs) )
|
6010 |
|
|
{
|
6011 |
|
|
printk("Bogus DISCONNECTED_SCBH %d\n", dis_scbh);
|
6012 |
|
|
bogus = TRUE;
|
6013 |
|
|
}
|
6014 |
|
|
else
|
6015 |
|
|
{
|
6016 |
|
|
temp = dis_scbh;
|
6017 |
|
|
while( (temp != SCB_LIST_NULL) && (temp < p->scb_data->maxhscbs) )
|
6018 |
|
|
{
|
6019 |
|
|
if(scb_status[temp] & 0x07)
|
6020 |
|
|
{
|
6021 |
|
|
printk("HSCB %d on multiple lists, status 0x%02x", temp,
|
6022 |
|
|
scb_status[temp] | SCB_DISCONNECTED_LIST);
|
6023 |
|
|
bogus = TRUE;
|
6024 |
|
|
}
|
6025 |
|
|
scb_status[temp] |= SCB_DISCONNECTED_LIST;
|
6026 |
|
|
aic_outb(p, temp, SCBPTR);
|
6027 |
|
|
temp = aic_inb(p, SCB_NEXT);
|
6028 |
|
|
}
|
6029 |
|
|
}
|
6030 |
|
|
|
6031 |
|
|
wait_scbh = aic_inb(p, WAITING_SCBH);
|
6032 |
|
|
if ( (wait_scbh != SCB_LIST_NULL) &&
|
6033 |
|
|
(wait_scbh >= p->scb_data->maxhscbs) )
|
6034 |
|
|
{
|
6035 |
|
|
printk("Bogus WAITING_SCBH %d\n", wait_scbh);
|
6036 |
|
|
bogus = TRUE;
|
6037 |
|
|
}
|
6038 |
|
|
else
|
6039 |
|
|
{
|
6040 |
|
|
temp = wait_scbh;
|
6041 |
|
|
while( (temp != SCB_LIST_NULL) && (temp < p->scb_data->maxhscbs) )
|
6042 |
|
|
{
|
6043 |
|
|
if(scb_status[temp] & 0x07)
|
6044 |
|
|
{
|
6045 |
|
|
printk("HSCB %d on multiple lists, status 0x%02x", temp,
|
6046 |
|
|
scb_status[temp] | SCB_WAITING_LIST);
|
6047 |
|
|
bogus = TRUE;
|
6048 |
|
|
}
|
6049 |
|
|
scb_status[temp] |= SCB_WAITING_LIST;
|
6050 |
|
|
aic_outb(p, temp, SCBPTR);
|
6051 |
|
|
temp = aic_inb(p, SCB_NEXT);
|
6052 |
|
|
}
|
6053 |
|
|
}
|
6054 |
|
|
|
6055 |
|
|
lost=0;
|
6056 |
|
|
for(i=0; i < p->scb_data->maxhscbs; i++)
|
6057 |
|
|
{
|
6058 |
|
|
aic_outb(p, i, SCBPTR);
|
6059 |
|
|
temp = aic_inb(p, SCB_NEXT);
|
6060 |
|
|
if ( ((temp != SCB_LIST_NULL) &&
|
6061 |
|
|
(temp >= p->scb_data->maxhscbs)) )
|
6062 |
|
|
{
|
6063 |
|
|
printk("HSCB %d bad, SCB_NEXT invalid(%d).\n", i, temp);
|
6064 |
|
|
bogus = TRUE;
|
6065 |
|
|
}
|
6066 |
|
|
if ( temp == i )
|
6067 |
|
|
{
|
6068 |
|
|
printk("HSCB %d bad, SCB_NEXT points to self.\n", i);
|
6069 |
|
|
bogus = TRUE;
|
6070 |
|
|
}
|
6071 |
|
|
temp = aic_inb(p, SCB_PREV);
|
6072 |
|
|
if ((temp != SCB_LIST_NULL) &&
|
6073 |
|
|
(temp >= p->scb_data->maxhscbs))
|
6074 |
|
|
{
|
6075 |
|
|
printk("HSCB %d bad, SCB_PREV invalid(%d).\n", i, temp);
|
6076 |
|
|
bogus = TRUE;
|
6077 |
|
|
}
|
6078 |
|
|
if (scb_status[i] == 0)
|
6079 |
|
|
lost++;
|
6080 |
|
|
if (lost > 1)
|
6081 |
|
|
{
|
6082 |
|
|
printk("Too many lost scbs.\n");
|
6083 |
|
|
bogus=TRUE;
|
6084 |
|
|
}
|
6085 |
|
|
}
|
6086 |
|
|
aic_outb(p, saved_scbptr, SCBPTR);
|
6087 |
|
|
unpause_sequencer(p, FALSE);
|
6088 |
|
|
if (bogus)
|
6089 |
|
|
{
|
6090 |
|
|
printk("Bogus parameters found in card SCB array structures.\n");
|
6091 |
|
|
printk("%s\n", buffer);
|
6092 |
|
|
aic7xxx_panic_abort(p, NULL);
|
6093 |
|
|
}
|
6094 |
|
|
return;
|
6095 |
|
|
}
|
6096 |
|
|
#endif
|
6097 |
|
|
|
6098 |
|
|
/*+F*************************************************************************
|
6099 |
|
|
* Function:
|
6100 |
|
|
* aic7xxx_isr
|
6101 |
|
|
*
|
6102 |
|
|
* Description:
|
6103 |
|
|
* SCSI controller interrupt handler.
|
6104 |
|
|
*-F*************************************************************************/
|
6105 |
|
|
static void
|
6106 |
|
|
aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs)
|
6107 |
|
|
{
|
6108 |
|
|
struct aic7xxx_host *p;
|
6109 |
|
|
unsigned char intstat;
|
6110 |
|
|
|
6111 |
|
|
p = (struct aic7xxx_host *)dev_id;
|
6112 |
|
|
|
6113 |
|
|
/*
|
6114 |
|
|
* Just a few sanity checks. Make sure that we have an int pending.
|
6115 |
|
|
* Also, if PCI, then we are going to check for a PCI bus error status
|
6116 |
|
|
* should we get too many spurious interrupts.
|
6117 |
|
|
*/
|
6118 |
|
|
if (!((intstat = aic_inb(p, INTSTAT)) & INT_PEND))
|
6119 |
|
|
{
|
6120 |
|
|
#ifdef CONFIG_PCI
|
6121 |
|
|
if ( (p->chip & AHC_PCI) && (p->spurious_int > 500) &&
|
6122 |
|
|
!(p->flags & AHC_HANDLING_REQINITS) )
|
6123 |
|
|
{
|
6124 |
|
|
if ( aic_inb(p, ERROR) & PCIERRSTAT )
|
6125 |
|
|
{
|
6126 |
|
|
aic7xxx_pci_intr(p);
|
6127 |
|
|
}
|
6128 |
|
|
p->spurious_int = 0;
|
6129 |
|
|
}
|
6130 |
|
|
else if ( !(p->flags & AHC_HANDLING_REQINITS) )
|
6131 |
|
|
{
|
6132 |
|
|
p->spurious_int++;
|
6133 |
|
|
}
|
6134 |
|
|
#endif
|
6135 |
|
|
return;
|
6136 |
|
|
}
|
6137 |
|
|
|
6138 |
|
|
p->spurious_int = 0;
|
6139 |
|
|
|
6140 |
|
|
/*
|
6141 |
|
|
* Keep track of interrupts for /proc/scsi
|
6142 |
|
|
*/
|
6143 |
|
|
p->isr_count++;
|
6144 |
|
|
|
6145 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
6146 |
|
|
if ( (p->isr_count < 16) && (aic7xxx_verbose > 0xffff) &&
|
6147 |
|
|
(aic7xxx_panic_on_abort) && (p->flags & AHC_PAGESCBS) )
|
6148 |
|
|
aic7xxx_check_scbs(p, "Bogus settings at start of interrupt.");
|
6149 |
|
|
#endif
|
6150 |
|
|
|
6151 |
|
|
/*
|
6152 |
|
|
* Handle all the interrupt sources - especially for SCSI
|
6153 |
|
|
* interrupts, we won't get a second chance at them.
|
6154 |
|
|
*/
|
6155 |
|
|
if (intstat & CMDCMPLT)
|
6156 |
|
|
{
|
6157 |
|
|
struct aic7xxx_scb *scb = NULL;
|
6158 |
|
|
Scsi_Cmnd *cmd;
|
6159 |
|
|
unsigned char scb_index;
|
6160 |
|
|
|
6161 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
6162 |
|
|
if(aic7xxx_verbose > 0xffff)
|
6163 |
|
|
printk(INFO_LEAD "Command Complete Int.\n", p->host_no, -1, -1, -1);
|
6164 |
|
|
#endif
|
6165 |
|
|
|
6166 |
|
|
/*
|
6167 |
|
|
* Clear interrupt status before running the completion loop.
|
6168 |
|
|
* This eliminates a race condition whereby a command could
|
6169 |
|
|
* complete between the last check of qoutfifo and the
|
6170 |
|
|
* CLRCMDINT statement. This would result in us thinking the
|
6171 |
|
|
* qoutfifo was empty when it wasn't, and in actuality be a lost
|
6172 |
|
|
* completion interrupt. With multiple devices or tagged queueing
|
6173 |
|
|
* this could be very bad if we caught all but the last completion
|
6174 |
|
|
* and no more are imediately sent.
|
6175 |
|
|
*/
|
6176 |
|
|
aic_outb(p, CLRCMDINT, CLRINT);
|
6177 |
|
|
/*
|
6178 |
|
|
* The sequencer will continue running when it
|
6179 |
|
|
* issues this interrupt. There may be >1 commands
|
6180 |
|
|
* finished, so loop until we've processed them all.
|
6181 |
|
|
*/
|
6182 |
|
|
|
6183 |
|
|
while (p->qoutfifo[p->qoutfifonext] != SCB_LIST_NULL)
|
6184 |
|
|
{
|
6185 |
|
|
scb_index = p->qoutfifo[p->qoutfifonext];
|
6186 |
|
|
p->qoutfifo[p->qoutfifonext++] = SCB_LIST_NULL;
|
6187 |
|
|
if ( scb_index >= p->scb_data->numscbs )
|
6188 |
|
|
scb = NULL;
|
6189 |
|
|
else
|
6190 |
|
|
scb = p->scb_data->scb_array[scb_index];
|
6191 |
|
|
if (scb == NULL)
|
6192 |
|
|
{
|
6193 |
|
|
printk(WARN_LEAD "CMDCMPLT with invalid SCB index %d\n", p->host_no,
|
6194 |
|
|
-1, -1, -1, scb_index);
|
6195 |
|
|
continue;
|
6196 |
|
|
}
|
6197 |
|
|
else if (!(scb->flags & SCB_ACTIVE) || (scb->cmd == NULL))
|
6198 |
|
|
{
|
6199 |
|
|
printk(WARN_LEAD "CMDCMPLT without command for SCB %d, SCB flags "
|
6200 |
|
|
"0x%x, cmd 0x%lx\n", p->host_no, -1, -1, -1, scb_index, scb->flags,
|
6201 |
|
|
(unsigned long) scb->cmd);
|
6202 |
|
|
continue;
|
6203 |
|
|
}
|
6204 |
|
|
else if (scb->flags & SCB_QUEUED_ABORT)
|
6205 |
|
|
{
|
6206 |
|
|
pause_sequencer(p);
|
6207 |
|
|
if ( ((aic_inb(p, LASTPHASE) & PHASE_MASK) != P_BUSFREE) &&
|
6208 |
|
|
(aic_inb(p, SCB_TAG) == scb->hscb->tag) )
|
6209 |
|
|
{
|
6210 |
|
|
unpause_sequencer(p, FALSE);
|
6211 |
|
|
continue;
|
6212 |
|
|
}
|
6213 |
|
|
aic7xxx_reset_device(p, scb->cmd->target, scb->cmd->channel,
|
6214 |
|
|
scb->cmd->lun, scb->hscb->tag);
|
6215 |
|
|
scb->flags &= ~(SCB_QUEUED_FOR_DONE | SCB_RESET | SCB_ABORT |
|
6216 |
|
|
SCB_QUEUED_ABORT);
|
6217 |
|
|
unpause_sequencer(p, FALSE);
|
6218 |
|
|
}
|
6219 |
|
|
else if (scb->flags & SCB_ABORT)
|
6220 |
|
|
{
|
6221 |
|
|
/*
|
6222 |
|
|
* We started to abort this, but it completed on us, let it
|
6223 |
|
|
* through as successful
|
6224 |
|
|
*/
|
6225 |
|
|
scb->flags &= ~(SCB_ABORT|SCB_RESET);
|
6226 |
|
|
}
|
6227 |
|
|
switch (status_byte(scb->hscb->target_status))
|
6228 |
|
|
{
|
6229 |
|
|
case QUEUE_FULL:
|
6230 |
|
|
case BUSY:
|
6231 |
|
|
scb->hscb->target_status = 0;
|
6232 |
|
|
scb->cmd->result = 0;
|
6233 |
|
|
aic7xxx_error(scb->cmd) = DID_OK;
|
6234 |
|
|
break;
|
6235 |
|
|
default:
|
6236 |
|
|
cmd = scb->cmd;
|
6237 |
|
|
if (scb->hscb->residual_SG_segment_count != 0)
|
6238 |
|
|
{
|
6239 |
|
|
aic7xxx_calculate_residual(p, scb);
|
6240 |
|
|
}
|
6241 |
|
|
cmd->result |= (aic7xxx_error(cmd) << 16);
|
6242 |
|
|
aic7xxx_done(p, scb);
|
6243 |
|
|
break;
|
6244 |
|
|
}
|
6245 |
|
|
}
|
6246 |
|
|
}
|
6247 |
|
|
|
6248 |
|
|
if (intstat & BRKADRINT)
|
6249 |
|
|
{
|
6250 |
|
|
int i;
|
6251 |
|
|
unsigned char errno = aic_inb(p, ERROR);
|
6252 |
|
|
|
6253 |
|
|
printk(KERN_ERR "(scsi%d) BRKADRINT error(0x%x):\n", p->host_no, errno);
|
6254 |
|
|
for (i = 0; i < NUMBER(hard_error); i++)
|
6255 |
|
|
{
|
6256 |
|
|
if (errno & hard_error[i].errno)
|
6257 |
|
|
{
|
6258 |
|
|
printk(KERN_ERR " %s\n", hard_error[i].errmesg);
|
6259 |
|
|
}
|
6260 |
|
|
}
|
6261 |
|
|
printk(KERN_ERR "(scsi%d) SEQADDR=0x%x\n", p->host_no,
|
6262 |
|
|
(((aic_inb(p, SEQADDR1) << 8) & 0x100) | aic_inb(p, SEQADDR0)));
|
6263 |
|
|
if (aic7xxx_panic_on_abort)
|
6264 |
|
|
aic7xxx_panic_abort(p, NULL);
|
6265 |
|
|
#ifdef CONFIG_PCI
|
6266 |
|
|
if (errno & PCIERRSTAT)
|
6267 |
|
|
aic7xxx_pci_intr(p);
|
6268 |
|
|
#endif
|
6269 |
|
|
if (errno & (SQPARERR | ILLOPCODE | ILLSADDR))
|
6270 |
|
|
{
|
6271 |
|
|
sti();
|
6272 |
|
|
panic("aic7xxx: unrecoverable BRKADRINT.\n");
|
6273 |
|
|
}
|
6274 |
|
|
if (errno & ILLHADDR)
|
6275 |
|
|
{
|
6276 |
|
|
printk(KERN_ERR "(scsi%d) BUG! Driver accessed chip without first "
|
6277 |
|
|
"pausing controller!\n", p->host_no);
|
6278 |
|
|
}
|
6279 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
6280 |
|
|
if (errno & DPARERR)
|
6281 |
|
|
{
|
6282 |
|
|
if (aic_inb(p, DMAPARAMS) & DIRECTION)
|
6283 |
|
|
printk("(scsi%d) while DMAing SCB from host to card.\n", p->host_no);
|
6284 |
|
|
else
|
6285 |
|
|
printk("(scsi%d) while DMAing SCB from card to host.\n", p->host_no);
|
6286 |
|
|
}
|
6287 |
|
|
#endif
|
6288 |
|
|
aic_outb(p, CLRPARERR | CLRBRKADRINT, CLRINT);
|
6289 |
|
|
unpause_sequencer(p, FALSE);
|
6290 |
|
|
}
|
6291 |
|
|
|
6292 |
|
|
if (intstat & SEQINT)
|
6293 |
|
|
{
|
6294 |
|
|
aic7xxx_handle_seqint(p, intstat);
|
6295 |
|
|
}
|
6296 |
|
|
|
6297 |
|
|
if (intstat & SCSIINT)
|
6298 |
|
|
{
|
6299 |
|
|
aic7xxx_handle_scsiint(p, intstat);
|
6300 |
|
|
}
|
6301 |
|
|
|
6302 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
6303 |
|
|
if ( (p->isr_count < 16) && (aic7xxx_verbose > 0xffff) &&
|
6304 |
|
|
(aic7xxx_panic_on_abort) && (p->flags & AHC_PAGESCBS) )
|
6305 |
|
|
aic7xxx_check_scbs(p, "Bogus settings at end of interrupt.");
|
6306 |
|
|
#endif
|
6307 |
|
|
|
6308 |
|
|
}
|
6309 |
|
|
|
6310 |
|
|
/*+F*************************************************************************
|
6311 |
|
|
* Function:
|
6312 |
|
|
* do_aic7xxx_isr
|
6313 |
|
|
*
|
6314 |
|
|
* Description:
|
6315 |
|
|
* This is a gross hack to solve a problem in linux kernels 2.1.85 and
|
6316 |
|
|
* above. Please, children, do not try this at home, and if you ever see
|
6317 |
|
|
* anything like it, please inform the Gross Hack Police immediately
|
6318 |
|
|
*-F*************************************************************************/
|
6319 |
|
|
static void
|
6320 |
|
|
do_aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs)
|
6321 |
|
|
{
|
6322 |
|
|
unsigned long cpu_flags;
|
6323 |
|
|
struct aic7xxx_host *p;
|
6324 |
|
|
|
6325 |
|
|
p = (struct aic7xxx_host *)dev_id;
|
6326 |
|
|
if(!p)
|
6327 |
|
|
return;
|
6328 |
|
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,95)
|
6329 |
|
|
spin_lock_irqsave(&io_request_lock, cpu_flags);
|
6330 |
|
|
if(test_and_set_bit(AHC_IN_ISR_BIT, &p->flags))
|
6331 |
|
|
{
|
6332 |
|
|
return;
|
6333 |
|
|
}
|
6334 |
|
|
do
|
6335 |
|
|
{
|
6336 |
|
|
aic7xxx_isr(irq, dev_id, regs);
|
6337 |
|
|
} while ( (aic_inb(p, INTSTAT) & INT_PEND) );
|
6338 |
|
|
aic7xxx_done_cmds_complete(p);
|
6339 |
|
|
aic7xxx_run_waiting_queues(p);
|
6340 |
|
|
clear_bit(AHC_IN_ISR_BIT, &p->flags);
|
6341 |
|
|
spin_unlock_irqrestore(&io_request_lock, cpu_flags);
|
6342 |
|
|
#else
|
6343 |
|
|
if(set_bit(AHC_IN_ISR_BIT, (int *)&p->flags))
|
6344 |
|
|
{
|
6345 |
|
|
return;
|
6346 |
|
|
}
|
6347 |
|
|
DRIVER_LOCK
|
6348 |
|
|
do
|
6349 |
|
|
{
|
6350 |
|
|
aic7xxx_isr(irq, dev_id, regs);
|
6351 |
|
|
} while ( (aic_inb(p, INTSTAT) & INT_PEND) );
|
6352 |
|
|
DRIVER_UNLOCK
|
6353 |
|
|
aic7xxx_done_cmds_complete(p);
|
6354 |
|
|
aic7xxx_run_waiting_queues(p);
|
6355 |
|
|
clear_bit(AHC_IN_ISR_BIT, (int *)&p->flags);
|
6356 |
|
|
#endif
|
6357 |
|
|
}
|
6358 |
|
|
|
6359 |
|
|
/*+F*************************************************************************
|
6360 |
|
|
* Function:
|
6361 |
|
|
* aic7xxx_device_queue_depth
|
6362 |
|
|
*
|
6363 |
|
|
* Description:
|
6364 |
|
|
* Determines the queue depth for a given device. There are two ways
|
6365 |
|
|
* a queue depth can be obtained for a tagged queueing device. One
|
6366 |
|
|
* way is the default queue depth which is determined by whether
|
6367 |
|
|
* AIC7XXX_CMDS_PER_DEVICE is defined. If it is defined, then it is used
|
6368 |
|
|
* as the default queue depth. Otherwise, we use either 4 or 8 as the
|
6369 |
|
|
* default queue depth (dependent on the number of hardware SCBs).
|
6370 |
|
|
* The other way we determine queue depth is through the use of the
|
6371 |
|
|
* aic7xxx_tag_info array which is enabled by defining
|
6372 |
|
|
* AIC7XXX_TAGGED_QUEUEING_BY_DEVICE. This array can be initialized
|
6373 |
|
|
* with queue depths for individual devices. It also allows tagged
|
6374 |
|
|
* queueing to be [en|dis]abled for a specific adapter.
|
6375 |
|
|
*-F*************************************************************************/
|
6376 |
|
|
static void
|
6377 |
|
|
aic7xxx_device_queue_depth(struct aic7xxx_host *p, Scsi_Device *device)
|
6378 |
|
|
{
|
6379 |
|
|
int default_depth = 3;
|
6380 |
|
|
unsigned char tindex;
|
6381 |
|
|
unsigned short target_mask;
|
6382 |
|
|
|
6383 |
|
|
tindex = device->id | (device->channel << 3);
|
6384 |
|
|
target_mask = (1 << tindex);
|
6385 |
|
|
|
6386 |
|
|
device->queue_depth = default_depth;
|
6387 |
|
|
p->dev_temp_queue_depth[tindex] = 1;
|
6388 |
|
|
p->dev_max_queue_depth[tindex] = 1;
|
6389 |
|
|
p->tagenable &= ~target_mask;
|
6390 |
|
|
|
6391 |
|
|
if (device->tagged_supported)
|
6392 |
|
|
{
|
6393 |
|
|
int tag_enabled = TRUE;
|
6394 |
|
|
|
6395 |
|
|
default_depth = AIC7XXX_CMDS_PER_DEVICE;
|
6396 |
|
|
|
6397 |
|
|
if (!(p->discenable & target_mask))
|
6398 |
|
|
{
|
6399 |
|
|
if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
|
6400 |
|
|
printk(INFO_LEAD "Disconnection disabled, unable to "
|
6401 |
|
|
"enable tagged queueing.\n",
|
6402 |
|
|
p->host_no, device->channel, device->id, device->lun);
|
6403 |
|
|
}
|
6404 |
|
|
else
|
6405 |
|
|
{
|
6406 |
|
|
if (p->instance >= NUMBER(aic7xxx_tag_info))
|
6407 |
|
|
{
|
6408 |
|
|
static int print_warning = TRUE;
|
6409 |
|
|
if(print_warning)
|
6410 |
|
|
{
|
6411 |
|
|
printk(KERN_INFO "aic7xxx: WARNING, insufficient tag_info instances for"
|
6412 |
|
|
" installed controllers.\n");
|
6413 |
|
|
printk(KERN_INFO "aic7xxx: Please update the aic7xxx_tag_info array in"
|
6414 |
|
|
" the aic7xxx.c source file.\n");
|
6415 |
|
|
print_warning = FALSE;
|
6416 |
|
|
}
|
6417 |
|
|
device->queue_depth = default_depth;
|
6418 |
|
|
}
|
6419 |
|
|
else
|
6420 |
|
|
{
|
6421 |
|
|
|
6422 |
|
|
if (aic7xxx_tag_info[p->instance].tag_commands[tindex] == 255)
|
6423 |
|
|
{
|
6424 |
|
|
tag_enabled = FALSE;
|
6425 |
|
|
device->queue_depth = 3; /* Tagged queueing is disabled. */
|
6426 |
|
|
}
|
6427 |
|
|
else if (aic7xxx_tag_info[p->instance].tag_commands[tindex] == 0)
|
6428 |
|
|
{
|
6429 |
|
|
device->queue_depth = default_depth;
|
6430 |
|
|
}
|
6431 |
|
|
else
|
6432 |
|
|
{
|
6433 |
|
|
device->queue_depth =
|
6434 |
|
|
aic7xxx_tag_info[p->instance].tag_commands[tindex];
|
6435 |
|
|
}
|
6436 |
|
|
}
|
6437 |
|
|
if ((device->tagged_queue == 0) && tag_enabled)
|
6438 |
|
|
{
|
6439 |
|
|
if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
|
6440 |
|
|
{
|
6441 |
|
|
printk(INFO_LEAD "Enabled tagged queuing, queue depth %d.\n",
|
6442 |
|
|
p->host_no, device->channel, device->id,
|
6443 |
|
|
device->lun, device->queue_depth);
|
6444 |
|
|
}
|
6445 |
|
|
p->dev_max_queue_depth[tindex] = device->queue_depth;
|
6446 |
|
|
p->dev_temp_queue_depth[tindex] = device->queue_depth;
|
6447 |
|
|
p->tagenable |= target_mask;
|
6448 |
|
|
p->orderedtag |= target_mask;
|
6449 |
|
|
device->tagged_queue = 1;
|
6450 |
|
|
device->current_tag = SCB_LIST_NULL;
|
6451 |
|
|
}
|
6452 |
|
|
}
|
6453 |
|
|
}
|
6454 |
|
|
}
|
6455 |
|
|
|
6456 |
|
|
/*+F*************************************************************************
|
6457 |
|
|
* Function:
|
6458 |
|
|
* aic7xxx_select_queue_depth
|
6459 |
|
|
*
|
6460 |
|
|
* Description:
|
6461 |
|
|
* Sets the queue depth for each SCSI device hanging off the input
|
6462 |
|
|
* host adapter. We use a queue depth of 2 for devices that do not
|
6463 |
|
|
* support tagged queueing. If AIC7XXX_CMDS_PER_LUN is defined, we
|
6464 |
|
|
* use that for tagged queueing devices; otherwise we use our own
|
6465 |
|
|
* algorithm for determining the queue depth based on the maximum
|
6466 |
|
|
* SCBs for the controller.
|
6467 |
|
|
*-F*************************************************************************/
|
6468 |
|
|
static void
|
6469 |
|
|
aic7xxx_select_queue_depth(struct Scsi_Host *host,
|
6470 |
|
|
Scsi_Device *scsi_devs)
|
6471 |
|
|
{
|
6472 |
|
|
Scsi_Device *device;
|
6473 |
|
|
struct aic7xxx_host *p = (struct aic7xxx_host *) host->hostdata;
|
6474 |
|
|
int scbnum;
|
6475 |
|
|
|
6476 |
|
|
scbnum = 0;
|
6477 |
|
|
for (device = scsi_devs; device != NULL; device = device->next)
|
6478 |
|
|
{
|
6479 |
|
|
if (device->host == host)
|
6480 |
|
|
{
|
6481 |
|
|
aic7xxx_device_queue_depth(p, device);
|
6482 |
|
|
scbnum += device->queue_depth;
|
6483 |
|
|
}
|
6484 |
|
|
}
|
6485 |
|
|
while (scbnum > p->scb_data->numscbs)
|
6486 |
|
|
{
|
6487 |
|
|
/*
|
6488 |
|
|
* Pre-allocate the needed SCBs to get around the possibility of having
|
6489 |
|
|
* to allocate some when memory is more or less exhausted and we need
|
6490 |
|
|
* the SCB in order to perform a swap operation (possible deadlock)
|
6491 |
|
|
*/
|
6492 |
|
|
if ( aic7xxx_allocate_scb(p) == 0 )
|
6493 |
|
|
return;
|
6494 |
|
|
}
|
6495 |
|
|
}
|
6496 |
|
|
|
6497 |
|
|
/*+F*************************************************************************
|
6498 |
|
|
* Function:
|
6499 |
|
|
* aic7xxx_probe
|
6500 |
|
|
*
|
6501 |
|
|
* Description:
|
6502 |
|
|
* Probing for EISA boards: it looks like the first two bytes
|
6503 |
|
|
* are a manufacturer code - three characters, five bits each:
|
6504 |
|
|
*
|
6505 |
|
|
* BYTE 0 BYTE 1 BYTE 2 BYTE 3
|
6506 |
|
|
* ?1111122 22233333 PPPPPPPP RRRRRRRR
|
6507 |
|
|
*
|
6508 |
|
|
* The characters are baselined off ASCII '@', so add that value
|
6509 |
|
|
* to each to get the real ASCII code for it. The next two bytes
|
6510 |
|
|
* appear to be a product and revision number, probably vendor-
|
6511 |
|
|
* specific. This is what is being searched for at each port,
|
6512 |
|
|
* and what should probably correspond to the ID= field in the
|
6513 |
|
|
* ECU's .cfg file for the card - if your card is not detected,
|
6514 |
|
|
* make sure your signature is listed in the array.
|
6515 |
|
|
*
|
6516 |
|
|
* The fourth byte's lowest bit seems to be an enabled/disabled
|
6517 |
|
|
* flag (rest of the bits are reserved?).
|
6518 |
|
|
*
|
6519 |
|
|
* NOTE: This function is only needed on Intel and Alpha platforms,
|
6520 |
|
|
* the other platforms we support don't have EISA/VLB busses. So,
|
6521 |
|
|
* we #ifdef this entire function to avoid compiler warnings about
|
6522 |
|
|
* an unused function.
|
6523 |
|
|
*-F*************************************************************************/
|
6524 |
|
|
#if defined(__i386__) || defined(__alpha__)
|
6525 |
|
|
static int
|
6526 |
|
|
aic7xxx_probe(int slot, int base, ahc_flag_type *flags)
|
6527 |
|
|
{
|
6528 |
|
|
int i;
|
6529 |
|
|
unsigned char buf[4];
|
6530 |
|
|
|
6531 |
|
|
static struct {
|
6532 |
|
|
int n;
|
6533 |
|
|
unsigned char signature[sizeof(buf)];
|
6534 |
|
|
ahc_chip type;
|
6535 |
|
|
int bios_disabled;
|
6536 |
|
|
} AIC7xxx[] = {
|
6537 |
|
|
{ 4, { 0x04, 0x90, 0x77, 0x70 },
|
6538 |
|
|
AHC_AIC7770|AHC_EISA, FALSE }, /* mb 7770 */
|
6539 |
|
|
{ 4, { 0x04, 0x90, 0x77, 0x71 },
|
6540 |
|
|
AHC_AIC7770|AHC_EISA, FALSE }, /* host adapter 274x */
|
6541 |
|
|
{ 4, { 0x04, 0x90, 0x77, 0x56 },
|
6542 |
|
|
AHC_AIC7770|AHC_VL, FALSE }, /* 284x BIOS enabled */
|
6543 |
|
|
{ 4, { 0x04, 0x90, 0x77, 0x57 },
|
6544 |
|
|
AHC_AIC7770|AHC_VL, TRUE } /* 284x BIOS disabled */
|
6545 |
|
|
};
|
6546 |
|
|
|
6547 |
|
|
/*
|
6548 |
|
|
* The VL-bus cards need to be primed by
|
6549 |
|
|
* writing before a signature check.
|
6550 |
|
|
*/
|
6551 |
|
|
for (i = 0; i < sizeof(buf); i++)
|
6552 |
|
|
{
|
6553 |
|
|
outb(0x80 + i, base);
|
6554 |
|
|
buf[i] = inb(base + i);
|
6555 |
|
|
}
|
6556 |
|
|
|
6557 |
|
|
for (i = 0; i < NUMBER(AIC7xxx); i++)
|
6558 |
|
|
{
|
6559 |
|
|
/*
|
6560 |
|
|
* Signature match on enabled card?
|
6561 |
|
|
*/
|
6562 |
|
|
if (!memcmp(buf, AIC7xxx[i].signature, AIC7xxx[i].n))
|
6563 |
|
|
{
|
6564 |
|
|
if (inb(base + 4) & 1)
|
6565 |
|
|
{
|
6566 |
|
|
if (AIC7xxx[i].bios_disabled)
|
6567 |
|
|
{
|
6568 |
|
|
*flags |= AHC_USEDEFAULTS;
|
6569 |
|
|
}
|
6570 |
|
|
else
|
6571 |
|
|
{
|
6572 |
|
|
*flags |= AHC_BIOS_ENABLED;
|
6573 |
|
|
}
|
6574 |
|
|
return (i);
|
6575 |
|
|
}
|
6576 |
|
|
|
6577 |
|
|
printk("aic7xxx: <Adaptec 7770 SCSI Host Adapter> "
|
6578 |
|
|
"disabled at slot %d, ignored.\n", slot);
|
6579 |
|
|
}
|
6580 |
|
|
}
|
6581 |
|
|
|
6582 |
|
|
return (-1);
|
6583 |
|
|
}
|
6584 |
|
|
#endif /* (__i386__) || (__alpha__) */
|
6585 |
|
|
|
6586 |
|
|
|
6587 |
|
|
/*+F*************************************************************************
|
6588 |
|
|
* Function:
|
6589 |
|
|
* read_2840_seeprom
|
6590 |
|
|
*
|
6591 |
|
|
* Description:
|
6592 |
|
|
* Reads the 2840 serial EEPROM and returns 1 if successful and 0 if
|
6593 |
|
|
* not successful.
|
6594 |
|
|
*
|
6595 |
|
|
* See read_seeprom (for the 2940) for the instruction set of the 93C46
|
6596 |
|
|
* chip.
|
6597 |
|
|
*
|
6598 |
|
|
* The 2840 interface to the 93C46 serial EEPROM is through the
|
6599 |
|
|
* STATUS_2840 and SEECTL_2840 registers. The CS_2840, CK_2840, and
|
6600 |
|
|
* DO_2840 bits of the SEECTL_2840 register are connected to the chip
|
6601 |
|
|
* select, clock, and data out lines respectively of the serial EEPROM.
|
6602 |
|
|
* The DI_2840 bit of the STATUS_2840 is connected to the data in line
|
6603 |
|
|
* of the serial EEPROM. The EEPROM_TF bit of STATUS_2840 register is
|
6604 |
|
|
* useful in that it gives us an 800 nsec timer. After a read from the
|
6605 |
|
|
* SEECTL_2840 register the timing flag is cleared and goes high 800 nsec
|
6606 |
|
|
* later.
|
6607 |
|
|
*-F*************************************************************************/
|
6608 |
|
|
static int
|
6609 |
|
|
read_284x_seeprom(struct aic7xxx_host *p, struct seeprom_config *sc)
|
6610 |
|
|
{
|
6611 |
|
|
int i = 0, k = 0;
|
6612 |
|
|
unsigned char temp;
|
6613 |
|
|
unsigned short checksum = 0;
|
6614 |
|
|
unsigned short *seeprom = (unsigned short *) sc;
|
6615 |
|
|
struct seeprom_cmd {
|
6616 |
|
|
unsigned char len;
|
6617 |
|
|
unsigned char bits[3];
|
6618 |
|
|
};
|
6619 |
|
|
struct seeprom_cmd seeprom_read = {3, {1, 1, 0}};
|
6620 |
|
|
|
6621 |
|
|
#define CLOCK_PULSE(p) \
|
6622 |
|
|
while ((aic_inb(p, STATUS_2840) & EEPROM_TF) == 0) \
|
6623 |
|
|
{ \
|
6624 |
|
|
; /* Do nothing */ \
|
6625 |
|
|
} \
|
6626 |
|
|
(void) aic_inb(p, SEECTL_2840);
|
6627 |
|
|
|
6628 |
|
|
/*
|
6629 |
|
|
* Read the first 32 registers of the seeprom. For the 2840,
|
6630 |
|
|
* the 93C46 SEEPROM is a 1024-bit device with 64 16-bit registers
|
6631 |
|
|
* but only the first 32 are used by Adaptec BIOS. The loop
|
6632 |
|
|
* will range from 0 to 31.
|
6633 |
|
|
*/
|
6634 |
|
|
for (k = 0; k < (sizeof(*sc) / 2); k++)
|
6635 |
|
|
{
|
6636 |
|
|
/*
|
6637 |
|
|
* Send chip select for one clock cycle.
|
6638 |
|
|
*/
|
6639 |
|
|
aic_outb(p, CK_2840 | CS_2840, SEECTL_2840);
|
6640 |
|
|
CLOCK_PULSE(p);
|
6641 |
|
|
|
6642 |
|
|
/*
|
6643 |
|
|
* Now we're ready to send the read command followed by the
|
6644 |
|
|
* address of the 16-bit register we want to read.
|
6645 |
|
|
*/
|
6646 |
|
|
for (i = 0; i < seeprom_read.len; i++)
|
6647 |
|
|
{
|
6648 |
|
|
temp = CS_2840 | seeprom_read.bits[i];
|
6649 |
|
|
aic_outb(p, temp, SEECTL_2840);
|
6650 |
|
|
CLOCK_PULSE(p);
|
6651 |
|
|
temp = temp ^ CK_2840;
|
6652 |
|
|
aic_outb(p, temp, SEECTL_2840);
|
6653 |
|
|
CLOCK_PULSE(p);
|
6654 |
|
|
}
|
6655 |
|
|
/*
|
6656 |
|
|
* Send the 6 bit address (MSB first, LSB last).
|
6657 |
|
|
*/
|
6658 |
|
|
for (i = 5; i >= 0; i--)
|
6659 |
|
|
{
|
6660 |
|
|
temp = k;
|
6661 |
|
|
temp = (temp >> i) & 1; /* Mask out all but lower bit. */
|
6662 |
|
|
temp = CS_2840 | temp;
|
6663 |
|
|
aic_outb(p, temp, SEECTL_2840);
|
6664 |
|
|
CLOCK_PULSE(p);
|
6665 |
|
|
temp = temp ^ CK_2840;
|
6666 |
|
|
aic_outb(p, temp, SEECTL_2840);
|
6667 |
|
|
CLOCK_PULSE(p);
|
6668 |
|
|
}
|
6669 |
|
|
|
6670 |
|
|
/*
|
6671 |
|
|
* Now read the 16 bit register. An initial 0 precedes the
|
6672 |
|
|
* register contents which begins with bit 15 (MSB) and ends
|
6673 |
|
|
* with bit 0 (LSB). The initial 0 will be shifted off the
|
6674 |
|
|
* top of our word as we let the loop run from 0 to 16.
|
6675 |
|
|
*/
|
6676 |
|
|
for (i = 0; i <= 16; i++)
|
6677 |
|
|
{
|
6678 |
|
|
temp = CS_2840;
|
6679 |
|
|
aic_outb(p, temp, SEECTL_2840);
|
6680 |
|
|
CLOCK_PULSE(p);
|
6681 |
|
|
temp = temp ^ CK_2840;
|
6682 |
|
|
seeprom[k] = (seeprom[k] << 1) | (aic_inb(p, STATUS_2840) & DI_2840);
|
6683 |
|
|
aic_outb(p, temp, SEECTL_2840);
|
6684 |
|
|
CLOCK_PULSE(p);
|
6685 |
|
|
}
|
6686 |
|
|
/*
|
6687 |
|
|
* The serial EEPROM has a checksum in the last word. Keep a
|
6688 |
|
|
* running checksum for all words read except for the last
|
6689 |
|
|
* word. We'll verify the checksum after all words have been
|
6690 |
|
|
* read.
|
6691 |
|
|
*/
|
6692 |
|
|
if (k < (sizeof(*sc) / 2) - 1)
|
6693 |
|
|
{
|
6694 |
|
|
checksum = checksum + seeprom[k];
|
6695 |
|
|
}
|
6696 |
|
|
|
6697 |
|
|
/*
|
6698 |
|
|
* Reset the chip select for the next command cycle.
|
6699 |
|
|
*/
|
6700 |
|
|
aic_outb(p, 0, SEECTL_2840);
|
6701 |
|
|
CLOCK_PULSE(p);
|
6702 |
|
|
aic_outb(p, CK_2840, SEECTL_2840);
|
6703 |
|
|
CLOCK_PULSE(p);
|
6704 |
|
|
aic_outb(p, 0, SEECTL_2840);
|
6705 |
|
|
CLOCK_PULSE(p);
|
6706 |
|
|
}
|
6707 |
|
|
|
6708 |
|
|
#if 0
|
6709 |
|
|
printk("Computed checksum 0x%x, checksum read 0x%x\n", checksum, sc->checksum);
|
6710 |
|
|
printk("Serial EEPROM:");
|
6711 |
|
|
for (k = 0; k < (sizeof(*sc) / 2); k++)
|
6712 |
|
|
{
|
6713 |
|
|
if (((k % 8) == 0) && (k != 0))
|
6714 |
|
|
{
|
6715 |
|
|
printk("\n ");
|
6716 |
|
|
}
|
6717 |
|
|
printk(" 0x%x", seeprom[k]);
|
6718 |
|
|
}
|
6719 |
|
|
printk("\n");
|
6720 |
|
|
#endif
|
6721 |
|
|
|
6722 |
|
|
if (checksum != sc->checksum)
|
6723 |
|
|
{
|
6724 |
|
|
printk("aic7xxx: SEEPROM checksum error, ignoring SEEPROM settings.\n");
|
6725 |
|
|
return (0);
|
6726 |
|
|
}
|
6727 |
|
|
|
6728 |
|
|
return (1);
|
6729 |
|
|
#undef CLOCK_PULSE
|
6730 |
|
|
}
|
6731 |
|
|
|
6732 |
|
|
/*+F*************************************************************************
|
6733 |
|
|
* Function:
|
6734 |
|
|
* acquire_seeprom
|
6735 |
|
|
*
|
6736 |
|
|
* Description:
|
6737 |
|
|
* Acquires access to the memory port on PCI controllers.
|
6738 |
|
|
*-F*************************************************************************/
|
6739 |
|
|
static int
|
6740 |
|
|
acquire_seeprom(struct aic7xxx_host *p)
|
6741 |
|
|
{
|
6742 |
|
|
int wait;
|
6743 |
|
|
|
6744 |
|
|
/*
|
6745 |
|
|
* Request access of the memory port. When access is
|
6746 |
|
|
* granted, SEERDY will go high. We use a 1 second
|
6747 |
|
|
* timeout which should be near 1 second more than
|
6748 |
|
|
* is needed. Reason: after the 7870 chip reset, there
|
6749 |
|
|
* should be no contention.
|
6750 |
|
|
*/
|
6751 |
|
|
aic_outb(p, SEEMS, SEECTL);
|
6752 |
|
|
wait = 1000; /* 1000 msec = 1 second */
|
6753 |
|
|
while ((wait > 0) && ((aic_inb(p, SEECTL) & SEERDY) == 0))
|
6754 |
|
|
{
|
6755 |
|
|
wait--;
|
6756 |
|
|
mdelay(1); /* 1 msec */
|
6757 |
|
|
}
|
6758 |
|
|
if ((aic_inb(p, SEECTL) & SEERDY) == 0)
|
6759 |
|
|
{
|
6760 |
|
|
aic_outb(p, 0, SEECTL);
|
6761 |
|
|
return (0);
|
6762 |
|
|
}
|
6763 |
|
|
return (1);
|
6764 |
|
|
}
|
6765 |
|
|
|
6766 |
|
|
/*+F*************************************************************************
|
6767 |
|
|
* Function:
|
6768 |
|
|
* release_seeprom
|
6769 |
|
|
*
|
6770 |
|
|
* Description:
|
6771 |
|
|
* Releases access to the memory port on PCI controllers.
|
6772 |
|
|
*-F*************************************************************************/
|
6773 |
|
|
static void
|
6774 |
|
|
release_seeprom(struct aic7xxx_host *p)
|
6775 |
|
|
{
|
6776 |
|
|
aic_outb(p, 0, SEECTL);
|
6777 |
|
|
}
|
6778 |
|
|
|
6779 |
|
|
/*+F*************************************************************************
|
6780 |
|
|
* Function:
|
6781 |
|
|
* read_seeprom
|
6782 |
|
|
*
|
6783 |
|
|
* Description:
|
6784 |
|
|
* Reads the serial EEPROM and returns 1 if successful and 0 if
|
6785 |
|
|
* not successful.
|
6786 |
|
|
*
|
6787 |
|
|
* The instruction set of the 93C46/56/66 chips is as follows:
|
6788 |
|
|
*
|
6789 |
|
|
* Start OP
|
6790 |
|
|
* Function Bit Code Address Data Description
|
6791 |
|
|
* -------------------------------------------------------------------
|
6792 |
|
|
* READ 1 10 A5 - A0 Reads data stored in memory,
|
6793 |
|
|
* starting at specified address
|
6794 |
|
|
* EWEN 1 00 11XXXX Write enable must precede
|
6795 |
|
|
* all programming modes
|
6796 |
|
|
* ERASE 1 11 A5 - A0 Erase register A5A4A3A2A1A0
|
6797 |
|
|
* WRITE 1 01 A5 - A0 D15 - D0 Writes register
|
6798 |
|
|
* ERAL 1 00 10XXXX Erase all registers
|
6799 |
|
|
* WRAL 1 00 01XXXX D15 - D0 Writes to all registers
|
6800 |
|
|
* EWDS 1 00 00XXXX Disables all programming
|
6801 |
|
|
* instructions
|
6802 |
|
|
* *Note: A value of X for address is a don't care condition.
|
6803 |
|
|
* *Note: The 93C56 and 93C66 have 8 address bits.
|
6804 |
|
|
*
|
6805 |
|
|
*
|
6806 |
|
|
* The 93C46 has a four wire interface: clock, chip select, data in, and
|
6807 |
|
|
* data out. In order to perform one of the above functions, you need
|
6808 |
|
|
* to enable the chip select for a clock period (typically a minimum of
|
6809 |
|
|
* 1 usec, with the clock high and low a minimum of 750 and 250 nsec
|
6810 |
|
|
* respectively. While the chip select remains high, you can clock in
|
6811 |
|
|
* the instructions (above) starting with the start bit, followed by the
|
6812 |
|
|
* OP code, Address, and Data (if needed). For the READ instruction, the
|
6813 |
|
|
* requested 16-bit register contents is read from the data out line but
|
6814 |
|
|
* is preceded by an initial zero (leading 0, followed by 16-bits, MSB
|
6815 |
|
|
* first). The clock cycling from low to high initiates the next data
|
6816 |
|
|
* bit to be sent from the chip.
|
6817 |
|
|
*
|
6818 |
|
|
* The 78xx interface to the 93C46 serial EEPROM is through the SEECTL
|
6819 |
|
|
* register. After successful arbitration for the memory port, the
|
6820 |
|
|
* SEECS bit of the SEECTL register is connected to the chip select.
|
6821 |
|
|
* The SEECK, SEEDO, and SEEDI are connected to the clock, data out,
|
6822 |
|
|
* and data in lines respectively. The SEERDY bit of SEECTL is useful
|
6823 |
|
|
* in that it gives us an 800 nsec timer. After a write to the SEECTL
|
6824 |
|
|
* register, the SEERDY goes high 800 nsec later. The one exception
|
6825 |
|
|
* to this is when we first request access to the memory port. The
|
6826 |
|
|
* SEERDY goes high to signify that access has been granted and, for
|
6827 |
|
|
* this case, has no implied timing.
|
6828 |
|
|
*-F*************************************************************************/
|
6829 |
|
|
static int
|
6830 |
|
|
read_seeprom(struct aic7xxx_host *p, int offset,
|
6831 |
|
|
unsigned short *scarray, unsigned int len, seeprom_chip_type chip)
|
6832 |
|
|
{
|
6833 |
|
|
int i = 0, k;
|
6834 |
|
|
unsigned char temp;
|
6835 |
|
|
unsigned short checksum = 0;
|
6836 |
|
|
struct seeprom_cmd {
|
6837 |
|
|
unsigned char len;
|
6838 |
|
|
unsigned char bits[3];
|
6839 |
|
|
};
|
6840 |
|
|
struct seeprom_cmd seeprom_read = {3, {1, 1, 0}};
|
6841 |
|
|
|
6842 |
|
|
#define CLOCK_PULSE(p) \
|
6843 |
|
|
while ((aic_inb(p, SEECTL) & SEERDY) == 0) \
|
6844 |
|
|
{ \
|
6845 |
|
|
; /* Do nothing */ \
|
6846 |
|
|
}
|
6847 |
|
|
|
6848 |
|
|
/*
|
6849 |
|
|
* Request access of the memory port.
|
6850 |
|
|
*/
|
6851 |
|
|
if (acquire_seeprom(p) == 0)
|
6852 |
|
|
{
|
6853 |
|
|
return (0);
|
6854 |
|
|
}
|
6855 |
|
|
|
6856 |
|
|
/*
|
6857 |
|
|
* Read 'len' registers of the seeprom. For the 7870, the 93C46
|
6858 |
|
|
* SEEPROM is a 1024-bit device with 64 16-bit registers but only
|
6859 |
|
|
* the first 32 are used by Adaptec BIOS. Some adapters use the
|
6860 |
|
|
* 93C56 SEEPROM which is a 2048-bit device. The loop will range
|
6861 |
|
|
* from 0 to 'len' - 1.
|
6862 |
|
|
*/
|
6863 |
|
|
for (k = 0; k < len; k++)
|
6864 |
|
|
{
|
6865 |
|
|
/*
|
6866 |
|
|
* Send chip select for one clock cycle.
|
6867 |
|
|
*/
|
6868 |
|
|
aic_outb(p, SEEMS | SEECK | SEECS, SEECTL);
|
6869 |
|
|
CLOCK_PULSE(p);
|
6870 |
|
|
|
6871 |
|
|
/*
|
6872 |
|
|
* Now we're ready to send the read command followed by the
|
6873 |
|
|
* address of the 16-bit register we want to read.
|
6874 |
|
|
*/
|
6875 |
|
|
for (i = 0; i < seeprom_read.len; i++)
|
6876 |
|
|
{
|
6877 |
|
|
temp = SEEMS | SEECS | (seeprom_read.bits[i] << 1);
|
6878 |
|
|
aic_outb(p, temp, SEECTL);
|
6879 |
|
|
CLOCK_PULSE(p);
|
6880 |
|
|
temp = temp ^ SEECK;
|
6881 |
|
|
aic_outb(p, temp, SEECTL);
|
6882 |
|
|
CLOCK_PULSE(p);
|
6883 |
|
|
}
|
6884 |
|
|
/*
|
6885 |
|
|
* Send the 6 or 8 bit address (MSB first, LSB last).
|
6886 |
|
|
*/
|
6887 |
|
|
for (i = ((int) chip - 1); i >= 0; i--)
|
6888 |
|
|
{
|
6889 |
|
|
temp = k + offset;
|
6890 |
|
|
temp = (temp >> i) & 1; /* Mask out all but lower bit. */
|
6891 |
|
|
temp = SEEMS | SEECS | (temp << 1);
|
6892 |
|
|
aic_outb(p, temp, SEECTL);
|
6893 |
|
|
CLOCK_PULSE(p);
|
6894 |
|
|
temp = temp ^ SEECK;
|
6895 |
|
|
aic_outb(p, temp, SEECTL);
|
6896 |
|
|
CLOCK_PULSE(p);
|
6897 |
|
|
}
|
6898 |
|
|
|
6899 |
|
|
/*
|
6900 |
|
|
* Now read the 16 bit register. An initial 0 precedes the
|
6901 |
|
|
* register contents which begins with bit 15 (MSB) and ends
|
6902 |
|
|
* with bit 0 (LSB). The initial 0 will be shifted off the
|
6903 |
|
|
* top of our word as we let the loop run from 0 to 16.
|
6904 |
|
|
*/
|
6905 |
|
|
for (i = 0; i <= 16; i++)
|
6906 |
|
|
{
|
6907 |
|
|
temp = SEEMS | SEECS;
|
6908 |
|
|
aic_outb(p, temp, SEECTL);
|
6909 |
|
|
CLOCK_PULSE(p);
|
6910 |
|
|
temp = temp ^ SEECK;
|
6911 |
|
|
scarray[k] = (scarray[k] << 1) | (aic_inb(p, SEECTL) & SEEDI);
|
6912 |
|
|
aic_outb(p, temp, SEECTL);
|
6913 |
|
|
CLOCK_PULSE(p);
|
6914 |
|
|
}
|
6915 |
|
|
|
6916 |
|
|
/*
|
6917 |
|
|
* The serial EEPROM should have a checksum in the last word.
|
6918 |
|
|
* Keep a running checksum for all words read except for the
|
6919 |
|
|
* last word. We'll verify the checksum after all words have
|
6920 |
|
|
* been read.
|
6921 |
|
|
*/
|
6922 |
|
|
if (k < (len - 1))
|
6923 |
|
|
{
|
6924 |
|
|
checksum = checksum + scarray[k];
|
6925 |
|
|
}
|
6926 |
|
|
|
6927 |
|
|
/*
|
6928 |
|
|
* Reset the chip select for the next command cycle.
|
6929 |
|
|
*/
|
6930 |
|
|
aic_outb(p, SEEMS, SEECTL);
|
6931 |
|
|
CLOCK_PULSE(p);
|
6932 |
|
|
aic_outb(p, SEEMS | SEECK, SEECTL);
|
6933 |
|
|
CLOCK_PULSE(p);
|
6934 |
|
|
aic_outb(p, SEEMS, SEECTL);
|
6935 |
|
|
CLOCK_PULSE(p);
|
6936 |
|
|
}
|
6937 |
|
|
|
6938 |
|
|
/*
|
6939 |
|
|
* Release access to the memory port and the serial EEPROM.
|
6940 |
|
|
*/
|
6941 |
|
|
release_seeprom(p);
|
6942 |
|
|
|
6943 |
|
|
#if 0
|
6944 |
|
|
printk("Computed checksum 0x%x, checksum read 0x%x\n",
|
6945 |
|
|
checksum, scarray[len - 1]);
|
6946 |
|
|
printk("Serial EEPROM:");
|
6947 |
|
|
for (k = 0; k < len; k++)
|
6948 |
|
|
{
|
6949 |
|
|
if (((k % 8) == 0) && (k != 0))
|
6950 |
|
|
{
|
6951 |
|
|
printk("\n ");
|
6952 |
|
|
}
|
6953 |
|
|
printk(" 0x%x", scarray[k]);
|
6954 |
|
|
}
|
6955 |
|
|
printk("\n");
|
6956 |
|
|
#endif
|
6957 |
|
|
if ( (checksum != scarray[len - 1]) || (checksum == 0) )
|
6958 |
|
|
{
|
6959 |
|
|
return (0);
|
6960 |
|
|
}
|
6961 |
|
|
|
6962 |
|
|
return (1);
|
6963 |
|
|
#undef CLOCK_PULSE
|
6964 |
|
|
}
|
6965 |
|
|
|
6966 |
|
|
/*+F*************************************************************************
|
6967 |
|
|
* Function:
|
6968 |
|
|
* write_brdctl
|
6969 |
|
|
*
|
6970 |
|
|
* Description:
|
6971 |
|
|
* Writes a value to the BRDCTL register.
|
6972 |
|
|
*-F*************************************************************************/
|
6973 |
|
|
static void
|
6974 |
|
|
write_brdctl(struct aic7xxx_host *p, unsigned char value)
|
6975 |
|
|
{
|
6976 |
|
|
unsigned char brdctl;
|
6977 |
|
|
|
6978 |
|
|
if ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895)
|
6979 |
|
|
{
|
6980 |
|
|
brdctl = BRDSTB;
|
6981 |
|
|
if (p->flags & AHC_CHNLB)
|
6982 |
|
|
brdctl |= BRDCS;
|
6983 |
|
|
}
|
6984 |
|
|
else if (p->features & AHC_ULTRA2)
|
6985 |
|
|
brdctl = 0;
|
6986 |
|
|
else
|
6987 |
|
|
brdctl = BRDSTB | BRDCS;
|
6988 |
|
|
aic_outb(p, brdctl, BRDCTL);
|
6989 |
|
|
udelay(1);
|
6990 |
|
|
brdctl |= value;
|
6991 |
|
|
aic_outb(p, brdctl, BRDCTL);
|
6992 |
|
|
udelay(1);
|
6993 |
|
|
if (p->features & AHC_ULTRA2)
|
6994 |
|
|
brdctl |= BRDSTB_ULTRA2;
|
6995 |
|
|
else
|
6996 |
|
|
brdctl &= ~BRDSTB;
|
6997 |
|
|
aic_outb(p, brdctl, BRDCTL);
|
6998 |
|
|
udelay(1);
|
6999 |
|
|
if (p->features & AHC_ULTRA2)
|
7000 |
|
|
brdctl = 0;
|
7001 |
|
|
else
|
7002 |
|
|
brdctl &= ~BRDCS;
|
7003 |
|
|
aic_outb(p, brdctl, BRDCTL);
|
7004 |
|
|
udelay(1);
|
7005 |
|
|
}
|
7006 |
|
|
|
7007 |
|
|
/*+F*************************************************************************
|
7008 |
|
|
* Function:
|
7009 |
|
|
* read_brdctl
|
7010 |
|
|
*
|
7011 |
|
|
* Description:
|
7012 |
|
|
* Reads the BRDCTL register.
|
7013 |
|
|
*-F*************************************************************************/
|
7014 |
|
|
static unsigned char
|
7015 |
|
|
read_brdctl(struct aic7xxx_host *p)
|
7016 |
|
|
{
|
7017 |
|
|
unsigned char brdctl, value;
|
7018 |
|
|
|
7019 |
|
|
if ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895)
|
7020 |
|
|
{
|
7021 |
|
|
brdctl = BRDRW;
|
7022 |
|
|
if (p->flags & AHC_CHNLB)
|
7023 |
|
|
brdctl |= BRDCS;
|
7024 |
|
|
}
|
7025 |
|
|
else if (p->features & AHC_ULTRA2)
|
7026 |
|
|
brdctl = BRDRW_ULTRA2;
|
7027 |
|
|
else
|
7028 |
|
|
brdctl = BRDRW | BRDCS;
|
7029 |
|
|
aic_outb(p, brdctl, BRDCTL);
|
7030 |
|
|
udelay(1);
|
7031 |
|
|
value = aic_inb(p, BRDCTL);
|
7032 |
|
|
aic_outb(p, 0, BRDCTL);
|
7033 |
|
|
udelay(1);
|
7034 |
|
|
return (value);
|
7035 |
|
|
}
|
7036 |
|
|
|
7037 |
|
|
/*+F*************************************************************************
|
7038 |
|
|
* Function:
|
7039 |
|
|
* aic785x_cable_detect
|
7040 |
|
|
*
|
7041 |
|
|
* Description:
|
7042 |
|
|
* Detect the cables that are present on aic785x class controller chips
|
7043 |
|
|
*-F*************************************************************************/
|
7044 |
|
|
static void
|
7045 |
|
|
aic785x_cable_detect(struct aic7xxx_host *p, int *int_50,
|
7046 |
|
|
int *ext_present, int *eeprom)
|
7047 |
|
|
{
|
7048 |
|
|
unsigned char brdctl;
|
7049 |
|
|
|
7050 |
|
|
aic_outb(p, BRDRW | BRDCS, BRDCTL);
|
7051 |
|
|
udelay(1);
|
7052 |
|
|
aic_outb(p, 0, BRDCTL);
|
7053 |
|
|
udelay(1);
|
7054 |
|
|
brdctl = aic_inb(p, BRDCTL);
|
7055 |
|
|
udelay(1);
|
7056 |
|
|
*int_50 = !(brdctl & BRDDAT5);
|
7057 |
|
|
*ext_present = !(brdctl & BRDDAT6);
|
7058 |
|
|
*eeprom = (aic_inb(p, SPIOCAP) & EEPROM);
|
7059 |
|
|
}
|
7060 |
|
|
|
7061 |
|
|
/*+F*************************************************************************
|
7062 |
|
|
* Function:
|
7063 |
|
|
* aic787x_cable_detect
|
7064 |
|
|
*
|
7065 |
|
|
* Description:
|
7066 |
|
|
* Detect the cables that are present on aic787x class controller chips
|
7067 |
|
|
*
|
7068 |
|
|
* NOTE: This functions assumes the SEEPROM will have already been aquired
|
7069 |
|
|
* prior to invocation of this function.
|
7070 |
|
|
*-F*************************************************************************/
|
7071 |
|
|
static void
|
7072 |
|
|
aic787x_cable_detect(struct aic7xxx_host *p, int *int_50, int *int_68,
|
7073 |
|
|
int *ext_present, int *eeprom)
|
7074 |
|
|
{
|
7075 |
|
|
unsigned char brdctl;
|
7076 |
|
|
|
7077 |
|
|
/*
|
7078 |
|
|
* First read the status of our cables. Set the rom bank to
|
7079 |
|
|
* 0 since the bank setting serves as a multiplexor for the
|
7080 |
|
|
* cable detection logic. BRDDAT5 controls the bank switch.
|
7081 |
|
|
*/
|
7082 |
|
|
write_brdctl(p, 0);
|
7083 |
|
|
|
7084 |
|
|
/*
|
7085 |
|
|
* Now we read the state of the two internal connectors. BRDDAT6
|
7086 |
|
|
* is internal 50, BRDDAT7 is internal 68. For each, the cable is
|
7087 |
|
|
* present if the bit is 0
|
7088 |
|
|
*/
|
7089 |
|
|
brdctl = read_brdctl(p);
|
7090 |
|
|
*int_50 = !(brdctl & BRDDAT6);
|
7091 |
|
|
*int_68 = !(brdctl & BRDDAT7);
|
7092 |
|
|
|
7093 |
|
|
/*
|
7094 |
|
|
* Set the bank bit in brdctl and then read the external cable state
|
7095 |
|
|
* and the EEPROM status
|
7096 |
|
|
*/
|
7097 |
|
|
write_brdctl(p, BRDDAT5);
|
7098 |
|
|
brdctl = read_brdctl(p);
|
7099 |
|
|
|
7100 |
|
|
*ext_present = !(brdctl & BRDDAT6);
|
7101 |
|
|
*eeprom = !(brdctl & BRDDAT7);
|
7102 |
|
|
|
7103 |
|
|
/*
|
7104 |
|
|
* We're done, the calling function will release the SEEPROM for us
|
7105 |
|
|
*/
|
7106 |
|
|
}
|
7107 |
|
|
|
7108 |
|
|
/*+F*************************************************************************
|
7109 |
|
|
* Function:
|
7110 |
|
|
* aic787x_ultra2_term_detect
|
7111 |
|
|
*
|
7112 |
|
|
* Description:
|
7113 |
|
|
* Detect the termination settings present on ultra2 class controllers
|
7114 |
|
|
*
|
7115 |
|
|
* NOTE: This functions assumes the SEEPROM will have already been aquired
|
7116 |
|
|
* prior to invocation of this function.
|
7117 |
|
|
*-F*************************************************************************/
|
7118 |
|
|
static void
|
7119 |
|
|
aic7xxx_ultra2_term_detect(struct aic7xxx_host *p, int *enableSE_low,
|
7120 |
|
|
int *enableSE_high, int *enableLVD_low,
|
7121 |
|
|
int *enableLVD_high, int *eprom_present)
|
7122 |
|
|
{
|
7123 |
|
|
unsigned char brdctl;
|
7124 |
|
|
|
7125 |
|
|
brdctl = read_brdctl(p);
|
7126 |
|
|
|
7127 |
|
|
*eprom_present = (brdctl & BRDDAT7);
|
7128 |
|
|
*enableSE_high = (brdctl & BRDDAT6);
|
7129 |
|
|
*enableSE_low = (brdctl & BRDDAT5);
|
7130 |
|
|
*enableLVD_high = (brdctl & BRDDAT4);
|
7131 |
|
|
*enableLVD_low = (brdctl & BRDDAT3);
|
7132 |
|
|
}
|
7133 |
|
|
|
7134 |
|
|
/*+F*************************************************************************
|
7135 |
|
|
* Function:
|
7136 |
|
|
* configure_termination
|
7137 |
|
|
*
|
7138 |
|
|
* Description:
|
7139 |
|
|
* Configures the termination settings on PCI adapters that have
|
7140 |
|
|
* SEEPROMs available.
|
7141 |
|
|
*-F*************************************************************************/
|
7142 |
|
|
static void
|
7143 |
|
|
configure_termination(struct aic7xxx_host *p)
|
7144 |
|
|
{
|
7145 |
|
|
int internal50_present = 0;
|
7146 |
|
|
int internal68_present = 0;
|
7147 |
|
|
int external_present = 0;
|
7148 |
|
|
int eprom_present = 0;
|
7149 |
|
|
int enableSE_low = 0;
|
7150 |
|
|
int enableSE_high = 0;
|
7151 |
|
|
int enableLVD_low = 0;
|
7152 |
|
|
int enableLVD_high = 0;
|
7153 |
|
|
unsigned char brddat = 0;
|
7154 |
|
|
unsigned char max_target = 0;
|
7155 |
|
|
unsigned char sxfrctl1 = aic_inb(p, SXFRCTL1);
|
7156 |
|
|
|
7157 |
|
|
if (acquire_seeprom(p))
|
7158 |
|
|
{
|
7159 |
|
|
if (p->features & (AHC_WIDE|AHC_TWIN))
|
7160 |
|
|
max_target = 16;
|
7161 |
|
|
else
|
7162 |
|
|
max_target = 8;
|
7163 |
|
|
aic_outb(p, SEEMS | SEECS, SEECTL);
|
7164 |
|
|
sxfrctl1 &= ~STPWEN;
|
7165 |
|
|
if ( (p->adapter_control & CFAUTOTERM) ||
|
7166 |
|
|
(p->features & AHC_ULTRA2) )
|
7167 |
|
|
{
|
7168 |
|
|
if ( (p->adapter_control & CFAUTOTERM) && !(p->features & AHC_ULTRA2) )
|
7169 |
|
|
{
|
7170 |
|
|
printk(KERN_INFO "(scsi%d) Warning - detected auto-termination\n",
|
7171 |
|
|
p->host_no);
|
7172 |
|
|
printk(KERN_INFO "(scsi%d) Please verify driver detected settings are "
|
7173 |
|
|
"correct.\n", p->host_no);
|
7174 |
|
|
printk(KERN_INFO "(scsi%d) If not, then please properly set the device "
|
7175 |
|
|
"termination\n", p->host_no);
|
7176 |
|
|
printk(KERN_INFO "(scsi%d) in the Adaptec SCSI BIOS by hitting CTRL-A "
|
7177 |
|
|
"when prompted\n", p->host_no);
|
7178 |
|
|
printk(KERN_INFO "(scsi%d) during machine bootup.\n", p->host_no);
|
7179 |
|
|
}
|
7180 |
|
|
/* Configure auto termination. */
|
7181 |
|
|
|
7182 |
|
|
if (p->features & AHC_ULTRA2)
|
7183 |
|
|
{
|
7184 |
|
|
if (aic7xxx_override_term == -1)
|
7185 |
|
|
aic7xxx_ultra2_term_detect(p, &enableSE_low, &enableSE_high,
|
7186 |
|
|
&enableLVD_low, &enableLVD_high,
|
7187 |
|
|
&eprom_present);
|
7188 |
|
|
if (!(p->adapter_control & CFSEAUTOTERM))
|
7189 |
|
|
{
|
7190 |
|
|
enableSE_low = (p->adapter_control & CFSTERM);
|
7191 |
|
|
enableSE_high = (p->adapter_control & CFWSTERM);
|
7192 |
|
|
}
|
7193 |
|
|
if (!(p->adapter_control & CFAUTOTERM))
|
7194 |
|
|
{
|
7195 |
|
|
enableLVD_low = enableLVD_high = (p->adapter_control & CFLVDSTERM);
|
7196 |
|
|
}
|
7197 |
|
|
internal50_present = 0;
|
7198 |
|
|
internal68_present = 1;
|
7199 |
|
|
external_present = 1;
|
7200 |
|
|
}
|
7201 |
|
|
else if ( (p->chip & AHC_CHIPID_MASK) >= AHC_AIC7870 )
|
7202 |
|
|
{
|
7203 |
|
|
aic787x_cable_detect(p, &internal50_present, &internal68_present,
|
7204 |
|
|
&external_present, &eprom_present);
|
7205 |
|
|
}
|
7206 |
|
|
else
|
7207 |
|
|
{
|
7208 |
|
|
aic785x_cable_detect(p, &internal50_present, &external_present,
|
7209 |
|
|
&eprom_present);
|
7210 |
|
|
}
|
7211 |
|
|
|
7212 |
|
|
if (max_target <= 8)
|
7213 |
|
|
internal68_present = 0;
|
7214 |
|
|
|
7215 |
|
|
if ( !(p->features & AHC_ULTRA2) )
|
7216 |
|
|
{
|
7217 |
|
|
if (max_target > 8)
|
7218 |
|
|
{
|
7219 |
|
|
printk(KERN_INFO "(scsi%d) Cables present (Int-50 %s, Int-68 %s, "
|
7220 |
|
|
"Ext-68 %s)\n", p->host_no,
|
7221 |
|
|
internal50_present ? "YES" : "NO",
|
7222 |
|
|
internal68_present ? "YES" : "NO",
|
7223 |
|
|
external_present ? "YES" : "NO");
|
7224 |
|
|
}
|
7225 |
|
|
else
|
7226 |
|
|
{
|
7227 |
|
|
printk(KERN_INFO "(scsi%d) Cables present (Int-50 %s, Ext-50 %s)\n",
|
7228 |
|
|
p->host_no,
|
7229 |
|
|
internal50_present ? "YES" : "NO",
|
7230 |
|
|
external_present ? "YES" : "NO");
|
7231 |
|
|
}
|
7232 |
|
|
}
|
7233 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
7234 |
|
|
printk(KERN_INFO "(scsi%d) EEPROM %s present.\n", p->host_no,
|
7235 |
|
|
eprom_present ? "is" : "is not");
|
7236 |
|
|
|
7237 |
|
|
/*
|
7238 |
|
|
* Now set the termination based on what we found. BRDDAT6
|
7239 |
|
|
* controls wide termination enable.
|
7240 |
|
|
* Flash Enable = BRDDAT7
|
7241 |
|
|
* SE High Term Enable = BRDDAT6
|
7242 |
|
|
* SE Low Term Enable = BRDDAT5 (7890)
|
7243 |
|
|
* LVD High Term Enable = BRDDAT4 (7890)
|
7244 |
|
|
*/
|
7245 |
|
|
if ( !(p->features & AHC_ULTRA2) &&
|
7246 |
|
|
(internal50_present && internal68_present && external_present) )
|
7247 |
|
|
{
|
7248 |
|
|
printk(KERN_INFO "(scsi%d) Illegal cable configuration!! Only two\n",
|
7249 |
|
|
p->host_no);
|
7250 |
|
|
printk(KERN_INFO "(scsi%d) connectors on the SCSI controller may be "
|
7251 |
|
|
"in use at a time!\n", p->host_no);
|
7252 |
|
|
/*
|
7253 |
|
|
* Force termination (low and high byte) on. This is safer than
|
7254 |
|
|
* leaving it completely off, especially since this message comes
|
7255 |
|
|
* most often from motherboard controllers that don't even have 3
|
7256 |
|
|
* connectors, but instead are failing the cable detection.
|
7257 |
|
|
*/
|
7258 |
|
|
internal50_present = external_present = 0;
|
7259 |
|
|
enableSE_high = enableSE_low = 1;
|
7260 |
|
|
}
|
7261 |
|
|
|
7262 |
|
|
if ((max_target > 8) &&
|
7263 |
|
|
((external_present == 0) || (internal68_present == 0) ||
|
7264 |
|
|
(enableSE_high != 0)))
|
7265 |
|
|
{
|
7266 |
|
|
brddat |= BRDDAT6;
|
7267 |
|
|
p->flags |= AHC_TERM_ENB_SE_HIGH;
|
7268 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
7269 |
|
|
printk(KERN_INFO "(scsi%d) SE High byte termination Enabled\n",
|
7270 |
|
|
p->host_no);
|
7271 |
|
|
}
|
7272 |
|
|
|
7273 |
|
|
if ( (((internal50_present ? 1 : 0) +
|
7274 |
|
|
(internal68_present ? 1 : 0) +
|
7275 |
|
|
(external_present ? 1 : 0)) <= 1) ||
|
7276 |
|
|
(enableSE_low != 0) )
|
7277 |
|
|
{
|
7278 |
|
|
if (p->features & AHC_ULTRA2)
|
7279 |
|
|
brddat |= BRDDAT5;
|
7280 |
|
|
else
|
7281 |
|
|
sxfrctl1 |= STPWEN;
|
7282 |
|
|
p->flags |= AHC_TERM_ENB_SE_LOW;
|
7283 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
7284 |
|
|
printk(KERN_INFO "(scsi%d) SE Low byte termination Enabled\n",
|
7285 |
|
|
p->host_no);
|
7286 |
|
|
}
|
7287 |
|
|
|
7288 |
|
|
if (enableLVD_low != 0)
|
7289 |
|
|
{
|
7290 |
|
|
sxfrctl1 |= STPWEN;
|
7291 |
|
|
p->flags |= AHC_TERM_ENB_LVD;
|
7292 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
7293 |
|
|
printk(KERN_INFO "(scsi%d) LVD Low byte termination Enabled\n",
|
7294 |
|
|
p->host_no);
|
7295 |
|
|
}
|
7296 |
|
|
|
7297 |
|
|
if (enableLVD_high != 0)
|
7298 |
|
|
{
|
7299 |
|
|
brddat |= BRDDAT4;
|
7300 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
7301 |
|
|
printk(KERN_INFO "(scsi%d) LVD High byte termination Enabled\n",
|
7302 |
|
|
p->host_no);
|
7303 |
|
|
}
|
7304 |
|
|
}
|
7305 |
|
|
else
|
7306 |
|
|
{
|
7307 |
|
|
if (p->adapter_control & CFSTERM)
|
7308 |
|
|
{
|
7309 |
|
|
if (p->features & AHC_ULTRA2)
|
7310 |
|
|
brddat |= BRDDAT5;
|
7311 |
|
|
else
|
7312 |
|
|
sxfrctl1 |= STPWEN;
|
7313 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
7314 |
|
|
printk(KERN_INFO "(scsi%d) SE Low byte termination Enabled\n",
|
7315 |
|
|
p->host_no);
|
7316 |
|
|
}
|
7317 |
|
|
|
7318 |
|
|
if (p->adapter_control & CFWSTERM)
|
7319 |
|
|
{
|
7320 |
|
|
brddat |= BRDDAT6;
|
7321 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
7322 |
|
|
printk(KERN_INFO "(scsi%d) SE High byte termination Enabled\n",
|
7323 |
|
|
p->host_no);
|
7324 |
|
|
}
|
7325 |
|
|
}
|
7326 |
|
|
write_brdctl(p, brddat);
|
7327 |
|
|
release_seeprom(p);
|
7328 |
|
|
aic_outb(p, sxfrctl1, SXFRCTL1);
|
7329 |
|
|
}
|
7330 |
|
|
}
|
7331 |
|
|
|
7332 |
|
|
/*+F*************************************************************************
|
7333 |
|
|
* Function:
|
7334 |
|
|
* detect_maxscb
|
7335 |
|
|
*
|
7336 |
|
|
* Description:
|
7337 |
|
|
* Detects the maximum number of SCBs for the controller and returns
|
7338 |
|
|
* the count and a mask in p (p->maxscbs, p->qcntmask).
|
7339 |
|
|
*-F*************************************************************************/
|
7340 |
|
|
static void
|
7341 |
|
|
detect_maxscb(struct aic7xxx_host *p)
|
7342 |
|
|
{
|
7343 |
|
|
int i;
|
7344 |
|
|
|
7345 |
|
|
/*
|
7346 |
|
|
* It's possible that we've already done this for multichannel
|
7347 |
|
|
* adapters.
|
7348 |
|
|
*/
|
7349 |
|
|
if (p->scb_data->maxhscbs == 0)
|
7350 |
|
|
{
|
7351 |
|
|
/*
|
7352 |
|
|
* We haven't initialized the SCB settings yet. Walk the SCBs to
|
7353 |
|
|
* determince how many there are.
|
7354 |
|
|
*/
|
7355 |
|
|
aic_outb(p, 0, FREE_SCBH);
|
7356 |
|
|
|
7357 |
|
|
for (i = 0; i < AIC7XXX_MAXSCB; i++)
|
7358 |
|
|
{
|
7359 |
|
|
aic_outb(p, i, SCBPTR);
|
7360 |
|
|
aic_outb(p, i, SCB_CONTROL);
|
7361 |
|
|
if (aic_inb(p, SCB_CONTROL) != i)
|
7362 |
|
|
break;
|
7363 |
|
|
aic_outb(p, 0, SCBPTR);
|
7364 |
|
|
if (aic_inb(p, SCB_CONTROL) != 0)
|
7365 |
|
|
break;
|
7366 |
|
|
|
7367 |
|
|
aic_outb(p, i, SCBPTR);
|
7368 |
|
|
aic_outb(p, 0, SCB_CONTROL); /* Clear the control byte. */
|
7369 |
|
|
aic_outb(p, i + 1, SCB_NEXT); /* Set the next pointer. */
|
7370 |
|
|
aic_outb(p, i - 1, SCB_PREV); /* Set the prev pointer. */
|
7371 |
|
|
aic_outb(p, SCB_LIST_NULL, SCB_TAG); /* Make the tag invalid. */
|
7372 |
|
|
aic_outb(p, SCB_LIST_NULL, SCB_BUSYTARGETS); /* no busy untagged */
|
7373 |
|
|
aic_outb(p, SCB_LIST_NULL, SCB_BUSYTARGETS+1);/* targets active yet */
|
7374 |
|
|
aic_outb(p, SCB_LIST_NULL, SCB_BUSYTARGETS+2);
|
7375 |
|
|
aic_outb(p, SCB_LIST_NULL, SCB_BUSYTARGETS+3);
|
7376 |
|
|
}
|
7377 |
|
|
|
7378 |
|
|
/* Make sure the last SCB terminates the free list. */
|
7379 |
|
|
aic_outb(p, i - 1, SCBPTR);
|
7380 |
|
|
aic_outb(p, SCB_LIST_NULL, SCB_NEXT);
|
7381 |
|
|
|
7382 |
|
|
/* Ensure we clear the first (0) SCBs control byte. */
|
7383 |
|
|
aic_outb(p, 0, SCBPTR);
|
7384 |
|
|
aic_outb(p, 0, SCB_CONTROL);
|
7385 |
|
|
|
7386 |
|
|
p->scb_data->maxhscbs = i;
|
7387 |
|
|
/*
|
7388 |
|
|
* Use direct indexing instead for speed
|
7389 |
|
|
*/
|
7390 |
|
|
if ( i == AIC7XXX_MAXSCB )
|
7391 |
|
|
p->flags &= ~AHC_PAGESCBS;
|
7392 |
|
|
}
|
7393 |
|
|
|
7394 |
|
|
}
|
7395 |
|
|
|
7396 |
|
|
/*+F*************************************************************************
|
7397 |
|
|
* Function:
|
7398 |
|
|
* aic7xxx_register
|
7399 |
|
|
*
|
7400 |
|
|
* Description:
|
7401 |
|
|
* Register a Adaptec aic7xxx chip SCSI controller with the kernel.
|
7402 |
|
|
*-F*************************************************************************/
|
7403 |
|
|
static int
|
7404 |
|
|
aic7xxx_register(Scsi_Host_Template *template, struct aic7xxx_host *p,
|
7405 |
|
|
int reset_delay)
|
7406 |
|
|
{
|
7407 |
|
|
int i, result;
|
7408 |
|
|
int max_targets;
|
7409 |
|
|
int found = 1;
|
7410 |
|
|
unsigned char term, scsi_conf;
|
7411 |
|
|
struct Scsi_Host *host;
|
7412 |
|
|
|
7413 |
|
|
/*
|
7414 |
|
|
* Lock out other contenders for our i/o space.
|
7415 |
|
|
*/
|
7416 |
|
|
request_region(p->base, MAXREG - MINREG, "aic7xxx");
|
7417 |
|
|
|
7418 |
|
|
|
7419 |
|
|
host = p->host;
|
7420 |
|
|
|
7421 |
|
|
p->scb_data->maxscbs = AIC7XXX_MAXSCB;
|
7422 |
|
|
host->can_queue = AIC7XXX_MAXSCB;
|
7423 |
|
|
host->cmd_per_lun = 3;
|
7424 |
|
|
host->sg_tablesize = AIC7XXX_MAX_SG;
|
7425 |
|
|
host->select_queue_depths = aic7xxx_select_queue_depth;
|
7426 |
|
|
host->this_id = p->scsi_id;
|
7427 |
|
|
host->io_port = p->base;
|
7428 |
|
|
host->n_io_port = 0xFF;
|
7429 |
|
|
host->base = (unsigned char *) p->mbase;
|
7430 |
|
|
host->irq = p->irq;
|
7431 |
|
|
if (p->features & AHC_WIDE)
|
7432 |
|
|
{
|
7433 |
|
|
host->max_id = 16;
|
7434 |
|
|
}
|
7435 |
|
|
if (p->features & AHC_TWIN)
|
7436 |
|
|
{
|
7437 |
|
|
host->max_channel = 1;
|
7438 |
|
|
}
|
7439 |
|
|
|
7440 |
|
|
p->host = host;
|
7441 |
|
|
p->host_no = host->host_no;
|
7442 |
|
|
host->unique_id = p->instance;
|
7443 |
|
|
p->isr_count = 0;
|
7444 |
|
|
p->next = NULL;
|
7445 |
|
|
p->completeq.head = NULL;
|
7446 |
|
|
p->completeq.tail = NULL;
|
7447 |
|
|
scbq_init(&p->scb_data->free_scbs);
|
7448 |
|
|
scbq_init(&p->waiting_scbs);
|
7449 |
|
|
init_timer(&p->dev_timer);
|
7450 |
|
|
p->dev_timer.data = (unsigned long)p;
|
7451 |
|
|
p->dev_timer.function = (void *)aic7xxx_timer;
|
7452 |
|
|
p->dev_timer_active = 0;
|
7453 |
|
|
|
7454 |
|
|
for (i = 0; i < NUMBER(p->untagged_scbs); i++)
|
7455 |
|
|
{
|
7456 |
|
|
p->untagged_scbs[i] = SCB_LIST_NULL;
|
7457 |
|
|
p->qinfifo[i] = SCB_LIST_NULL;
|
7458 |
|
|
p->qoutfifo[i] = SCB_LIST_NULL;
|
7459 |
|
|
}
|
7460 |
|
|
/*
|
7461 |
|
|
* We currently have no commands of any type
|
7462 |
|
|
*/
|
7463 |
|
|
p->qinfifonext = 0;
|
7464 |
|
|
p->qoutfifonext = 0;
|
7465 |
|
|
|
7466 |
|
|
for (i = 0; i < MAX_TARGETS; i++)
|
7467 |
|
|
{
|
7468 |
|
|
p->dev_commands_sent[i] = 0;
|
7469 |
|
|
p->dev_flags[i] = 0;
|
7470 |
|
|
p->dev_active_cmds[i] = 0;
|
7471 |
|
|
p->dev_last_queue_full[i] = 0;
|
7472 |
|
|
p->dev_last_queue_full_count[i] = 0;
|
7473 |
|
|
p->dev_max_queue_depth[i] = 1;
|
7474 |
|
|
p->dev_temp_queue_depth[i] = 1;
|
7475 |
|
|
p->dev_expires[i] = 0;
|
7476 |
|
|
scbq_init(&p->delayed_scbs[i]);
|
7477 |
|
|
}
|
7478 |
|
|
|
7479 |
|
|
printk(KERN_INFO "(scsi%d) <%s> found at ", p->host_no,
|
7480 |
|
|
board_names[p->board_name_index]);
|
7481 |
|
|
switch(p->chip)
|
7482 |
|
|
{
|
7483 |
|
|
case (AHC_AIC7770|AHC_EISA):
|
7484 |
|
|
printk("EISA slot %d\n", p->pci_device_fn);
|
7485 |
|
|
break;
|
7486 |
|
|
case (AHC_AIC7770|AHC_VL):
|
7487 |
|
|
printk("VLB slot %d\n", p->pci_device_fn);
|
7488 |
|
|
break;
|
7489 |
|
|
default:
|
7490 |
|
|
printk("PCI %d/%d\n", PCI_SLOT(p->pci_device_fn),
|
7491 |
|
|
PCI_FUNC(p->pci_device_fn));
|
7492 |
|
|
break;
|
7493 |
|
|
}
|
7494 |
|
|
if (p->features & AHC_TWIN)
|
7495 |
|
|
{
|
7496 |
|
|
printk(KERN_INFO "(scsi%d) Twin Channel, A SCSI ID %d, B SCSI ID %d, ",
|
7497 |
|
|
p->host_no, p->scsi_id, p->scsi_id_b);
|
7498 |
|
|
}
|
7499 |
|
|
else
|
7500 |
|
|
{
|
7501 |
|
|
char *channel;
|
7502 |
|
|
|
7503 |
|
|
channel = "";
|
7504 |
|
|
|
7505 |
|
|
if ((p->flags & AHC_MULTI_CHANNEL) != 0)
|
7506 |
|
|
{
|
7507 |
|
|
channel = " A";
|
7508 |
|
|
|
7509 |
|
|
if ( (p->flags & (AHC_CHNLB|AHC_CHNLC)) != 0 )
|
7510 |
|
|
{
|
7511 |
|
|
channel = (p->flags & AHC_CHNLB) ? " B" : " C";
|
7512 |
|
|
}
|
7513 |
|
|
}
|
7514 |
|
|
if (p->features & AHC_WIDE)
|
7515 |
|
|
{
|
7516 |
|
|
printk(KERN_INFO "(scsi%d) Wide ", p->host_no);
|
7517 |
|
|
}
|
7518 |
|
|
else
|
7519 |
|
|
{
|
7520 |
|
|
printk(KERN_INFO "(scsi%d) Narrow ", p->host_no);
|
7521 |
|
|
}
|
7522 |
|
|
printk("Channel%s, SCSI ID=%d, ", channel, p->scsi_id);
|
7523 |
|
|
}
|
7524 |
|
|
aic_outb(p, 0, SEQ_FLAGS);
|
7525 |
|
|
|
7526 |
|
|
detect_maxscb(p);
|
7527 |
|
|
|
7528 |
|
|
|
7529 |
|
|
printk("%d/%d SCBs\n", p->scb_data->maxhscbs, p->scb_data->maxscbs);
|
7530 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
7531 |
|
|
{
|
7532 |
|
|
printk(KERN_INFO "(scsi%d) BIOS %sabled, IO Port 0x%lx, IRQ %d\n",
|
7533 |
|
|
p->host_no, (p->flags & AHC_BIOS_ENABLED) ? "en" : "dis",
|
7534 |
|
|
p->base, p->irq);
|
7535 |
|
|
printk(KERN_INFO "(scsi%d) IO Memory at 0x%lx, MMAP Memory at 0x%lx\n",
|
7536 |
|
|
p->host_no, p->mbase, (unsigned long)p->maddr);
|
7537 |
|
|
}
|
7538 |
|
|
|
7539 |
|
|
#ifdef CONFIG_PCI
|
7540 |
|
|
/*
|
7541 |
|
|
* Now that we know our instance number, we can set the flags we need to
|
7542 |
|
|
* force termination if need be.
|
7543 |
|
|
*/
|
7544 |
|
|
if (aic7xxx_stpwlev != -1)
|
7545 |
|
|
{
|
7546 |
|
|
/*
|
7547 |
|
|
* This option only applies to PCI controllers.
|
7548 |
|
|
*/
|
7549 |
|
|
if ( (p->chip & ~AHC_CHIPID_MASK) == AHC_PCI)
|
7550 |
|
|
{
|
7551 |
|
|
unsigned char devconfig;
|
7552 |
|
|
|
7553 |
|
|
#if LINUX_KERNEL_VERSION > KERNEL_VERSION(2,1,92)
|
7554 |
|
|
pci_read_config_byte(p->pdev, DEVCONFIG, &devconfig);
|
7555 |
|
|
#else
|
7556 |
|
|
pcibios_read_config_byte(p->pci_bus, p->pci_device_fn,
|
7557 |
|
|
DEVCONFIG, &devconfig);
|
7558 |
|
|
#endif
|
7559 |
|
|
if ( (aic7xxx_stpwlev >> p->instance) & 0x01 )
|
7560 |
|
|
{
|
7561 |
|
|
devconfig |= 0x02;
|
7562 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
7563 |
|
|
printk("(scsi%d) Force setting STPWLEV bit\n", p->host_no);
|
7564 |
|
|
}
|
7565 |
|
|
else
|
7566 |
|
|
{
|
7567 |
|
|
devconfig &= ~0x02;
|
7568 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
7569 |
|
|
printk("(scsi%d) Force clearing STPWLEV bit\n", p->host_no);
|
7570 |
|
|
}
|
7571 |
|
|
#if LINUX_KERNEL_VERSION > KERNEL_VERSION(2,1,92)
|
7572 |
|
|
pci_write_config_byte(p->pdev, DEVCONFIG, devconfig);
|
7573 |
|
|
#else
|
7574 |
|
|
pcibios_write_config_byte(p->pci_bus, p->pci_device_fn,
|
7575 |
|
|
DEVCONFIG, devconfig);
|
7576 |
|
|
#endif
|
7577 |
|
|
}
|
7578 |
|
|
}
|
7579 |
|
|
#endif
|
7580 |
|
|
|
7581 |
|
|
/*
|
7582 |
|
|
* That took care of devconfig and stpwlev, now for the actual termination
|
7583 |
|
|
* settings.
|
7584 |
|
|
*/
|
7585 |
|
|
if (aic7xxx_override_term != -1)
|
7586 |
|
|
{
|
7587 |
|
|
/*
|
7588 |
|
|
* Again, this only applies to PCI controllers. We don't have problems
|
7589 |
|
|
* with the termination on 274x controllers to the best of my knowledge.
|
7590 |
|
|
*/
|
7591 |
|
|
if ( (p->chip & ~AHC_CHIPID_MASK) == AHC_PCI)
|
7592 |
|
|
{
|
7593 |
|
|
unsigned char term_override;
|
7594 |
|
|
|
7595 |
|
|
term_override = ( (aic7xxx_override_term >> (p->instance * 4)) & 0x0f);
|
7596 |
|
|
p->adapter_control &=
|
7597 |
|
|
~(CFSTERM|CFWSTERM|CFLVDSTERM|CFAUTOTERM|CFSEAUTOTERM);
|
7598 |
|
|
if ( (p->features & AHC_ULTRA2) && (term_override & 0x0c) )
|
7599 |
|
|
{
|
7600 |
|
|
p->adapter_control |= CFLVDSTERM;
|
7601 |
|
|
}
|
7602 |
|
|
if (term_override & 0x02)
|
7603 |
|
|
{
|
7604 |
|
|
p->adapter_control |= CFWSTERM;
|
7605 |
|
|
}
|
7606 |
|
|
if (term_override & 0x01)
|
7607 |
|
|
{
|
7608 |
|
|
p->adapter_control |= CFSTERM;
|
7609 |
|
|
}
|
7610 |
|
|
}
|
7611 |
|
|
}
|
7612 |
|
|
|
7613 |
|
|
if ( (p->flags & AHC_SEEPROM_FOUND) || (aic7xxx_override_term != -1) )
|
7614 |
|
|
{
|
7615 |
|
|
if (p->features & AHC_SPIOCAP)
|
7616 |
|
|
{
|
7617 |
|
|
if ( aic_inb(p, SPIOCAP) & SSPIOCPS )
|
7618 |
|
|
/*
|
7619 |
|
|
* Update the settings in sxfrctl1 to match the termination
|
7620 |
|
|
* settings.
|
7621 |
|
|
*/
|
7622 |
|
|
configure_termination(p);
|
7623 |
|
|
}
|
7624 |
|
|
else if ((p->chip & AHC_CHIPID_MASK) >= AHC_AIC7870)
|
7625 |
|
|
{
|
7626 |
|
|
configure_termination(p);
|
7627 |
|
|
}
|
7628 |
|
|
}
|
7629 |
|
|
|
7630 |
|
|
/*
|
7631 |
|
|
* Clear out any possible pending interrupts.
|
7632 |
|
|
*/
|
7633 |
|
|
aic7xxx_clear_intstat(p);
|
7634 |
|
|
|
7635 |
|
|
/*
|
7636 |
|
|
* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1, for both channels
|
7637 |
|
|
*/
|
7638 |
|
|
if (p->features & AHC_TWIN)
|
7639 |
|
|
{
|
7640 |
|
|
/* Select channel B */
|
7641 |
|
|
aic_outb(p, aic_inb(p, SBLKCTL) | SELBUSB, SBLKCTL);
|
7642 |
|
|
|
7643 |
|
|
term = ((p->flags & AHC_TERM_ENB_B) != 0) ? STPWEN : 0;
|
7644 |
|
|
aic_outb(p, p->scsi_id_b, SCSIID);
|
7645 |
|
|
scsi_conf = aic_inb(p, SCSICONF + 1);
|
7646 |
|
|
aic_outb(p, DFON | SPIOEN, SXFRCTL0);
|
7647 |
|
|
aic_outb(p, (scsi_conf & ENSPCHK) | STIMESEL | term |
|
7648 |
|
|
ENSTIMER | ACTNEGEN, SXFRCTL1);
|
7649 |
|
|
aic_outb(p, 0, SIMODE0);
|
7650 |
|
|
aic_outb(p, ENSELTIMO | ENSCSIRST | ENSCSIPERR, SIMODE1);
|
7651 |
|
|
aic_outb(p, 0, SCSIRATE);
|
7652 |
|
|
|
7653 |
|
|
/* Select channel A */
|
7654 |
|
|
aic_outb(p, aic_inb(p, SBLKCTL) & ~SELBUSB, SBLKCTL);
|
7655 |
|
|
}
|
7656 |
|
|
|
7657 |
|
|
term = ((p->flags & AHC_TERM_ENB_SE_LOW) != 0) ? STPWEN : 0;
|
7658 |
|
|
if (p->features & AHC_ULTRA2)
|
7659 |
|
|
aic_outb(p, p->scsi_id, SCSIID_ULTRA2);
|
7660 |
|
|
else
|
7661 |
|
|
aic_outb(p, p->scsi_id, SCSIID);
|
7662 |
|
|
scsi_conf = aic_inb(p, SCSICONF);
|
7663 |
|
|
aic_outb(p, DFON | SPIOEN, SXFRCTL0);
|
7664 |
|
|
aic_outb(p, (scsi_conf & ENSPCHK) | STIMESEL | term |
|
7665 |
|
|
ENSTIMER | ACTNEGEN, SXFRCTL1);
|
7666 |
|
|
aic_outb(p, 0, SIMODE0);
|
7667 |
|
|
aic_outb(p, ENSELTIMO | ENSCSIRST | ENSCSIPERR, SIMODE1);
|
7668 |
|
|
aic_outb(p, 0, SCSIRATE);
|
7669 |
|
|
if ( p->features & AHC_ULTRA2)
|
7670 |
|
|
aic_outb(p, 0, SCSIOFFSET);
|
7671 |
|
|
|
7672 |
|
|
/*
|
7673 |
|
|
* Look at the information that board initialization or the board
|
7674 |
|
|
* BIOS has left us. In the lower four bits of each target's
|
7675 |
|
|
* scratch space any value other than 0 indicates that we should
|
7676 |
|
|
* initiate synchronous transfers. If it's zero, the user or the
|
7677 |
|
|
* BIOS has decided to disable synchronous negotiation to that
|
7678 |
|
|
* target so we don't activate the needsdtr flag.
|
7679 |
|
|
*/
|
7680 |
|
|
if ((p->features & (AHC_TWIN|AHC_WIDE)) == 0)
|
7681 |
|
|
{
|
7682 |
|
|
max_targets = 8;
|
7683 |
|
|
}
|
7684 |
|
|
else
|
7685 |
|
|
{
|
7686 |
|
|
max_targets = 16;
|
7687 |
|
|
}
|
7688 |
|
|
|
7689 |
|
|
if (!(aic7xxx_no_reset))
|
7690 |
|
|
{
|
7691 |
|
|
/*
|
7692 |
|
|
* If we reset the bus, then clear the transfer settings, else leave
|
7693 |
|
|
* them be
|
7694 |
|
|
*/
|
7695 |
|
|
for (i = 0; i < max_targets; i++)
|
7696 |
|
|
{
|
7697 |
|
|
aic_outb(p, 0, TARG_SCSIRATE + i);
|
7698 |
|
|
if (p->features & AHC_ULTRA2)
|
7699 |
|
|
{
|
7700 |
|
|
aic_outb(p, 0, TARG_OFFSET + i);
|
7701 |
|
|
}
|
7702 |
|
|
p->transinfo[i].cur_offset = 0;
|
7703 |
|
|
p->transinfo[i].cur_period = 0;
|
7704 |
|
|
p->transinfo[i].cur_width = MSG_EXT_WDTR_BUS_8_BIT;
|
7705 |
|
|
}
|
7706 |
|
|
|
7707 |
|
|
/*
|
7708 |
|
|
* If we reset the bus, then clear the transfer settings, else leave
|
7709 |
|
|
* them be.
|
7710 |
|
|
*/
|
7711 |
|
|
aic_outb(p, 0, ULTRA_ENB);
|
7712 |
|
|
aic_outb(p, 0, ULTRA_ENB + 1);
|
7713 |
|
|
p->ultraenb = 0;
|
7714 |
|
|
}
|
7715 |
|
|
|
7716 |
|
|
/*
|
7717 |
|
|
* Allocate enough hardware scbs to handle the maximum number of
|
7718 |
|
|
* concurrent transactions we can have. We have to make sure that
|
7719 |
|
|
* the allocated memory is contiguous memory. The Linux kmalloc
|
7720 |
|
|
* routine should only allocate contiguous memory, but note that
|
7721 |
|
|
* this could be a problem if kmalloc() is changed.
|
7722 |
|
|
*/
|
7723 |
|
|
{
|
7724 |
|
|
size_t array_size;
|
7725 |
|
|
unsigned int hscb_physaddr;
|
7726 |
|
|
unsigned long temp;
|
7727 |
|
|
|
7728 |
|
|
array_size = p->scb_data->maxscbs * sizeof(struct aic7xxx_hwscb);
|
7729 |
|
|
if (p->scb_data->hscbs == NULL)
|
7730 |
|
|
{
|
7731 |
|
|
/*
|
7732 |
|
|
* A little padding so we can align thing the way we want
|
7733 |
|
|
*/
|
7734 |
|
|
p->scb_data->hscbs = kmalloc(array_size + 0x1f, GFP_ATOMIC);
|
7735 |
|
|
}
|
7736 |
|
|
if (p->scb_data->hscbs == NULL)
|
7737 |
|
|
{
|
7738 |
|
|
printk("(scsi%d) Unable to allocate hardware SCB array; "
|
7739 |
|
|
"failing detection.\n", p->host_no);
|
7740 |
|
|
p->irq = 0;
|
7741 |
|
|
return(0);
|
7742 |
|
|
}
|
7743 |
|
|
/*
|
7744 |
|
|
* Save the actual kmalloc buffer pointer off, then align our
|
7745 |
|
|
* buffer to a 32 byte boundary
|
7746 |
|
|
*/
|
7747 |
|
|
p->scb_data->hscb_kmalloc_ptr = p->scb_data->hscbs;
|
7748 |
|
|
temp = (unsigned long)p->scb_data->hscbs;
|
7749 |
|
|
temp += 0x1f;
|
7750 |
|
|
temp &= ~0x1f;
|
7751 |
|
|
p->scb_data->hscbs = (struct aic7xxx_hwscb *)temp;
|
7752 |
|
|
/* At least the control byte of each SCB needs to be 0. */
|
7753 |
|
|
memset(p->scb_data->hscbs, 0, array_size);
|
7754 |
|
|
|
7755 |
|
|
/* Tell the sequencer where it can find the hardware SCB array. */
|
7756 |
|
|
hscb_physaddr = VIRT_TO_BUS(p->scb_data->hscbs);
|
7757 |
|
|
aic_outb(p, hscb_physaddr & 0xFF, HSCB_ADDR);
|
7758 |
|
|
aic_outb(p, (hscb_physaddr >> 8) & 0xFF, HSCB_ADDR + 1);
|
7759 |
|
|
aic_outb(p, (hscb_physaddr >> 16) & 0xFF, HSCB_ADDR + 2);
|
7760 |
|
|
aic_outb(p, (hscb_physaddr >> 24) & 0xFF, HSCB_ADDR + 3);
|
7761 |
|
|
|
7762 |
|
|
/* Set up the fifo areas at the same time */
|
7763 |
|
|
hscb_physaddr = VIRT_TO_BUS(&p->untagged_scbs[0]);
|
7764 |
|
|
aic_outb(p, hscb_physaddr & 0xFF, SCBID_ADDR);
|
7765 |
|
|
aic_outb(p, (hscb_physaddr >> 8) & 0xFF, SCBID_ADDR + 1);
|
7766 |
|
|
aic_outb(p, (hscb_physaddr >> 16) & 0xFF, SCBID_ADDR + 2);
|
7767 |
|
|
aic_outb(p, (hscb_physaddr >> 24) & 0xFF, SCBID_ADDR + 3);
|
7768 |
|
|
}
|
7769 |
|
|
|
7770 |
|
|
/* The Q-FIFOs we just set up are all empty */
|
7771 |
|
|
aic_outb(p, 0, QINPOS);
|
7772 |
|
|
aic_outb(p, 0, KERNEL_QINPOS);
|
7773 |
|
|
aic_outb(p, 0, QOUTPOS);
|
7774 |
|
|
|
7775 |
|
|
if(p->features & AHC_QUEUE_REGS)
|
7776 |
|
|
{
|
7777 |
|
|
aic_outb(p, SCB_QSIZE_256, QOFF_CTLSTA);
|
7778 |
|
|
aic_outb(p, 0, SDSCB_QOFF);
|
7779 |
|
|
aic_outb(p, 0, SNSCB_QOFF);
|
7780 |
|
|
aic_outb(p, 0, HNSCB_QOFF);
|
7781 |
|
|
}
|
7782 |
|
|
|
7783 |
|
|
/*
|
7784 |
|
|
* We don't have any waiting selections or disconnected SCBs.
|
7785 |
|
|
*/
|
7786 |
|
|
aic_outb(p, SCB_LIST_NULL, WAITING_SCBH);
|
7787 |
|
|
aic_outb(p, SCB_LIST_NULL, DISCONNECTED_SCBH);
|
7788 |
|
|
|
7789 |
|
|
/*
|
7790 |
|
|
* Message out buffer starts empty
|
7791 |
|
|
*/
|
7792 |
|
|
aic_outb(p, MSG_NOOP, MSG_OUT);
|
7793 |
|
|
aic_outb(p, MSG_NOOP, LAST_MSG);
|
7794 |
|
|
|
7795 |
|
|
/*
|
7796 |
|
|
* Set all the other asundry items that haven't been set yet.
|
7797 |
|
|
* This includes just dumping init values to a lot of registers simply
|
7798 |
|
|
* to make sure they've been touched and are ready for use parity wise
|
7799 |
|
|
* speaking.
|
7800 |
|
|
*/
|
7801 |
|
|
aic_outb(p, 0, TMODE_CMDADDR);
|
7802 |
|
|
aic_outb(p, 0, TMODE_CMDADDR + 1);
|
7803 |
|
|
aic_outb(p, 0, TMODE_CMDADDR + 2);
|
7804 |
|
|
aic_outb(p, 0, TMODE_CMDADDR + 3);
|
7805 |
|
|
aic_outb(p, 0, TMODE_CMDADDR_NEXT);
|
7806 |
|
|
|
7807 |
|
|
/*
|
7808 |
|
|
* Link us into the list of valid hosts
|
7809 |
|
|
*/
|
7810 |
|
|
p->next = first_aic7xxx;
|
7811 |
|
|
first_aic7xxx = p;
|
7812 |
|
|
|
7813 |
|
|
/*
|
7814 |
|
|
* Clear out any possible pending interrupts, again.
|
7815 |
|
|
*/
|
7816 |
|
|
aic7xxx_clear_intstat(p);
|
7817 |
|
|
|
7818 |
|
|
/*
|
7819 |
|
|
* Allocate the first set of scbs for this controller. This is to stream-
|
7820 |
|
|
* line code elsewhere in the driver. If we have to check for the existence
|
7821 |
|
|
* of scbs in certain code sections, it slows things down. However, as
|
7822 |
|
|
* soon as we register the IRQ for this card, we could get an interrupt that
|
7823 |
|
|
* includes possibly the SCSI_RSTI interrupt. If we catch that interrupt
|
7824 |
|
|
* then we are likely to segfault if we don't have at least one chunk of
|
7825 |
|
|
* SCBs allocated or add checks all through the reset code to make sure
|
7826 |
|
|
* that the SCBs have been allocated which is an invalid running condition
|
7827 |
|
|
* and therefore I think it's preferable to simply pre-allocate the first
|
7828 |
|
|
* chunk of SCBs.
|
7829 |
|
|
*/
|
7830 |
|
|
aic7xxx_allocate_scb(p);
|
7831 |
|
|
|
7832 |
|
|
/*
|
7833 |
|
|
* Load the sequencer program, then re-enable the board -
|
7834 |
|
|
* resetting the AIC-7770 disables it, leaving the lights
|
7835 |
|
|
* on with nobody home.
|
7836 |
|
|
*/
|
7837 |
|
|
aic7xxx_loadseq(p);
|
7838 |
|
|
|
7839 |
|
|
/*
|
7840 |
|
|
* Make sure the AUTOFLUSHDIS bit is *not* set in the SBLKCTL register
|
7841 |
|
|
*/
|
7842 |
|
|
aic_outb(p, aic_inb(p, SBLKCTL) & ~AUTOFLUSHDIS, SBLKCTL);
|
7843 |
|
|
|
7844 |
|
|
if ( (p->chip & AHC_CHIPID_MASK) == AHC_AIC7770 )
|
7845 |
|
|
{
|
7846 |
|
|
aic_outb(p, ENABLE, BCTL); /* Enable the boards BUS drivers. */
|
7847 |
|
|
}
|
7848 |
|
|
|
7849 |
|
|
if ( !(aic7xxx_no_reset) )
|
7850 |
|
|
{
|
7851 |
|
|
if (p->features & AHC_TWIN)
|
7852 |
|
|
{
|
7853 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
7854 |
|
|
printk(KERN_INFO "(scsi%d) Resetting channel B\n", p->host_no);
|
7855 |
|
|
aic_outb(p, aic_inb(p, SBLKCTL) | SELBUSB, SBLKCTL);
|
7856 |
|
|
aic7xxx_reset_current_bus(p);
|
7857 |
|
|
aic_outb(p, aic_inb(p, SBLKCTL) & ~SELBUSB, SBLKCTL);
|
7858 |
|
|
}
|
7859 |
|
|
/* Reset SCSI bus A. */
|
7860 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
7861 |
|
|
{ /* In case we are a 3940, 3985, or 7895, print the right channel */
|
7862 |
|
|
char *channel = "";
|
7863 |
|
|
if (p->flags & AHC_MULTI_CHANNEL)
|
7864 |
|
|
{
|
7865 |
|
|
channel = " A";
|
7866 |
|
|
if (p->flags & (AHC_CHNLB|AHC_CHNLC))
|
7867 |
|
|
channel = (p->flags & AHC_CHNLB) ? " B" : " C";
|
7868 |
|
|
}
|
7869 |
|
|
printk(KERN_INFO "(scsi%d) Resetting channel%s\n", p->host_no, channel);
|
7870 |
|
|
}
|
7871 |
|
|
|
7872 |
|
|
/*
|
7873 |
|
|
* Some of the new Ultra2 chipsets need a longer delay after a chip
|
7874 |
|
|
* reset than just the init setup creates, so we have to delay here
|
7875 |
|
|
* before we go into a reset in order to make the chips happy.
|
7876 |
|
|
*/
|
7877 |
|
|
if (p->features & AHC_ULTRA2)
|
7878 |
|
|
mdelay(250);
|
7879 |
|
|
aic7xxx_reset_current_bus(p);
|
7880 |
|
|
|
7881 |
|
|
/*
|
7882 |
|
|
* Delay for the reset delay.
|
7883 |
|
|
*/
|
7884 |
|
|
if (!reset_delay)
|
7885 |
|
|
aic7xxx_delay(AIC7XXX_RESET_DELAY);
|
7886 |
|
|
}
|
7887 |
|
|
else
|
7888 |
|
|
{
|
7889 |
|
|
if (!reset_delay)
|
7890 |
|
|
{
|
7891 |
|
|
printk(KERN_INFO "(scsi%d) Not resetting SCSI bus. Note: Don't use "
|
7892 |
|
|
"the no_reset\n", p->host_no);
|
7893 |
|
|
printk(KERN_INFO "(scsi%d) option unless you have a verifiable need "
|
7894 |
|
|
"for it.\n", p->host_no);
|
7895 |
|
|
printk(KERN_INFO "(scsi%d) The no_reset option is known to break some "
|
7896 |
|
|
"systems,\n", p->host_no);
|
7897 |
|
|
printk(KERN_INFO "(scsi%d) and is not supported by the driver author\n",
|
7898 |
|
|
p->host_no);
|
7899 |
|
|
aic7xxx_delay(AIC7XXX_RESET_DELAY);
|
7900 |
|
|
}
|
7901 |
|
|
}
|
7902 |
|
|
|
7903 |
|
|
/*
|
7904 |
|
|
* Register IRQ with the kernel. Only allow sharing IRQs with
|
7905 |
|
|
* PCI devices.
|
7906 |
|
|
*/
|
7907 |
|
|
if (!(p->chip & AHC_PCI))
|
7908 |
|
|
{
|
7909 |
|
|
result = (request_irq(p->irq, do_aic7xxx_isr, 0, "aic7xxx", p));
|
7910 |
|
|
}
|
7911 |
|
|
else
|
7912 |
|
|
{
|
7913 |
|
|
result = (request_irq(p->irq, do_aic7xxx_isr, SA_SHIRQ,
|
7914 |
|
|
"aic7xxx", p));
|
7915 |
|
|
if (result < 0)
|
7916 |
|
|
{
|
7917 |
|
|
result = (request_irq(p->irq, do_aic7xxx_isr, SA_INTERRUPT | SA_SHIRQ,
|
7918 |
|
|
"aic7xxx", p));
|
7919 |
|
|
}
|
7920 |
|
|
}
|
7921 |
|
|
if (result < 0)
|
7922 |
|
|
{
|
7923 |
|
|
printk(KERN_WARNING "(scsi%d) Couldn't register IRQ %d, ignoring "
|
7924 |
|
|
"controller.\n", p->host_no, p->irq);
|
7925 |
|
|
p->irq = 0;
|
7926 |
|
|
return (0);
|
7927 |
|
|
}
|
7928 |
|
|
|
7929 |
|
|
unpause_sequencer(p, /* unpause_always */ TRUE);
|
7930 |
|
|
|
7931 |
|
|
return (found);
|
7932 |
|
|
}
|
7933 |
|
|
|
7934 |
|
|
/*+F*************************************************************************
|
7935 |
|
|
* Function:
|
7936 |
|
|
* aic7xxx_chip_reset
|
7937 |
|
|
*
|
7938 |
|
|
* Description:
|
7939 |
|
|
* Perform a chip reset on the aic7xxx SCSI controller. The controller
|
7940 |
|
|
* is paused upon return.
|
7941 |
|
|
*-F*************************************************************************/
|
7942 |
|
|
int
|
7943 |
|
|
aic7xxx_chip_reset(struct aic7xxx_host *p)
|
7944 |
|
|
{
|
7945 |
|
|
unsigned char sblkctl;
|
7946 |
|
|
int wait;
|
7947 |
|
|
|
7948 |
|
|
/*
|
7949 |
|
|
* For some 274x boards, we must clear the CHIPRST bit and pause
|
7950 |
|
|
* the sequencer. For some reason, this makes the driver work.
|
7951 |
|
|
*/
|
7952 |
|
|
aic_outb(p, PAUSE | CHIPRST, HCNTRL);
|
7953 |
|
|
|
7954 |
|
|
/*
|
7955 |
|
|
* In the future, we may call this function as a last resort for
|
7956 |
|
|
* error handling. Let's be nice and not do any unecessary delays.
|
7957 |
|
|
*/
|
7958 |
|
|
wait = 1000; /* 1 second (1000 * 1 msec) */
|
7959 |
|
|
while (--wait && !(aic_inb(p, HCNTRL) & CHIPRSTACK))
|
7960 |
|
|
{
|
7961 |
|
|
mdelay(1); /* 1 msec */
|
7962 |
|
|
}
|
7963 |
|
|
|
7964 |
|
|
pause_sequencer(p);
|
7965 |
|
|
|
7966 |
|
|
sblkctl = aic_inb(p, SBLKCTL) & (SELBUSB|SELWIDE);
|
7967 |
|
|
if (p->chip & AHC_PCI)
|
7968 |
|
|
sblkctl &= ~SELBUSB;
|
7969 |
|
|
switch( sblkctl )
|
7970 |
|
|
{
|
7971 |
|
|
case 0: /* normal narrow card */
|
7972 |
|
|
break;
|
7973 |
|
|
case 2: /* Wide card */
|
7974 |
|
|
p->features |= AHC_WIDE;
|
7975 |
|
|
break;
|
7976 |
|
|
case 8: /* Twin card */
|
7977 |
|
|
p->features |= AHC_TWIN;
|
7978 |
|
|
p->flags |= AHC_MULTI_CHANNEL;
|
7979 |
|
|
break;
|
7980 |
|
|
default: /* hmmm...we don't know what this is */
|
7981 |
|
|
printk(KERN_WARNING "aic7xxx: Unsupported adapter type %d, ignoring.\n",
|
7982 |
|
|
aic_inb(p, SBLKCTL) & 0x0a);
|
7983 |
|
|
return(-1);
|
7984 |
|
|
}
|
7985 |
|
|
return(0);
|
7986 |
|
|
}
|
7987 |
|
|
|
7988 |
|
|
/*+F*************************************************************************
|
7989 |
|
|
* Function:
|
7990 |
|
|
* aic7xxx_alloc
|
7991 |
|
|
*
|
7992 |
|
|
* Description:
|
7993 |
|
|
* Allocate and initialize a host structure. Returns NULL upon error
|
7994 |
|
|
* and a pointer to a aic7xxx_host struct upon success.
|
7995 |
|
|
*-F*************************************************************************/
|
7996 |
|
|
static struct aic7xxx_host *
|
7997 |
|
|
aic7xxx_alloc(Scsi_Host_Template *sht, struct aic7xxx_host *temp)
|
7998 |
|
|
{
|
7999 |
|
|
struct aic7xxx_host *p = NULL;
|
8000 |
|
|
struct Scsi_Host *host;
|
8001 |
|
|
int i;
|
8002 |
|
|
|
8003 |
|
|
/*
|
8004 |
|
|
* Allocate a storage area by registering us with the mid-level
|
8005 |
|
|
* SCSI layer.
|
8006 |
|
|
*/
|
8007 |
|
|
host = scsi_register(sht, sizeof(struct aic7xxx_host));
|
8008 |
|
|
|
8009 |
|
|
if (host != NULL)
|
8010 |
|
|
{
|
8011 |
|
|
p = (struct aic7xxx_host *) host->hostdata;
|
8012 |
|
|
memset(p, 0, sizeof(struct aic7xxx_host));
|
8013 |
|
|
*p = *temp;
|
8014 |
|
|
p->host = host;
|
8015 |
|
|
|
8016 |
|
|
p->scb_data = kmalloc(sizeof(scb_data_type), GFP_ATOMIC);
|
8017 |
|
|
if (p->scb_data != NULL)
|
8018 |
|
|
{
|
8019 |
|
|
memset(p->scb_data, 0, sizeof(scb_data_type));
|
8020 |
|
|
scbq_init (&p->scb_data->free_scbs);
|
8021 |
|
|
}
|
8022 |
|
|
else
|
8023 |
|
|
{
|
8024 |
|
|
/*
|
8025 |
|
|
* For some reason we don't have enough memory. Free the
|
8026 |
|
|
* allocated memory for the aic7xxx_host struct, and return NULL.
|
8027 |
|
|
*/
|
8028 |
|
|
release_region(p->base, MAXREG - MINREG);
|
8029 |
|
|
scsi_unregister(host);
|
8030 |
|
|
return(NULL);
|
8031 |
|
|
}
|
8032 |
|
|
p->host_no = host->host_no;
|
8033 |
|
|
p->tagenable = 0;
|
8034 |
|
|
p->orderedtag = 0;
|
8035 |
|
|
for (i=0; i<MAX_TARGETS; i++)
|
8036 |
|
|
{
|
8037 |
|
|
p->transinfo[i].goal_period = 0;
|
8038 |
|
|
p->transinfo[i].goal_offset = 0;
|
8039 |
|
|
p->transinfo[i].goal_width = MSG_EXT_WDTR_BUS_8_BIT;
|
8040 |
|
|
}
|
8041 |
|
|
DRIVER_LOCK_INIT
|
8042 |
|
|
}
|
8043 |
|
|
return (p);
|
8044 |
|
|
}
|
8045 |
|
|
|
8046 |
|
|
/*+F*************************************************************************
|
8047 |
|
|
* Function:
|
8048 |
|
|
* aic7xxx_free
|
8049 |
|
|
*
|
8050 |
|
|
* Description:
|
8051 |
|
|
* Frees and releases all resources associated with an instance of
|
8052 |
|
|
* the driver (struct aic7xxx_host *).
|
8053 |
|
|
*-F*************************************************************************/
|
8054 |
|
|
static void
|
8055 |
|
|
aic7xxx_free(struct aic7xxx_host *p)
|
8056 |
|
|
{
|
8057 |
|
|
int i;
|
8058 |
|
|
|
8059 |
|
|
/*
|
8060 |
|
|
* Free the allocated hardware SCB space.
|
8061 |
|
|
*/
|
8062 |
|
|
if (p->scb_data != NULL)
|
8063 |
|
|
{
|
8064 |
|
|
if (p->scb_data->hscbs != NULL)
|
8065 |
|
|
{
|
8066 |
|
|
kfree(p->scb_data->hscb_kmalloc_ptr);
|
8067 |
|
|
p->scb_data->hscbs = p->scb_data->hscb_kmalloc_ptr = NULL;
|
8068 |
|
|
}
|
8069 |
|
|
/*
|
8070 |
|
|
* Free the driver SCBs. These were allocated on an as-need
|
8071 |
|
|
* basis. We allocated these in groups depending on how many
|
8072 |
|
|
* we could fit into a given amount of RAM. The tail SCB for
|
8073 |
|
|
* these allocations has a pointer to the alloced area.
|
8074 |
|
|
*/
|
8075 |
|
|
for (i = 0; i < p->scb_data->numscbs; i++)
|
8076 |
|
|
{
|
8077 |
|
|
if (p->scb_data->scb_array[i]->kmalloc_ptr != NULL)
|
8078 |
|
|
kfree(p->scb_data->scb_array[i]->kmalloc_ptr);
|
8079 |
|
|
p->scb_data->scb_array[i] = NULL;
|
8080 |
|
|
}
|
8081 |
|
|
|
8082 |
|
|
/*
|
8083 |
|
|
* Free the SCB data area.
|
8084 |
|
|
*/
|
8085 |
|
|
kfree(p->scb_data);
|
8086 |
|
|
}
|
8087 |
|
|
|
8088 |
|
|
/*
|
8089 |
|
|
* Free any alloced Scsi_Cmnd structures that might be around for
|
8090 |
|
|
* negotiation purposes....
|
8091 |
|
|
*/
|
8092 |
|
|
for (i = 0; i < MAX_TARGETS; i++)
|
8093 |
|
|
{
|
8094 |
|
|
if(p->dev_wdtr_cmnd[i])
|
8095 |
|
|
kfree(p->dev_wdtr_cmnd[i]);
|
8096 |
|
|
if(p->dev_sdtr_cmnd[i])
|
8097 |
|
|
kfree(p->dev_sdtr_cmnd[i]);
|
8098 |
|
|
}
|
8099 |
|
|
|
8100 |
|
|
}
|
8101 |
|
|
|
8102 |
|
|
/*+F*************************************************************************
|
8103 |
|
|
* Function:
|
8104 |
|
|
* aic7xxx_load_seeprom
|
8105 |
|
|
*
|
8106 |
|
|
* Description:
|
8107 |
|
|
* Load the seeprom and configure adapter and target settings.
|
8108 |
|
|
* Returns 1 if the load was successful and 0 otherwise.
|
8109 |
|
|
*-F*************************************************************************/
|
8110 |
|
|
static void
|
8111 |
|
|
aic7xxx_load_seeprom(struct aic7xxx_host *p, unsigned char *sxfrctl1)
|
8112 |
|
|
{
|
8113 |
|
|
int have_seeprom = 0;
|
8114 |
|
|
int i, max_targets, mask;
|
8115 |
|
|
unsigned char scsirate, scsi_conf;
|
8116 |
|
|
unsigned short scarray[128];
|
8117 |
|
|
struct seeprom_config *sc = (struct seeprom_config *) scarray;
|
8118 |
|
|
|
8119 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
8120 |
|
|
{
|
8121 |
|
|
printk(KERN_INFO "aic7xxx: Loading serial EEPROM...");
|
8122 |
|
|
}
|
8123 |
|
|
switch (p->chip)
|
8124 |
|
|
{
|
8125 |
|
|
case (AHC_AIC7770|AHC_EISA): /* None of these adapters have seeproms. */
|
8126 |
|
|
if (aic_inb(p, SCSICONF) & TERM_ENB)
|
8127 |
|
|
p->flags |= AHC_TERM_ENB_A;
|
8128 |
|
|
if ( (p->features & AHC_TWIN) && (aic_inb(p, SCSICONF + 1) & TERM_ENB) )
|
8129 |
|
|
p->flags |= AHC_TERM_ENB_B;
|
8130 |
|
|
aic_outb(p, 0, DISC_DSB);
|
8131 |
|
|
aic_outb(p, 0, DISC_DSB + 1);
|
8132 |
|
|
break;
|
8133 |
|
|
|
8134 |
|
|
case (AHC_AIC7770|AHC_VL):
|
8135 |
|
|
have_seeprom = read_284x_seeprom(p, (struct seeprom_config *) scarray);
|
8136 |
|
|
break;
|
8137 |
|
|
|
8138 |
|
|
default:
|
8139 |
|
|
have_seeprom = read_seeprom(p, (p->flags & (AHC_CHNLB|AHC_CHNLC)),
|
8140 |
|
|
scarray, p->sc_size, p->sc_type);
|
8141 |
|
|
if (!have_seeprom)
|
8142 |
|
|
{
|
8143 |
|
|
if(p->sc_type == C46)
|
8144 |
|
|
have_seeprom = read_seeprom(p, (p->flags & (AHC_CHNLB|AHC_CHNLC)),
|
8145 |
|
|
scarray, p->sc_size, C56_66);
|
8146 |
|
|
else
|
8147 |
|
|
have_seeprom = read_seeprom(p, (p->flags & (AHC_CHNLB|AHC_CHNLC)),
|
8148 |
|
|
scarray, p->sc_size, C46);
|
8149 |
|
|
}
|
8150 |
|
|
if (!have_seeprom)
|
8151 |
|
|
{
|
8152 |
|
|
p->sc_size = 128;
|
8153 |
|
|
have_seeprom = read_seeprom(p, (p->flags & (AHC_CHNLB|AHC_CHNLC)),
|
8154 |
|
|
scarray, p->sc_size, p->sc_type);
|
8155 |
|
|
if (!have_seeprom)
|
8156 |
|
|
{
|
8157 |
|
|
if(p->sc_type == C46)
|
8158 |
|
|
have_seeprom = read_seeprom(p, (p->flags & (AHC_CHNLB|AHC_CHNLC)),
|
8159 |
|
|
scarray, p->sc_size, C56_66);
|
8160 |
|
|
else
|
8161 |
|
|
have_seeprom = read_seeprom(p, (p->flags & (AHC_CHNLB|AHC_CHNLC)),
|
8162 |
|
|
scarray, p->sc_size, C46);
|
8163 |
|
|
}
|
8164 |
|
|
}
|
8165 |
|
|
break;
|
8166 |
|
|
}
|
8167 |
|
|
|
8168 |
|
|
if (!have_seeprom)
|
8169 |
|
|
{
|
8170 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
8171 |
|
|
{
|
8172 |
|
|
printk("\naic7xxx: No SEEPROM available.\n");
|
8173 |
|
|
}
|
8174 |
|
|
p->flags |= AHC_NEWEEPROM_FMT;
|
8175 |
|
|
if (aic_inb(p, SCSISEQ) == 0)
|
8176 |
|
|
{
|
8177 |
|
|
p->flags |= AHC_USEDEFAULTS;
|
8178 |
|
|
p->flags &= ~AHC_BIOS_ENABLED;
|
8179 |
|
|
p->scsi_id = p->scsi_id_b = 7;
|
8180 |
|
|
*sxfrctl1 |= STPWEN;
|
8181 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
8182 |
|
|
{
|
8183 |
|
|
printk("aic7xxx: Using default values.\n");
|
8184 |
|
|
}
|
8185 |
|
|
}
|
8186 |
|
|
else if (aic7xxx_verbose & VERBOSE_PROBE2)
|
8187 |
|
|
{
|
8188 |
|
|
printk("aic7xxx: Using leftover BIOS values.\n");
|
8189 |
|
|
}
|
8190 |
|
|
if ( ((p->chip & ~AHC_CHIPID_MASK) == AHC_PCI) && (*sxfrctl1 & STPWEN) )
|
8191 |
|
|
{
|
8192 |
|
|
p->flags |= AHC_TERM_ENB_SE_LOW | AHC_TERM_ENB_SE_HIGH;
|
8193 |
|
|
sc->adapter_control &= ~CFAUTOTERM;
|
8194 |
|
|
sc->adapter_control |= CFSTERM | CFWSTERM | CFLVDSTERM;
|
8195 |
|
|
}
|
8196 |
|
|
if (aic7xxx_extended)
|
8197 |
|
|
p->flags |= (AHC_EXTEND_TRANS_A | AHC_EXTEND_TRANS_B);
|
8198 |
|
|
else
|
8199 |
|
|
p->flags &= ~(AHC_EXTEND_TRANS_A | AHC_EXTEND_TRANS_B);
|
8200 |
|
|
}
|
8201 |
|
|
else
|
8202 |
|
|
{
|
8203 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
8204 |
|
|
{
|
8205 |
|
|
printk("done\n");
|
8206 |
|
|
}
|
8207 |
|
|
|
8208 |
|
|
/*
|
8209 |
|
|
* Note things in our flags
|
8210 |
|
|
*/
|
8211 |
|
|
p->flags |= AHC_SEEPROM_FOUND;
|
8212 |
|
|
|
8213 |
|
|
/*
|
8214 |
|
|
* Update the settings in sxfrctl1 to match the termination settings.
|
8215 |
|
|
*/
|
8216 |
|
|
*sxfrctl1 = 0;
|
8217 |
|
|
|
8218 |
|
|
/*
|
8219 |
|
|
* Get our SCSI ID from the SEEPROM setting...
|
8220 |
|
|
*/
|
8221 |
|
|
p->scsi_id = (sc->brtime_id & CFSCSIID);
|
8222 |
|
|
|
8223 |
|
|
/*
|
8224 |
|
|
* First process the settings that are different between the VLB
|
8225 |
|
|
* and PCI adapter seeproms.
|
8226 |
|
|
*/
|
8227 |
|
|
if ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7770)
|
8228 |
|
|
{
|
8229 |
|
|
/* VLB adapter seeproms */
|
8230 |
|
|
if (sc->bios_control & CF284XEXTEND)
|
8231 |
|
|
p->flags |= AHC_EXTEND_TRANS_A;
|
8232 |
|
|
|
8233 |
|
|
if (sc->adapter_control & CF284XSTERM)
|
8234 |
|
|
{
|
8235 |
|
|
*sxfrctl1 |= STPWEN;
|
8236 |
|
|
p->flags |= AHC_TERM_ENB_SE_LOW | AHC_TERM_ENB_SE_HIGH;
|
8237 |
|
|
}
|
8238 |
|
|
}
|
8239 |
|
|
else
|
8240 |
|
|
{
|
8241 |
|
|
/* PCI adapter seeproms */
|
8242 |
|
|
if (sc->bios_control & CFEXTEND)
|
8243 |
|
|
p->flags |= AHC_EXTEND_TRANS_A;
|
8244 |
|
|
if (sc->bios_control & CFBIOSEN)
|
8245 |
|
|
p->flags |= AHC_BIOS_ENABLED;
|
8246 |
|
|
else
|
8247 |
|
|
p->flags &= ~AHC_BIOS_ENABLED;
|
8248 |
|
|
|
8249 |
|
|
if (sc->adapter_control & CFSTERM)
|
8250 |
|
|
{
|
8251 |
|
|
*sxfrctl1 |= STPWEN;
|
8252 |
|
|
p->flags |= AHC_TERM_ENB_SE_LOW | AHC_TERM_ENB_SE_HIGH;
|
8253 |
|
|
}
|
8254 |
|
|
}
|
8255 |
|
|
p->sc = *sc;
|
8256 |
|
|
}
|
8257 |
|
|
|
8258 |
|
|
p->discenable = 0;
|
8259 |
|
|
|
8260 |
|
|
/*
|
8261 |
|
|
* Limit to 16 targets just in case. The 2842 for one is known to
|
8262 |
|
|
* blow the max_targets setting, future cards might also.
|
8263 |
|
|
*/
|
8264 |
|
|
max_targets = MIN(sc->max_targets & CFMAXTARG,
|
8265 |
|
|
((p->features & (AHC_TWIN | AHC_WIDE)) ? 16 : 8));
|
8266 |
|
|
|
8267 |
|
|
if (have_seeprom)
|
8268 |
|
|
{
|
8269 |
|
|
for (i = 0; i < max_targets; i++)
|
8270 |
|
|
{
|
8271 |
|
|
if( ((p->features & AHC_ULTRA) &&
|
8272 |
|
|
!(sc->adapter_control & CFULTRAEN) &&
|
8273 |
|
|
(sc->device_flags[i] & CFSYNCHISULTRA)) ||
|
8274 |
|
|
(sc->device_flags[i] & CFNEWULTRAFORMAT) )
|
8275 |
|
|
{
|
8276 |
|
|
p->flags |= AHC_NEWEEPROM_FMT;
|
8277 |
|
|
break;
|
8278 |
|
|
}
|
8279 |
|
|
}
|
8280 |
|
|
}
|
8281 |
|
|
|
8282 |
|
|
for (i = 0; i < max_targets; i++)
|
8283 |
|
|
{
|
8284 |
|
|
mask = (0x01 << i);
|
8285 |
|
|
if (!have_seeprom)
|
8286 |
|
|
{
|
8287 |
|
|
if (aic_inb(p, SCSISEQ) != 0)
|
8288 |
|
|
{
|
8289 |
|
|
/*
|
8290 |
|
|
* OK...the BIOS set things up and left behind the settings we need.
|
8291 |
|
|
* Just make our sc->device_flags[i] entry match what the card has
|
8292 |
|
|
* set for this device.
|
8293 |
|
|
*/
|
8294 |
|
|
p->discenable =
|
8295 |
|
|
~(aic_inb(p, DISC_DSB) | (aic_inb(p, DISC_DSB + 1) << 8) );
|
8296 |
|
|
p->ultraenb =
|
8297 |
|
|
(aic_inb(p, ULTRA_ENB) | (aic_inb(p, ULTRA_ENB + 1) << 8) );
|
8298 |
|
|
sc->device_flags[i] = (p->discenable & mask) ? CFDISC : 0;
|
8299 |
|
|
if (aic_inb(p, TARG_SCSIRATE + i) & WIDEXFER)
|
8300 |
|
|
sc->device_flags[i] |= CFWIDEB;
|
8301 |
|
|
if (p->features & AHC_ULTRA2)
|
8302 |
|
|
{
|
8303 |
|
|
if (aic_inb(p, TARG_OFFSET + i))
|
8304 |
|
|
{
|
8305 |
|
|
sc->device_flags[i] |= CFSYNCH;
|
8306 |
|
|
sc->device_flags[i] |= (aic_inb(p, TARG_SCSIRATE + i) & 0x07);
|
8307 |
|
|
if ( (aic_inb(p, TARG_SCSIRATE + i) & 0x18) == 0x18 )
|
8308 |
|
|
sc->device_flags[i] |= CFSYNCHISULTRA;
|
8309 |
|
|
}
|
8310 |
|
|
}
|
8311 |
|
|
else
|
8312 |
|
|
{
|
8313 |
|
|
if (aic_inb(p, TARG_SCSIRATE + i) & ~WIDEXFER)
|
8314 |
|
|
{
|
8315 |
|
|
sc->device_flags[i] |= CFSYNCH;
|
8316 |
|
|
if (p->features & AHC_ULTRA)
|
8317 |
|
|
sc->device_flags[i] |= ((p->ultraenb & mask) ?
|
8318 |
|
|
CFSYNCHISULTRA : 0);
|
8319 |
|
|
}
|
8320 |
|
|
}
|
8321 |
|
|
}
|
8322 |
|
|
else
|
8323 |
|
|
{
|
8324 |
|
|
/*
|
8325 |
|
|
* Assume the BIOS has NOT been run on this card and nothing between
|
8326 |
|
|
* the card and the devices is configured yet.
|
8327 |
|
|
*/
|
8328 |
|
|
sc->device_flags[i] = CFDISC;
|
8329 |
|
|
if (p->features & AHC_WIDE)
|
8330 |
|
|
sc->device_flags[i] |= CFWIDEB;
|
8331 |
|
|
if (p->features & AHC_ULTRA2)
|
8332 |
|
|
sc->device_flags[i] |= 3;
|
8333 |
|
|
else if (p->features & AHC_ULTRA)
|
8334 |
|
|
sc->device_flags[i] |= CFSYNCHISULTRA;
|
8335 |
|
|
sc->device_flags[i] |= CFSYNCH;
|
8336 |
|
|
aic_outb(p, 0, TARG_SCSIRATE + i);
|
8337 |
|
|
if (p->features & AHC_ULTRA2)
|
8338 |
|
|
aic_outb(p, 0, TARG_OFFSET + i);
|
8339 |
|
|
}
|
8340 |
|
|
}
|
8341 |
|
|
if (sc->device_flags[i] & CFDISC)
|
8342 |
|
|
{
|
8343 |
|
|
p->discenable |= mask;
|
8344 |
|
|
}
|
8345 |
|
|
if (p->flags & AHC_NEWEEPROM_FMT)
|
8346 |
|
|
{
|
8347 |
|
|
if ( (sc->device_flags[i] & CFNEWULTRAFORMAT) &&
|
8348 |
|
|
!(p->features & AHC_ULTRA2) )
|
8349 |
|
|
{
|
8350 |
|
|
/*
|
8351 |
|
|
* I know of two different Ultra BIOSes that do this differently.
|
8352 |
|
|
* One on the Gigabyte 6BXU mb that wants flags[i] & CFXFER to
|
8353 |
|
|
* be == to 0x03 and SYNCISULTRA to be true to mean 40MByte/s
|
8354 |
|
|
* while on the IBM Netfinity 5000 they want the same thing
|
8355 |
|
|
* to be something else, while flags[i] & CFXFER == 0x03 and
|
8356 |
|
|
* SYNCISULTRA false should be 40MByte/s. So, we set both to
|
8357 |
|
|
* 40MByte/s and the lower speeds be damned. People will have
|
8358 |
|
|
* to select around the conversely mapped lower speeds in order
|
8359 |
|
|
* to select lower speeds on these boards.
|
8360 |
|
|
*/
|
8361 |
|
|
if ((sc->device_flags[i] & (CFXFER)) == 0x03)
|
8362 |
|
|
{
|
8363 |
|
|
sc->device_flags[i] &= ~CFXFER;
|
8364 |
|
|
sc->device_flags[i] |= CFSYNCHISULTRA;
|
8365 |
|
|
}
|
8366 |
|
|
}
|
8367 |
|
|
if (sc->device_flags[i] & CFSYNCHISULTRA)
|
8368 |
|
|
{
|
8369 |
|
|
p->ultraenb |= mask;
|
8370 |
|
|
}
|
8371 |
|
|
}
|
8372 |
|
|
else if (sc->adapter_control & CFULTRAEN)
|
8373 |
|
|
{
|
8374 |
|
|
p->ultraenb |= mask;
|
8375 |
|
|
}
|
8376 |
|
|
if ( (sc->device_flags[i] & CFSYNCH) == 0)
|
8377 |
|
|
{
|
8378 |
|
|
sc->device_flags[i] &= ~CFXFER;
|
8379 |
|
|
p->ultraenb &= ~mask;
|
8380 |
|
|
p->transinfo[i].user_offset = 0;
|
8381 |
|
|
p->transinfo[i].user_period = 0;
|
8382 |
|
|
p->transinfo[i].cur_offset = 0;
|
8383 |
|
|
p->transinfo[i].cur_period = 0;
|
8384 |
|
|
p->needsdtr_copy &= ~mask;
|
8385 |
|
|
}
|
8386 |
|
|
else
|
8387 |
|
|
{
|
8388 |
|
|
if (p->features & AHC_ULTRA2)
|
8389 |
|
|
{
|
8390 |
|
|
p->transinfo[i].user_offset = MAX_OFFSET_ULTRA2;
|
8391 |
|
|
p->transinfo[i].cur_offset = aic_inb(p, TARG_OFFSET + i);
|
8392 |
|
|
scsirate = (sc->device_flags[i] & CFXFER) |
|
8393 |
|
|
((p->ultraenb & mask) ? 0x18 : 0x10);
|
8394 |
|
|
p->transinfo[i].user_period = aic7xxx_find_period(p, scsirate,
|
8395 |
|
|
AHC_SYNCRATE_ULTRA2);
|
8396 |
|
|
p->transinfo[i].cur_period = aic7xxx_find_period(p,
|
8397 |
|
|
aic_inb(p, TARG_SCSIRATE + i),
|
8398 |
|
|
AHC_SYNCRATE_ULTRA2);
|
8399 |
|
|
}
|
8400 |
|
|
else
|
8401 |
|
|
{
|
8402 |
|
|
scsirate = (sc->device_flags[i] & CFXFER) << 4;
|
8403 |
|
|
if (sc->device_flags[i] & CFWIDEB)
|
8404 |
|
|
p->transinfo[i].user_offset = MAX_OFFSET_16BIT;
|
8405 |
|
|
else
|
8406 |
|
|
p->transinfo[i].user_offset = MAX_OFFSET_8BIT;
|
8407 |
|
|
if (p->features & AHC_ULTRA)
|
8408 |
|
|
{
|
8409 |
|
|
short ultraenb;
|
8410 |
|
|
ultraenb = aic_inb(p, ULTRA_ENB) |
|
8411 |
|
|
(aic_inb(p, ULTRA_ENB + 1) << 8);
|
8412 |
|
|
p->transinfo[i].user_period = aic7xxx_find_period(p,
|
8413 |
|
|
scsirate,
|
8414 |
|
|
(p->ultraenb & mask) ?
|
8415 |
|
|
AHC_SYNCRATE_ULTRA :
|
8416 |
|
|
AHC_SYNCRATE_FAST);
|
8417 |
|
|
p->transinfo[i].cur_period = aic7xxx_find_period(p,
|
8418 |
|
|
aic_inb(p, TARG_SCSIRATE + i),
|
8419 |
|
|
(ultraenb & mask) ?
|
8420 |
|
|
AHC_SYNCRATE_ULTRA :
|
8421 |
|
|
AHC_SYNCRATE_FAST);
|
8422 |
|
|
}
|
8423 |
|
|
else
|
8424 |
|
|
p->transinfo[i].user_period = aic7xxx_find_period(p,
|
8425 |
|
|
scsirate, AHC_SYNCRATE_FAST);
|
8426 |
|
|
}
|
8427 |
|
|
p->needsdtr_copy |= mask;
|
8428 |
|
|
}
|
8429 |
|
|
if ( (sc->device_flags[i] & CFWIDEB) && (p->features & AHC_WIDE) )
|
8430 |
|
|
{
|
8431 |
|
|
p->transinfo[i].user_width = MSG_EXT_WDTR_BUS_16_BIT;
|
8432 |
|
|
p->needwdtr_copy |= mask;
|
8433 |
|
|
}
|
8434 |
|
|
else
|
8435 |
|
|
{
|
8436 |
|
|
p->transinfo[i].user_width = MSG_EXT_WDTR_BUS_8_BIT;
|
8437 |
|
|
p->needwdtr_copy &= ~mask;
|
8438 |
|
|
}
|
8439 |
|
|
p->transinfo[i].cur_width =
|
8440 |
|
|
(aic_inb(p, TARG_SCSIRATE + i) & WIDEXFER) ?
|
8441 |
|
|
MSG_EXT_WDTR_BUS_16_BIT : MSG_EXT_WDTR_BUS_8_BIT;
|
8442 |
|
|
}
|
8443 |
|
|
aic_outb(p, ~(p->discenable & 0xFF), DISC_DSB);
|
8444 |
|
|
aic_outb(p, ~((p->discenable >> 8) & 0xFF), DISC_DSB + 1);
|
8445 |
|
|
p->needwdtr = p->needwdtr_copy;
|
8446 |
|
|
p->needsdtr = p->needsdtr_copy;
|
8447 |
|
|
p->wdtr_pending = p->sdtr_pending = 0;
|
8448 |
|
|
|
8449 |
|
|
/*
|
8450 |
|
|
* We set the p->ultraenb from the SEEPROM to begin with, but now we make
|
8451 |
|
|
* it match what is already down in the card. If we are doing a reset
|
8452 |
|
|
* on the card then this will get put back to a default state anyway.
|
8453 |
|
|
* This allows us to not have to pre-emptively negotiate when using the
|
8454 |
|
|
* no_reset option.
|
8455 |
|
|
*/
|
8456 |
|
|
if (p->features & AHC_ULTRA)
|
8457 |
|
|
p->ultraenb = aic_inb(p, ULTRA_ENB) | (aic_inb(p, ULTRA_ENB + 1) << 8);
|
8458 |
|
|
|
8459 |
|
|
|
8460 |
|
|
scsi_conf = (p->scsi_id & HSCSIID);
|
8461 |
|
|
|
8462 |
|
|
if(have_seeprom)
|
8463 |
|
|
{
|
8464 |
|
|
p->adapter_control = sc->adapter_control;
|
8465 |
|
|
p->bios_control = sc->bios_control;
|
8466 |
|
|
|
8467 |
|
|
switch (p->chip & AHC_CHIPID_MASK)
|
8468 |
|
|
{
|
8469 |
|
|
case AHC_AIC7895:
|
8470 |
|
|
case AHC_AIC7896:
|
8471 |
|
|
if (p->adapter_control & CFBPRIMARY)
|
8472 |
|
|
p->flags |= AHC_CHANNEL_B_PRIMARY;
|
8473 |
|
|
default:
|
8474 |
|
|
break;
|
8475 |
|
|
}
|
8476 |
|
|
|
8477 |
|
|
if (sc->adapter_control & CFSPARITY)
|
8478 |
|
|
scsi_conf |= ENSPCHK;
|
8479 |
|
|
}
|
8480 |
|
|
else
|
8481 |
|
|
{
|
8482 |
|
|
scsi_conf |= ENSPCHK | RESET_SCSI;
|
8483 |
|
|
}
|
8484 |
|
|
|
8485 |
|
|
/*
|
8486 |
|
|
* Only set the SCSICONF and SCSICONF + 1 registers if we are a PCI card.
|
8487 |
|
|
* The 2842 and 2742 cards already have these registers set and we don't
|
8488 |
|
|
* want to muck with them since we don't set all the bits they do.
|
8489 |
|
|
*/
|
8490 |
|
|
if ( (p->chip & ~AHC_CHIPID_MASK) == AHC_PCI )
|
8491 |
|
|
{
|
8492 |
|
|
/* Set the host ID */
|
8493 |
|
|
aic_outb(p, scsi_conf, SCSICONF);
|
8494 |
|
|
/* In case we are a wide card */
|
8495 |
|
|
aic_outb(p, p->scsi_id, SCSICONF + 1);
|
8496 |
|
|
}
|
8497 |
|
|
}
|
8498 |
|
|
|
8499 |
|
|
/*+F*************************************************************************
|
8500 |
|
|
* Function:
|
8501 |
|
|
* aic7xxx_detect
|
8502 |
|
|
*
|
8503 |
|
|
* Description:
|
8504 |
|
|
* Try to detect and register an Adaptec 7770 or 7870 SCSI controller.
|
8505 |
|
|
*
|
8506 |
|
|
* XXX - This should really be called aic7xxx_probe(). A sequence of
|
8507 |
|
|
* probe(), attach()/detach(), and init() makes more sense than
|
8508 |
|
|
* one do-it-all function. This may be useful when (and if) the
|
8509 |
|
|
* mid-level SCSI code is overhauled.
|
8510 |
|
|
*-F*************************************************************************/
|
8511 |
|
|
int
|
8512 |
|
|
aic7xxx_detect(Scsi_Host_Template *template)
|
8513 |
|
|
{
|
8514 |
|
|
struct aic7xxx_host *temp_p = NULL;
|
8515 |
|
|
struct aic7xxx_host *current_p = NULL;
|
8516 |
|
|
struct aic7xxx_host *list_p = NULL;
|
8517 |
|
|
int found = 0;
|
8518 |
|
|
#if defined(__i386__) || defined(__alpha__)
|
8519 |
|
|
ahc_flag_type flags = 0;
|
8520 |
|
|
int type;
|
8521 |
|
|
#endif
|
8522 |
|
|
unsigned char sxfrctl1;
|
8523 |
|
|
#if defined(__i386__) || defined(__alpha__)
|
8524 |
|
|
unsigned char hcntrl, hostconf;
|
8525 |
|
|
unsigned int slot, base;
|
8526 |
|
|
#endif
|
8527 |
|
|
|
8528 |
|
|
#ifdef MODULE
|
8529 |
|
|
/*
|
8530 |
|
|
* If we are called as a module, the aic7xxx pointer may not be null
|
8531 |
|
|
* and it would point to our bootup string, just like on the lilo
|
8532 |
|
|
* command line. IF not NULL, then process this config string with
|
8533 |
|
|
* aic7xxx_setup
|
8534 |
|
|
*/
|
8535 |
|
|
if(aic7xxx)
|
8536 |
|
|
aic7xxx_setup(aic7xxx, NULL);
|
8537 |
|
|
if(dummy_buffer[0] != 'P')
|
8538 |
|
|
printk(KERN_WARNING "aic7xxx: Please read the file /usr/src/linux/drivers"
|
8539 |
|
|
"/scsi/README.aic7xxx\n"
|
8540 |
|
|
"aic7xxx: to see the proper way to specify options to the aic7xxx "
|
8541 |
|
|
"module\n"
|
8542 |
|
|
"aic7xxx: Specifically, don't use any commas when passing arguments to\n"
|
8543 |
|
|
"aic7xxx: insmod or else it might trash certain memory areas.\n");
|
8544 |
|
|
#endif
|
8545 |
|
|
|
8546 |
|
|
template->proc_dir = &proc_scsi_aic7xxx;
|
8547 |
|
|
template->sg_tablesize = AIC7XXX_MAX_SG;
|
8548 |
|
|
|
8549 |
|
|
|
8550 |
|
|
#if defined(__i386__) || defined(__alpha__)
|
8551 |
|
|
/*
|
8552 |
|
|
* EISA/VL-bus card signature probe.
|
8553 |
|
|
*/
|
8554 |
|
|
slot = MINSLOT;
|
8555 |
|
|
while ( (slot <= MAXSLOT) && !(aic7xxx_no_probe) )
|
8556 |
|
|
{
|
8557 |
|
|
base = SLOTBASE(slot) + MINREG;
|
8558 |
|
|
|
8559 |
|
|
if (check_region(base, MAXREG - MINREG))
|
8560 |
|
|
{
|
8561 |
|
|
/*
|
8562 |
|
|
* Some other driver has staked a
|
8563 |
|
|
* claim to this i/o region already.
|
8564 |
|
|
*/
|
8565 |
|
|
slot++;
|
8566 |
|
|
continue; /* back to the beginning of the for loop */
|
8567 |
|
|
}
|
8568 |
|
|
flags = 0;
|
8569 |
|
|
type = aic7xxx_probe(slot, base + AHC_HID0, &flags);
|
8570 |
|
|
if (type == -1)
|
8571 |
|
|
{
|
8572 |
|
|
slot++;
|
8573 |
|
|
continue;
|
8574 |
|
|
}
|
8575 |
|
|
temp_p = kmalloc(sizeof(struct aic7xxx_host), GFP_ATOMIC);
|
8576 |
|
|
if (temp_p == NULL)
|
8577 |
|
|
{
|
8578 |
|
|
printk(KERN_WARNING "aic7xxx: Unable to allocate device space.\n");
|
8579 |
|
|
slot++;
|
8580 |
|
|
continue; /* back to the beginning of the while loop */
|
8581 |
|
|
}
|
8582 |
|
|
/*
|
8583 |
|
|
* Pause the card preserving the IRQ type. Allow the operator
|
8584 |
|
|
* to override the IRQ trigger.
|
8585 |
|
|
*/
|
8586 |
|
|
if (aic7xxx_irq_trigger == 1)
|
8587 |
|
|
hcntrl = IRQMS; /* Level */
|
8588 |
|
|
else if (aic7xxx_irq_trigger == 0)
|
8589 |
|
|
hcntrl = 0; /* Edge */
|
8590 |
|
|
else
|
8591 |
|
|
hcntrl = inb(base + HCNTRL) & IRQMS; /* Default */
|
8592 |
|
|
memset(temp_p, 0, sizeof(struct aic7xxx_host));
|
8593 |
|
|
temp_p->unpause = hcntrl | INTEN;
|
8594 |
|
|
temp_p->pause = hcntrl | PAUSE | INTEN;
|
8595 |
|
|
temp_p->base = base;
|
8596 |
|
|
temp_p->mbase = 0;
|
8597 |
|
|
temp_p->maddr = 0;
|
8598 |
|
|
temp_p->pci_bus = 0;
|
8599 |
|
|
temp_p->pci_device_fn = slot;
|
8600 |
|
|
aic_outb(temp_p, hcntrl | PAUSE, HCNTRL);
|
8601 |
|
|
while( (aic_inb(temp_p, HCNTRL) & PAUSE) == 0 ) ;
|
8602 |
|
|
if (aic7xxx_chip_reset(temp_p) == -1)
|
8603 |
|
|
temp_p->irq = 0;
|
8604 |
|
|
else
|
8605 |
|
|
temp_p->irq = aic_inb(temp_p, INTDEF) & 0x0F;
|
8606 |
|
|
temp_p->flags |= AHC_PAGESCBS;
|
8607 |
|
|
|
8608 |
|
|
switch (temp_p->irq)
|
8609 |
|
|
{
|
8610 |
|
|
case 9:
|
8611 |
|
|
case 10:
|
8612 |
|
|
case 11:
|
8613 |
|
|
case 12:
|
8614 |
|
|
case 14:
|
8615 |
|
|
case 15:
|
8616 |
|
|
break;
|
8617 |
|
|
|
8618 |
|
|
default:
|
8619 |
|
|
printk(KERN_WARNING "aic7xxx: Host adapter uses unsupported IRQ "
|
8620 |
|
|
"level %d, ignoring.\n", temp_p->irq);
|
8621 |
|
|
kfree(temp_p);
|
8622 |
|
|
slot++;
|
8623 |
|
|
continue; /* back to the beginning of the while loop */
|
8624 |
|
|
}
|
8625 |
|
|
|
8626 |
|
|
/*
|
8627 |
|
|
* We are commited now, everything has been checked and this card
|
8628 |
|
|
* has been found, now we just set it up
|
8629 |
|
|
*/
|
8630 |
|
|
|
8631 |
|
|
/*
|
8632 |
|
|
* Insert our new struct into the list at the end
|
8633 |
|
|
*/
|
8634 |
|
|
if (list_p == NULL)
|
8635 |
|
|
{
|
8636 |
|
|
list_p = current_p = temp_p;
|
8637 |
|
|
}
|
8638 |
|
|
else
|
8639 |
|
|
{
|
8640 |
|
|
current_p = list_p;
|
8641 |
|
|
while (current_p->next != NULL)
|
8642 |
|
|
current_p = current_p->next;
|
8643 |
|
|
current_p->next = temp_p;
|
8644 |
|
|
}
|
8645 |
|
|
|
8646 |
|
|
switch (type)
|
8647 |
|
|
{
|
8648 |
|
|
case 0:
|
8649 |
|
|
temp_p->board_name_index = 2;
|
8650 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
8651 |
|
|
printk("aic7xxx: <%s> at EISA %d\n",
|
8652 |
|
|
board_names[2], slot);
|
8653 |
|
|
/* FALLTHROUGH */
|
8654 |
|
|
case 1:
|
8655 |
|
|
{
|
8656 |
|
|
temp_p->chip = AHC_AIC7770 | AHC_EISA;
|
8657 |
|
|
temp_p->features |= AHC_AIC7770_FE;
|
8658 |
|
|
temp_p->bios_control = aic_inb(temp_p, HA_274_BIOSCTRL);
|
8659 |
|
|
|
8660 |
|
|
/*
|
8661 |
|
|
* Get the primary channel information. Right now we don't
|
8662 |
|
|
* do anything with this, but someday we will be able to inform
|
8663 |
|
|
* the mid-level SCSI code which channel is primary.
|
8664 |
|
|
*/
|
8665 |
|
|
if (temp_p->board_name_index == 0)
|
8666 |
|
|
{
|
8667 |
|
|
temp_p->board_name_index = 3;
|
8668 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
8669 |
|
|
printk("aic7xxx: <%s> at EISA %d\n",
|
8670 |
|
|
board_names[3], slot);
|
8671 |
|
|
}
|
8672 |
|
|
if (temp_p->bios_control & CHANNEL_B_PRIMARY)
|
8673 |
|
|
{
|
8674 |
|
|
temp_p->flags |= AHC_CHANNEL_B_PRIMARY;
|
8675 |
|
|
}
|
8676 |
|
|
|
8677 |
|
|
if ((temp_p->bios_control & BIOSMODE) == BIOSDISABLED)
|
8678 |
|
|
{
|
8679 |
|
|
temp_p->flags &= ~AHC_BIOS_ENABLED;
|
8680 |
|
|
}
|
8681 |
|
|
else
|
8682 |
|
|
{
|
8683 |
|
|
temp_p->flags &= ~AHC_USEDEFAULTS;
|
8684 |
|
|
temp_p->flags |= AHC_BIOS_ENABLED;
|
8685 |
|
|
if ( (temp_p->bios_control & 0x20) == 0 )
|
8686 |
|
|
{
|
8687 |
|
|
temp_p->bios_address = 0xcc000;
|
8688 |
|
|
temp_p->bios_address += (0x4000 * (temp_p->bios_control & 0x07));
|
8689 |
|
|
}
|
8690 |
|
|
else
|
8691 |
|
|
{
|
8692 |
|
|
temp_p->bios_address = 0xd0000;
|
8693 |
|
|
temp_p->bios_address += (0x8000 * (temp_p->bios_control & 0x06));
|
8694 |
|
|
}
|
8695 |
|
|
}
|
8696 |
|
|
temp_p->adapter_control = aic_inb(temp_p, SCSICONF) << 8;
|
8697 |
|
|
temp_p->adapter_control |= aic_inb(temp_p, SCSICONF + 1);
|
8698 |
|
|
if (temp_p->features & AHC_WIDE)
|
8699 |
|
|
{
|
8700 |
|
|
temp_p->scsi_id = temp_p->adapter_control & HWSCSIID;
|
8701 |
|
|
temp_p->scsi_id_b = temp_p->scsi_id;
|
8702 |
|
|
}
|
8703 |
|
|
else
|
8704 |
|
|
{
|
8705 |
|
|
temp_p->scsi_id = (temp_p->adapter_control >> 8) & HSCSIID;
|
8706 |
|
|
temp_p->scsi_id_b = temp_p->adapter_control & HSCSIID;
|
8707 |
|
|
}
|
8708 |
|
|
aic7xxx_load_seeprom(temp_p, &sxfrctl1);
|
8709 |
|
|
break;
|
8710 |
|
|
}
|
8711 |
|
|
|
8712 |
|
|
case 2:
|
8713 |
|
|
case 3:
|
8714 |
|
|
temp_p->chip = AHC_AIC7770 | AHC_VL;
|
8715 |
|
|
temp_p->features |= AHC_AIC7770_FE;
|
8716 |
|
|
if (type == 2)
|
8717 |
|
|
temp_p->flags |= AHC_BIOS_ENABLED;
|
8718 |
|
|
else
|
8719 |
|
|
temp_p->flags &= ~AHC_BIOS_ENABLED;
|
8720 |
|
|
if (aic_inb(temp_p, SCSICONF) & TERM_ENB)
|
8721 |
|
|
sxfrctl1 = STPWEN;
|
8722 |
|
|
aic7xxx_load_seeprom(temp_p, &sxfrctl1);
|
8723 |
|
|
temp_p->board_name_index = 4;
|
8724 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
8725 |
|
|
printk("aic7xxx: <%s> at VLB %d\n",
|
8726 |
|
|
board_names[2], slot);
|
8727 |
|
|
switch( aic_inb(temp_p, STATUS_2840) & BIOS_SEL )
|
8728 |
|
|
{
|
8729 |
|
|
case 0x00:
|
8730 |
|
|
temp_p->bios_address = 0xe0000;
|
8731 |
|
|
break;
|
8732 |
|
|
case 0x20:
|
8733 |
|
|
temp_p->bios_address = 0xc8000;
|
8734 |
|
|
break;
|
8735 |
|
|
case 0x40:
|
8736 |
|
|
temp_p->bios_address = 0xd0000;
|
8737 |
|
|
break;
|
8738 |
|
|
case 0x60:
|
8739 |
|
|
temp_p->bios_address = 0xd8000;
|
8740 |
|
|
break;
|
8741 |
|
|
default:
|
8742 |
|
|
break; /* can't get here */
|
8743 |
|
|
}
|
8744 |
|
|
break;
|
8745 |
|
|
|
8746 |
|
|
default: /* Won't get here. */
|
8747 |
|
|
break;
|
8748 |
|
|
}
|
8749 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
8750 |
|
|
{
|
8751 |
|
|
printk(KERN_INFO "aic7xxx: BIOS %sabled, IO Port 0x%lx, IRQ %d (%s)\n",
|
8752 |
|
|
(temp_p->flags & AHC_USEDEFAULTS) ? "dis" : "en", temp_p->base,
|
8753 |
|
|
temp_p->irq,
|
8754 |
|
|
(temp_p->pause & IRQMS) ? "level sensitive" : "edge triggered");
|
8755 |
|
|
printk(KERN_INFO "aic7xxx: Extended translation %sabled.\n",
|
8756 |
|
|
(temp_p->flags & AHC_EXTEND_TRANS_A) ? "en" : "dis");
|
8757 |
|
|
}
|
8758 |
|
|
|
8759 |
|
|
/*
|
8760 |
|
|
* Set the FIFO threshold and the bus off time.
|
8761 |
|
|
*/
|
8762 |
|
|
hostconf = aic_inb(temp_p, HOSTCONF);
|
8763 |
|
|
aic_outb(temp_p, hostconf & DFTHRSH, BUSSPD);
|
8764 |
|
|
aic_outb(temp_p, (hostconf << 2) & BOFF, BUSTIME);
|
8765 |
|
|
slot++;
|
8766 |
|
|
found++;
|
8767 |
|
|
}
|
8768 |
|
|
|
8769 |
|
|
#endif /* defined(__i386__) || defined(__alpha__) */
|
8770 |
|
|
|
8771 |
|
|
#ifdef CONFIG_PCI
|
8772 |
|
|
/*
|
8773 |
|
|
* PCI-bus probe.
|
8774 |
|
|
*/
|
8775 |
|
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
|
8776 |
|
|
if (pci_present())
|
8777 |
|
|
#else
|
8778 |
|
|
if (pcibios_present())
|
8779 |
|
|
#endif
|
8780 |
|
|
{
|
8781 |
|
|
struct
|
8782 |
|
|
{
|
8783 |
|
|
unsigned short vendor_id;
|
8784 |
|
|
unsigned short device_id;
|
8785 |
|
|
ahc_chip chip;
|
8786 |
|
|
ahc_flag_type flags;
|
8787 |
|
|
ahc_feature features;
|
8788 |
|
|
int board_name_index;
|
8789 |
|
|
unsigned short seeprom_size;
|
8790 |
|
|
unsigned short seeprom_type;
|
8791 |
|
|
} const aic_pdevs[] = {
|
8792 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7810, AHC_NONE,
|
8793 |
|
|
AHC_FNONE, AHC_FENONE, 1,
|
8794 |
|
|
32, C46 },
|
8795 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7850, AHC_AIC7850,
|
8796 |
|
|
AHC_PAGESCBS, AHC_AIC7850_FE, 5,
|
8797 |
|
|
32, C46 },
|
8798 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7855, AHC_AIC7850,
|
8799 |
|
|
AHC_PAGESCBS, AHC_AIC7850_FE, 6,
|
8800 |
|
|
32, C46 },
|
8801 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7821, AHC_AIC7860,
|
8802 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8803 |
|
|
AHC_AIC7860_FE, 7,
|
8804 |
|
|
32, C46 },
|
8805 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_3860, AHC_AIC7860,
|
8806 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8807 |
|
|
AHC_AIC7860_FE, 7,
|
8808 |
|
|
32, C46 },
|
8809 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7860, AHC_AIC7860,
|
8810 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8811 |
|
|
AHC_AIC7860_FE, 7,
|
8812 |
|
|
32, C46 },
|
8813 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7861, AHC_AIC7860,
|
8814 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8815 |
|
|
AHC_AIC7860_FE, 8,
|
8816 |
|
|
32, C46 },
|
8817 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7870, AHC_AIC7870,
|
8818 |
|
|
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7870_FE, 9,
|
8819 |
|
|
32, C46 },
|
8820 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7871, AHC_AIC7870,
|
8821 |
|
|
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7870_FE, 10,
|
8822 |
|
|
32, C46 },
|
8823 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7872, AHC_AIC7870,
|
8824 |
|
|
AHC_PAGESCBS | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
|
8825 |
|
|
AHC_AIC7870_FE, 11,
|
8826 |
|
|
32, C56_66 },
|
8827 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7873, AHC_AIC7870,
|
8828 |
|
|
AHC_PAGESCBS | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
|
8829 |
|
|
AHC_AIC7870_FE, 12,
|
8830 |
|
|
32, C56_66 },
|
8831 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7874, AHC_AIC7870,
|
8832 |
|
|
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7870_FE, 13,
|
8833 |
|
|
32, C46 },
|
8834 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7880, AHC_AIC7880,
|
8835 |
|
|
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 14,
|
8836 |
|
|
32, C46 },
|
8837 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7881, AHC_AIC7880,
|
8838 |
|
|
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 15,
|
8839 |
|
|
32, C46 },
|
8840 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7882, AHC_AIC7880,
|
8841 |
|
|
AHC_PAGESCBS | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
|
8842 |
|
|
AHC_AIC7880_FE, 16,
|
8843 |
|
|
32, C56_66 },
|
8844 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7883, AHC_AIC7880,
|
8845 |
|
|
AHC_PAGESCBS | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
|
8846 |
|
|
AHC_AIC7880_FE, 17,
|
8847 |
|
|
32, C56_66 },
|
8848 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7884, AHC_AIC7880,
|
8849 |
|
|
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 18,
|
8850 |
|
|
32, C46 },
|
8851 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7885, AHC_AIC7880,
|
8852 |
|
|
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 18,
|
8853 |
|
|
32, C46 },
|
8854 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7886, AHC_AIC7880,
|
8855 |
|
|
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 18,
|
8856 |
|
|
32, C46 },
|
8857 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7887, AHC_AIC7880,
|
8858 |
|
|
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 18,
|
8859 |
|
|
32, C46 },
|
8860 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7888, AHC_AIC7880,
|
8861 |
|
|
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 18,
|
8862 |
|
|
32, C46 },
|
8863 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7895, AHC_AIC7895,
|
8864 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
|
8865 |
|
|
AHC_AIC7895_FE, 19,
|
8866 |
|
|
32, C56_66 },
|
8867 |
|
|
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7890, AHC_AIC7890,
|
8868 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8869 |
|
|
AHC_AIC7890_FE, 20,
|
8870 |
|
|
32, C46 },
|
8871 |
|
|
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7890B, AHC_AIC7890,
|
8872 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8873 |
|
|
AHC_AIC7890_FE, 20,
|
8874 |
|
|
32, C46 },
|
8875 |
|
|
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_2930U2, AHC_AIC7890,
|
8876 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8877 |
|
|
AHC_AIC7890_FE, 21,
|
8878 |
|
|
32, C46 },
|
8879 |
|
|
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_2940U2, AHC_AIC7890,
|
8880 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8881 |
|
|
AHC_AIC7890_FE, 22,
|
8882 |
|
|
32, C46 },
|
8883 |
|
|
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7896, AHC_AIC7896,
|
8884 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
|
8885 |
|
|
AHC_AIC7896_FE, 23,
|
8886 |
|
|
32, C56_66 },
|
8887 |
|
|
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_3940U2, AHC_AIC7896,
|
8888 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
|
8889 |
|
|
AHC_AIC7896_FE, 24,
|
8890 |
|
|
32, C56_66 },
|
8891 |
|
|
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_3950U2D, AHC_AIC7896,
|
8892 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
|
8893 |
|
|
AHC_AIC7896_FE, 25,
|
8894 |
|
|
32, C56_66 },
|
8895 |
|
|
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_1480A, AHC_AIC7860,
|
8896 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8897 |
|
|
AHC_AIC7860_FE, 26,
|
8898 |
|
|
32, C46 },
|
8899 |
|
|
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7892A, AHC_AIC7892,
|
8900 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8901 |
|
|
AHC_AIC7892_FE, 27,
|
8902 |
|
|
32, C46 },
|
8903 |
|
|
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7892B, AHC_AIC7892,
|
8904 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8905 |
|
|
AHC_AIC7892_FE, 27,
|
8906 |
|
|
32, C46 },
|
8907 |
|
|
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7892D, AHC_AIC7892,
|
8908 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8909 |
|
|
AHC_AIC7892_FE, 27,
|
8910 |
|
|
32, C46 },
|
8911 |
|
|
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7892P, AHC_AIC7892,
|
8912 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8913 |
|
|
AHC_AIC7892_FE, 27,
|
8914 |
|
|
32, C46 },
|
8915 |
|
|
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7899A, AHC_AIC7899,
|
8916 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8917 |
|
|
AHC_AIC7899_FE, 28,
|
8918 |
|
|
32, C56_66 },
|
8919 |
|
|
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7899B, AHC_AIC7899,
|
8920 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8921 |
|
|
AHC_AIC7899_FE, 28,
|
8922 |
|
|
32, C56_66 },
|
8923 |
|
|
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7899D, AHC_AIC7899,
|
8924 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8925 |
|
|
AHC_AIC7899_FE, 28,
|
8926 |
|
|
32, C56_66 },
|
8927 |
|
|
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7899P, AHC_AIC7899,
|
8928 |
|
|
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
|
8929 |
|
|
AHC_AIC7899_FE, 28,
|
8930 |
|
|
32, C56_66 },
|
8931 |
|
|
};
|
8932 |
|
|
|
8933 |
|
|
unsigned short command;
|
8934 |
|
|
unsigned int devconfig, i, oldverbose;
|
8935 |
|
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
|
8936 |
|
|
struct pci_dev *pdev = NULL;
|
8937 |
|
|
#else
|
8938 |
|
|
int index;
|
8939 |
|
|
unsigned int piobase, mmapbase;
|
8940 |
|
|
unsigned char pci_bus, pci_devfn, pci_irq;
|
8941 |
|
|
#endif
|
8942 |
|
|
|
8943 |
|
|
for (i = 0; i < NUMBER(aic_pdevs); i++)
|
8944 |
|
|
{
|
8945 |
|
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
|
8946 |
|
|
pdev = NULL;
|
8947 |
|
|
while ((pdev = pci_find_device(aic_pdevs[i].vendor_id,
|
8948 |
|
|
aic_pdevs[i].device_id,
|
8949 |
|
|
pdev)))
|
8950 |
|
|
#else
|
8951 |
|
|
index = 0;
|
8952 |
|
|
while (!(pcibios_find_device(aic_pdevs[i].vendor_id,
|
8953 |
|
|
aic_pdevs[i].device_id,
|
8954 |
|
|
index++, &pci_bus, &pci_devfn)) )
|
8955 |
|
|
#endif
|
8956 |
|
|
{
|
8957 |
|
|
if ( i == 0 ) /* We found one, but it's the 7810 RAID cont. */
|
8958 |
|
|
{
|
8959 |
|
|
if (aic7xxx_verbose & (VERBOSE_PROBE|VERBOSE_PROBE2))
|
8960 |
|
|
{
|
8961 |
|
|
printk(KERN_INFO "aic7xxx: The 7810 RAID controller is not "
|
8962 |
|
|
"supported by\n");
|
8963 |
|
|
printk(KERN_INFO " this driver, we are ignoring it.\n");
|
8964 |
|
|
}
|
8965 |
|
|
}
|
8966 |
|
|
else if ( (temp_p = kmalloc(sizeof(struct aic7xxx_host),
|
8967 |
|
|
GFP_ATOMIC)) != NULL )
|
8968 |
|
|
{
|
8969 |
|
|
memset(temp_p, 0, sizeof(struct aic7xxx_host));
|
8970 |
|
|
temp_p->chip = aic_pdevs[i].chip | AHC_PCI;
|
8971 |
|
|
temp_p->flags = aic_pdevs[i].flags;
|
8972 |
|
|
temp_p->features = aic_pdevs[i].features;
|
8973 |
|
|
temp_p->board_name_index = aic_pdevs[i].board_name_index;
|
8974 |
|
|
temp_p->sc_size = aic_pdevs[i].seeprom_size;
|
8975 |
|
|
temp_p->sc_type = aic_pdevs[i].seeprom_type;
|
8976 |
|
|
|
8977 |
|
|
/*
|
8978 |
|
|
* Read sundry information from PCI BIOS.
|
8979 |
|
|
*/
|
8980 |
|
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
|
8981 |
|
|
temp_p->irq = pdev->irq;
|
8982 |
|
|
temp_p->pdev = pdev;
|
8983 |
|
|
temp_p->pci_bus = pdev->bus->number;
|
8984 |
|
|
temp_p->pci_device_fn = pdev->devfn;
|
8985 |
|
|
temp_p->base = pdev->base_address[0];
|
8986 |
|
|
temp_p->mbase = pdev->base_address[1];
|
8987 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
8988 |
|
|
printk("aic7xxx: <%s> at PCI %d/%d\n",
|
8989 |
|
|
board_names[aic_pdevs[i].board_name_index],
|
8990 |
|
|
PCI_SLOT(temp_p->pdev->devfn),
|
8991 |
|
|
PCI_FUNC(temp_p->pdev->devfn));
|
8992 |
|
|
pci_read_config_word(pdev, PCI_COMMAND, &command);
|
8993 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
8994 |
|
|
{
|
8995 |
|
|
printk("aic7xxx: Initial PCI_COMMAND value was 0x%x\n",
|
8996 |
|
|
(int)command);
|
8997 |
|
|
}
|
8998 |
|
|
#ifdef AIC7XXX_STRICT_PCI_SETUP
|
8999 |
|
|
command |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
|
9000 |
|
|
PCI_COMMAND_INVALIDATE | PCI_COMMAND_MASTER |
|
9001 |
|
|
PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
|
9002 |
|
|
#else
|
9003 |
|
|
command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
|
9004 |
|
|
#endif
|
9005 |
|
|
if (aic7xxx_pci_parity == 0)
|
9006 |
|
|
command &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
|
9007 |
|
|
pci_write_config_word(pdev, PCI_COMMAND, command);
|
9008 |
|
|
#ifdef AIC7XXX_STRICT_PCI_SETUP
|
9009 |
|
|
pci_read_config_dword(pdev, DEVCONFIG, &devconfig);
|
9010 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
9011 |
|
|
{
|
9012 |
|
|
printk("aic7xxx: Initial DEVCONFIG value was 0x%x\n", devconfig);
|
9013 |
|
|
}
|
9014 |
|
|
devconfig |= 0x80000000;
|
9015 |
|
|
if ((aic7xxx_pci_parity == 0) || (aic7xxx_pci_parity == -1))
|
9016 |
|
|
{
|
9017 |
|
|
devconfig &= ~(0x00000008);
|
9018 |
|
|
}
|
9019 |
|
|
else
|
9020 |
|
|
{
|
9021 |
|
|
devconfig |= 0x00000008;
|
9022 |
|
|
}
|
9023 |
|
|
pci_write_config_dword(pdev, DEVCONFIG, devconfig);
|
9024 |
|
|
#endif /* AIC7XXX_STRICT_PCI_SETUP */
|
9025 |
|
|
#else /* LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) */
|
9026 |
|
|
temp_p->pci_bus = pci_bus;
|
9027 |
|
|
temp_p->pci_device_fn = pci_devfn;
|
9028 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
9029 |
|
|
printk("aic7xxx: <%s> at PCI %d/%d\n",
|
9030 |
|
|
board_names[aic_pdevs[i].board_name_index],
|
9031 |
|
|
PCI_SLOT(temp_p->pci_device_fn),
|
9032 |
|
|
PCI_FUNC(temp_p->pci_device_fn));
|
9033 |
|
|
pcibios_read_config_byte(pci_bus, pci_devfn, PCI_INTERRUPT_LINE,
|
9034 |
|
|
&pci_irq);
|
9035 |
|
|
temp_p->irq = pci_irq;
|
9036 |
|
|
pcibios_read_config_dword(pci_bus, pci_devfn, PCI_BASE_ADDRESS_0,
|
9037 |
|
|
&piobase);
|
9038 |
|
|
temp_p->base = piobase;
|
9039 |
|
|
pcibios_read_config_dword(pci_bus, pci_devfn, PCI_BASE_ADDRESS_1,
|
9040 |
|
|
&mmapbase);
|
9041 |
|
|
temp_p->mbase = mmapbase;
|
9042 |
|
|
pcibios_read_config_word(pci_bus, pci_devfn, PCI_COMMAND, &command);
|
9043 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
9044 |
|
|
{
|
9045 |
|
|
printk("aic7xxx: Initial PCI_COMMAND value was 0x%x\n",
|
9046 |
|
|
(int)command);
|
9047 |
|
|
}
|
9048 |
|
|
#ifdef AIC7XXX_STRICT_PCI_SETUP
|
9049 |
|
|
command |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
|
9050 |
|
|
PCI_COMMAND_INVALIDATE | PCI_COMMAND_MASTER |
|
9051 |
|
|
PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
|
9052 |
|
|
#else
|
9053 |
|
|
command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
|
9054 |
|
|
#endif
|
9055 |
|
|
if (aic7xxx_pci_parity == 0)
|
9056 |
|
|
command &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
|
9057 |
|
|
pcibios_write_config_word(pci_bus, pci_devfn, PCI_COMMAND, command);
|
9058 |
|
|
#ifdef AIC7XXX_STRICT_PCI_SETUP
|
9059 |
|
|
pcibios_read_config_dword(pci_bus, pci_devfn, DEVCONFIG, &devconfig);
|
9060 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
9061 |
|
|
{
|
9062 |
|
|
printk("aic7xxx: Initial DEVCONFIG value was 0x%x\n", devconfig);
|
9063 |
|
|
}
|
9064 |
|
|
devconfig |= 0x80000000;
|
9065 |
|
|
if ((aic7xxx_pci_parity == 0) || (aic7xxx_pci_parity == -1))
|
9066 |
|
|
{
|
9067 |
|
|
devconfig &= ~(0x00000008);
|
9068 |
|
|
}
|
9069 |
|
|
else
|
9070 |
|
|
{
|
9071 |
|
|
devconfig |= 0x00000008;
|
9072 |
|
|
}
|
9073 |
|
|
pcibios_write_config_dword(pci_bus, pci_devfn, DEVCONFIG, devconfig);
|
9074 |
|
|
#endif /* AIC7XXX_STRICT_PCI_SETUP */
|
9075 |
|
|
#endif /* LINUIX_VERSION_CODE > KERNEL_VERSION(2,1,92) */
|
9076 |
|
|
|
9077 |
|
|
/*
|
9078 |
|
|
* The first bit (LSB) of PCI_BASE_ADDRESS_0 is always set, so
|
9079 |
|
|
* we mask it off.
|
9080 |
|
|
*/
|
9081 |
|
|
temp_p->base &= PCI_BASE_ADDRESS_IO_MASK;
|
9082 |
|
|
temp_p->mbase &= PCI_BASE_ADDRESS_MEM_MASK;
|
9083 |
|
|
temp_p->unpause = INTEN;
|
9084 |
|
|
temp_p->pause = temp_p->unpause | PAUSE;
|
9085 |
|
|
if ( ((temp_p->base == 0) &&
|
9086 |
|
|
(temp_p->mbase == 0)) ||
|
9087 |
|
|
(temp_p->irq == 0) )
|
9088 |
|
|
{
|
9089 |
|
|
printk("aic7xxx: <%s> at PCI %d/%d\n",
|
9090 |
|
|
board_names[aic_pdevs[i].board_name_index],
|
9091 |
|
|
PCI_SLOT(temp_p->pci_device_fn),
|
9092 |
|
|
PCI_FUNC(temp_p->pci_device_fn));
|
9093 |
|
|
printk("aic7xxx: Controller disabled by BIOS, ignoring.\n");
|
9094 |
|
|
kfree(temp_p);
|
9095 |
|
|
temp_p = NULL;
|
9096 |
|
|
continue;
|
9097 |
|
|
}
|
9098 |
|
|
|
9099 |
|
|
#ifdef MMAPIO
|
9100 |
|
|
{
|
9101 |
|
|
unsigned long page_offset, base;
|
9102 |
|
|
|
9103 |
|
|
base = temp_p->mbase & PAGE_MASK;
|
9104 |
|
|
page_offset = temp_p->mbase - base;
|
9105 |
|
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
|
9106 |
|
|
temp_p->maddr = ioremap_nocache(base, page_offset + 256);
|
9107 |
|
|
#else
|
9108 |
|
|
temp_p->maddr = vremap(base, page_offset + 256);
|
9109 |
|
|
#endif
|
9110 |
|
|
if(temp_p->maddr)
|
9111 |
|
|
{
|
9112 |
|
|
temp_p->maddr += page_offset;
|
9113 |
|
|
/*
|
9114 |
|
|
* We need to check the I/O with the MMAPed address. Some machines
|
9115 |
|
|
* simply fail to work with MMAPed I/O and certain controllers.
|
9116 |
|
|
*/
|
9117 |
|
|
if(aic_inb(temp_p, HCNTRL) == 0xff)
|
9118 |
|
|
{
|
9119 |
|
|
/*
|
9120 |
|
|
* OK.....we failed our test....go back to programmed I/O
|
9121 |
|
|
*/
|
9122 |
|
|
printk(KERN_INFO "aic7xxx: <%s> at PCI %d/%d\n",
|
9123 |
|
|
board_names[aic_pdevs[i].board_name_index],
|
9124 |
|
|
PCI_SLOT(temp_p->pci_device_fn),
|
9125 |
|
|
PCI_FUNC(temp_p->pci_device_fn));
|
9126 |
|
|
printk(KERN_INFO "aic7xxx: MMAPed I/O failed, reverting to "
|
9127 |
|
|
"Programmed I/O.\n");
|
9128 |
|
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
|
9129 |
|
|
iounmap((void *) (((unsigned long) temp_p->maddr) & PAGE_MASK));
|
9130 |
|
|
#else
|
9131 |
|
|
vfree((void *) (((unsigned long) temp_p->maddr) & PAGE_MASK));
|
9132 |
|
|
#endif
|
9133 |
|
|
temp_p->maddr = 0;
|
9134 |
|
|
}
|
9135 |
|
|
}
|
9136 |
|
|
}
|
9137 |
|
|
#endif
|
9138 |
|
|
|
9139 |
|
|
/*
|
9140 |
|
|
* We HAVE to make sure the first pause_sequencer() and all other
|
9141 |
|
|
* subsequent I/O that isn't PCI config space I/O takes place
|
9142 |
|
|
* after the MMAPed I/O region is configured and tested. The
|
9143 |
|
|
* problem is the PowerPC architecture that doesn't support
|
9144 |
|
|
* programmed I/O at all, so we have to have the MMAP I/O set up
|
9145 |
|
|
* for this pause to even work on those machines.
|
9146 |
|
|
*/
|
9147 |
|
|
pause_sequencer(temp_p);
|
9148 |
|
|
|
9149 |
|
|
/*
|
9150 |
|
|
* Clear out any pending PCI error status messages. Also set
|
9151 |
|
|
* verbose to 0 so that we don't emit strange PCI error messages
|
9152 |
|
|
* while cleaning out the current status bits.
|
9153 |
|
|
*/
|
9154 |
|
|
oldverbose = aic7xxx_verbose;
|
9155 |
|
|
aic7xxx_verbose = 0;
|
9156 |
|
|
aic7xxx_pci_intr(temp_p);
|
9157 |
|
|
aic7xxx_verbose = oldverbose;
|
9158 |
|
|
|
9159 |
|
|
temp_p->bios_address = 0;
|
9160 |
|
|
|
9161 |
|
|
/*
|
9162 |
|
|
* Remember how the card was setup in case there is no seeprom.
|
9163 |
|
|
*/
|
9164 |
|
|
if (temp_p->features & AHC_ULTRA2)
|
9165 |
|
|
temp_p->scsi_id = aic_inb(temp_p, SCSIID_ULTRA2) & OID;
|
9166 |
|
|
else
|
9167 |
|
|
temp_p->scsi_id = aic_inb(temp_p, SCSIID) & OID;
|
9168 |
|
|
/*
|
9169 |
|
|
* Get current termination setting
|
9170 |
|
|
*/
|
9171 |
|
|
sxfrctl1 = aic_inb(temp_p, SXFRCTL1) & STPWEN;
|
9172 |
|
|
|
9173 |
|
|
if (aic7xxx_chip_reset(temp_p) == -1)
|
9174 |
|
|
{
|
9175 |
|
|
kfree(temp_p);
|
9176 |
|
|
temp_p = NULL;
|
9177 |
|
|
continue;
|
9178 |
|
|
}
|
9179 |
|
|
|
9180 |
|
|
/*
|
9181 |
|
|
* We need to set the CHNL? assignments before loading the SEEPROM
|
9182 |
|
|
* The 3940 and 3985 cards (original stuff, not any of the later
|
9183 |
|
|
* stuff) are 7870 and 7880 class chips. The Ultra2 stuff falls
|
9184 |
|
|
* under 7896 and 7897. The 7895 is in a class by itself :)
|
9185 |
|
|
*/
|
9186 |
|
|
switch (temp_p->chip & AHC_CHIPID_MASK)
|
9187 |
|
|
{
|
9188 |
|
|
case AHC_AIC7870: /* 3840 / 3985 */
|
9189 |
|
|
case AHC_AIC7880: /* 3840 UW / 3985 UW */
|
9190 |
|
|
if(temp_p->flags & AHC_MULTI_CHANNEL)
|
9191 |
|
|
{
|
9192 |
|
|
switch(PCI_SLOT(temp_p->pci_device_fn))
|
9193 |
|
|
{
|
9194 |
|
|
case 5:
|
9195 |
|
|
temp_p->flags |= AHC_CHNLB;
|
9196 |
|
|
break;
|
9197 |
|
|
case 8:
|
9198 |
|
|
temp_p->flags |= AHC_CHNLB;
|
9199 |
|
|
break;
|
9200 |
|
|
case 12:
|
9201 |
|
|
temp_p->flags |= AHC_CHNLC;
|
9202 |
|
|
break;
|
9203 |
|
|
default:
|
9204 |
|
|
break;
|
9205 |
|
|
}
|
9206 |
|
|
}
|
9207 |
|
|
break;
|
9208 |
|
|
|
9209 |
|
|
case AHC_AIC7895: /* 7895 */
|
9210 |
|
|
case AHC_AIC7896: /* 7896/7 */
|
9211 |
|
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
|
9212 |
|
|
if (PCI_FUNC(temp_p->pdev->devfn) != 0)
|
9213 |
|
|
{
|
9214 |
|
|
temp_p->flags |= AHC_CHNLB;
|
9215 |
|
|
}
|
9216 |
|
|
/*
|
9217 |
|
|
* The 7895 is the only chipset that sets the SCBSIZE32 param
|
9218 |
|
|
* in the DEVCONFIG register. The Ultra2 chipsets use
|
9219 |
|
|
* the DSCOMMAND0 register instead.
|
9220 |
|
|
*/
|
9221 |
|
|
if ((temp_p->chip & AHC_CHIPID_MASK) == AHC_AIC7895)
|
9222 |
|
|
{
|
9223 |
|
|
pci_read_config_dword(pdev, DEVCONFIG, &devconfig);
|
9224 |
|
|
devconfig |= SCBSIZE32;
|
9225 |
|
|
pci_write_config_dword(pdev, DEVCONFIG, devconfig);
|
9226 |
|
|
}
|
9227 |
|
|
#else
|
9228 |
|
|
if (PCI_FUNC(temp_p->pci_device_fn) != 0)
|
9229 |
|
|
{
|
9230 |
|
|
temp_p->flags |= AHC_CHNLB;
|
9231 |
|
|
}
|
9232 |
|
|
/*
|
9233 |
|
|
* The 7895 is the only chipset that sets the SCBSIZE32 param
|
9234 |
|
|
* in the DEVCONFIG register. The Ultra2 chipsets use
|
9235 |
|
|
* the DSCOMMAND0 register instead.
|
9236 |
|
|
*/
|
9237 |
|
|
if ((temp_p->chip & AHC_CHIPID_MASK) == AHC_AIC7895)
|
9238 |
|
|
{
|
9239 |
|
|
pcibios_read_config_dword(pci_bus, pci_devfn, DEVCONFIG,
|
9240 |
|
|
&devconfig);
|
9241 |
|
|
devconfig |= SCBSIZE32;
|
9242 |
|
|
pcibios_write_config_dword(pci_bus, pci_devfn, DEVCONFIG,
|
9243 |
|
|
devconfig);
|
9244 |
|
|
}
|
9245 |
|
|
#endif
|
9246 |
|
|
break;
|
9247 |
|
|
default:
|
9248 |
|
|
break;
|
9249 |
|
|
}
|
9250 |
|
|
|
9251 |
|
|
/*
|
9252 |
|
|
* Loading of the SEEPROM needs to come after we've set the flags
|
9253 |
|
|
* to indicate possible CHNLB and CHNLC assigments. Otherwise,
|
9254 |
|
|
* on 394x and 398x cards we'll end up reading the wrong settings
|
9255 |
|
|
* for channels B and C
|
9256 |
|
|
*/
|
9257 |
|
|
switch (temp_p->chip & AHC_CHIPID_MASK)
|
9258 |
|
|
{
|
9259 |
|
|
case AHC_AIC7890:
|
9260 |
|
|
case AHC_AIC7896:
|
9261 |
|
|
aic_outb(temp_p, 0, SCAMCTL);
|
9262 |
|
|
/*
|
9263 |
|
|
* We used to set DPARCKEN in this register, but after talking
|
9264 |
|
|
* to a tech from Adaptec, I found out they don't use that
|
9265 |
|
|
* particular bit in their own register settings, and when you
|
9266 |
|
|
* combine that with the fact that I determined that we were
|
9267 |
|
|
* seeing Data-Path Parity Errors on things we shouldn't see
|
9268 |
|
|
* them on, I think there is a bug in the silicon and the way
|
9269 |
|
|
* to work around it is to disable this particular check. Also
|
9270 |
|
|
* This bug only showed up on certain commands, so it seems to
|
9271 |
|
|
* be pattern related or some such. The commands we would
|
9272 |
|
|
* typically send as a linux TEST_UNIT_READY or INQUIRY command
|
9273 |
|
|
* could cause it to be triggered, while regular commands that
|
9274 |
|
|
* actually made reasonable use of the SG array capabilities
|
9275 |
|
|
* seemed not to cause the problem.
|
9276 |
|
|
*/
|
9277 |
|
|
/*
|
9278 |
|
|
aic_outb(temp_p, aic_inb(temp_p, DSCOMMAND0) |
|
9279 |
|
|
CACHETHEN | DPARCKEN | MPARCKEN |
|
9280 |
|
|
USCBSIZE32 | CIOPARCKEN,
|
9281 |
|
|
DSCOMMAND0);
|
9282 |
|
|
*/
|
9283 |
|
|
aic_outb(temp_p, (aic_inb(temp_p, DSCOMMAND0) |
|
9284 |
|
|
CACHETHEN | MPARCKEN | USCBSIZE32 |
|
9285 |
|
|
CIOPARCKEN) & ~DPARCKEN, DSCOMMAND0);
|
9286 |
|
|
aic7xxx_load_seeprom(temp_p, &sxfrctl1);
|
9287 |
|
|
break;
|
9288 |
|
|
case AHC_AIC7850:
|
9289 |
|
|
case AHC_AIC7860:
|
9290 |
|
|
/*
|
9291 |
|
|
* Set the DSCOMMAND0 register on these cards different from
|
9292 |
|
|
* on the 789x cards. Also, read the SEEPROM as well.
|
9293 |
|
|
*/
|
9294 |
|
|
aic_outb(temp_p, (aic_inb(temp_p, DSCOMMAND0) |
|
9295 |
|
|
CACHETHEN | MPARCKEN) & ~DPARCKEN,
|
9296 |
|
|
DSCOMMAND0);
|
9297 |
|
|
/* FALLTHROUGH */
|
9298 |
|
|
default:
|
9299 |
|
|
aic7xxx_load_seeprom(temp_p, &sxfrctl1);
|
9300 |
|
|
break;
|
9301 |
|
|
case AHC_AIC7880:
|
9302 |
|
|
/*
|
9303 |
|
|
* Check the rev of the chipset before we change DSCOMMAND0
|
9304 |
|
|
*/
|
9305 |
|
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
|
9306 |
|
|
pci_read_config_dword(pdev, DEVCONFIG, &devconfig);
|
9307 |
|
|
#else
|
9308 |
|
|
pcibios_read_config_dword(pci_bus, pci_devfn, DEVCONFIG,
|
9309 |
|
|
&devconfig);
|
9310 |
|
|
#endif
|
9311 |
|
|
if ((devconfig & 0xff) >= 1)
|
9312 |
|
|
{
|
9313 |
|
|
aic_outb(temp_p, (aic_inb(temp_p, DSCOMMAND0) |
|
9314 |
|
|
CACHETHEN | MPARCKEN) & ~DPARCKEN,
|
9315 |
|
|
DSCOMMAND0);
|
9316 |
|
|
}
|
9317 |
|
|
aic7xxx_load_seeprom(temp_p, &sxfrctl1);
|
9318 |
|
|
break;
|
9319 |
|
|
}
|
9320 |
|
|
|
9321 |
|
|
|
9322 |
|
|
/*
|
9323 |
|
|
* and then we need another switch based on the type in order to
|
9324 |
|
|
* make sure the channel B primary flag is set properly on 7895
|
9325 |
|
|
* controllers....Arrrgggghhh!!! We also have to catch the fact
|
9326 |
|
|
* that when you disable the BIOS on the 7895 on the Intel DK440LX
|
9327 |
|
|
* motherboard, and possibly others, it only sets the BIOS disabled
|
9328 |
|
|
* bit on the A channel...I think I'm starting to lean towards
|
9329 |
|
|
* going postal....
|
9330 |
|
|
*/
|
9331 |
|
|
switch(temp_p->chip & AHC_CHIPID_MASK)
|
9332 |
|
|
{
|
9333 |
|
|
case AHC_AIC7895:
|
9334 |
|
|
case AHC_AIC7896:
|
9335 |
|
|
current_p = list_p;
|
9336 |
|
|
while(current_p != NULL)
|
9337 |
|
|
{
|
9338 |
|
|
if ( (current_p->pci_bus == temp_p->pci_bus) &&
|
9339 |
|
|
(PCI_SLOT(current_p->pci_device_fn) ==
|
9340 |
|
|
PCI_SLOT(temp_p->pci_device_fn)) )
|
9341 |
|
|
{
|
9342 |
|
|
if ( PCI_FUNC(current_p->pci_device_fn) == 0 )
|
9343 |
|
|
{
|
9344 |
|
|
temp_p->flags |=
|
9345 |
|
|
(current_p->flags & AHC_CHANNEL_B_PRIMARY);
|
9346 |
|
|
temp_p->flags &= ~(AHC_BIOS_ENABLED|AHC_USEDEFAULTS);
|
9347 |
|
|
temp_p->flags |=
|
9348 |
|
|
(current_p->flags & (AHC_BIOS_ENABLED|AHC_USEDEFAULTS));
|
9349 |
|
|
}
|
9350 |
|
|
else
|
9351 |
|
|
{
|
9352 |
|
|
current_p->flags |=
|
9353 |
|
|
(temp_p->flags & AHC_CHANNEL_B_PRIMARY);
|
9354 |
|
|
current_p->flags &= ~(AHC_BIOS_ENABLED|AHC_USEDEFAULTS);
|
9355 |
|
|
current_p->flags |=
|
9356 |
|
|
(temp_p->flags & (AHC_BIOS_ENABLED|AHC_USEDEFAULTS));
|
9357 |
|
|
}
|
9358 |
|
|
}
|
9359 |
|
|
current_p = current_p->next;
|
9360 |
|
|
}
|
9361 |
|
|
break;
|
9362 |
|
|
default:
|
9363 |
|
|
break;
|
9364 |
|
|
}
|
9365 |
|
|
|
9366 |
|
|
/*
|
9367 |
|
|
* We only support external SCB RAM on the 7895/6/7 chipsets.
|
9368 |
|
|
* We could support it on the 7890/1 easy enough, but I don't
|
9369 |
|
|
* know of any 7890/1 based cards that have it. I do know
|
9370 |
|
|
* of 7895/6/7 cards that have it and they work properly.
|
9371 |
|
|
*/
|
9372 |
|
|
switch(temp_p->chip & AHC_CHIPID_MASK)
|
9373 |
|
|
{
|
9374 |
|
|
default:
|
9375 |
|
|
break;
|
9376 |
|
|
case AHC_AIC7895:
|
9377 |
|
|
case AHC_AIC7896:
|
9378 |
|
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
|
9379 |
|
|
pci_read_config_dword(pdev, DEVCONFIG, &devconfig);
|
9380 |
|
|
#else
|
9381 |
|
|
pcibios_read_config_dword(pci_bus, pci_devfn, DEVCONFIG,
|
9382 |
|
|
&devconfig);
|
9383 |
|
|
#endif
|
9384 |
|
|
if (temp_p->features & AHC_ULTRA2)
|
9385 |
|
|
{
|
9386 |
|
|
if (aic_inb(temp_p, DSCOMMAND0) & RAMPSM_ULTRA2)
|
9387 |
|
|
{
|
9388 |
|
|
aic_outb(temp_p,
|
9389 |
|
|
aic_inb(temp_p, DSCOMMAND0) & ~SCBRAMSEL_ULTRA2,
|
9390 |
|
|
DSCOMMAND0);
|
9391 |
|
|
temp_p->flags |= AHC_EXTERNAL_SRAM;
|
9392 |
|
|
devconfig |= EXTSCBPEN;
|
9393 |
|
|
}
|
9394 |
|
|
}
|
9395 |
|
|
else if (devconfig & RAMPSM)
|
9396 |
|
|
{
|
9397 |
|
|
devconfig &= ~SCBRAMSEL;
|
9398 |
|
|
devconfig |= EXTSCBPEN;
|
9399 |
|
|
temp_p->flags |= AHC_EXTERNAL_SRAM;
|
9400 |
|
|
}
|
9401 |
|
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
|
9402 |
|
|
pci_write_config_dword(pdev, DEVCONFIG, devconfig);
|
9403 |
|
|
#else
|
9404 |
|
|
pcibios_write_config_dword(pci_bus, pci_devfn, DEVCONFIG,
|
9405 |
|
|
devconfig);
|
9406 |
|
|
#endif
|
9407 |
|
|
if ( (temp_p->flags & AHC_EXTERNAL_SRAM) &&
|
9408 |
|
|
(temp_p->flags & AHC_CHNLB) )
|
9409 |
|
|
aic_outb(temp_p, 1, CCSCBBADDR);
|
9410 |
|
|
break;
|
9411 |
|
|
}
|
9412 |
|
|
|
9413 |
|
|
/*
|
9414 |
|
|
* Take the LED out of diagnostic mode
|
9415 |
|
|
*/
|
9416 |
|
|
aic_outb(temp_p,
|
9417 |
|
|
(aic_inb(temp_p, SBLKCTL) & ~(DIAGLEDEN | DIAGLEDON)),
|
9418 |
|
|
SBLKCTL);
|
9419 |
|
|
|
9420 |
|
|
/*
|
9421 |
|
|
* We don't know where this is set in the SEEPROM or by the
|
9422 |
|
|
* BIOS, so we default to 100%. On Ultra2 controllers, use 75%
|
9423 |
|
|
* instead.
|
9424 |
|
|
*/
|
9425 |
|
|
if (temp_p->features & AHC_ULTRA2)
|
9426 |
|
|
{
|
9427 |
|
|
aic_outb(temp_p, RD_DFTHRSH_75 | WR_DFTHRSH_75, DFF_THRSH);
|
9428 |
|
|
}
|
9429 |
|
|
else
|
9430 |
|
|
{
|
9431 |
|
|
aic_outb(temp_p, DFTHRSH_100, DSPCISTATUS);
|
9432 |
|
|
}
|
9433 |
|
|
|
9434 |
|
|
if ( list_p == NULL )
|
9435 |
|
|
{
|
9436 |
|
|
list_p = current_p = temp_p;
|
9437 |
|
|
}
|
9438 |
|
|
else
|
9439 |
|
|
{
|
9440 |
|
|
current_p = list_p;
|
9441 |
|
|
while(current_p->next != NULL)
|
9442 |
|
|
current_p = current_p->next;
|
9443 |
|
|
current_p->next = temp_p;
|
9444 |
|
|
}
|
9445 |
|
|
temp_p->next = NULL;
|
9446 |
|
|
found++;
|
9447 |
|
|
} /* Found an Adaptec PCI device. */
|
9448 |
|
|
else /* Well, we found one, but we couldn't get any memory */
|
9449 |
|
|
{
|
9450 |
|
|
printk("aic7xxx: Found <%s>\n",
|
9451 |
|
|
board_names[aic_pdevs[i].board_name_index]);
|
9452 |
|
|
printk(KERN_INFO "aic7xxx: Unable to allocate device memory, "
|
9453 |
|
|
"skipping.\n");
|
9454 |
|
|
}
|
9455 |
|
|
} /* while(pdev=....) */
|
9456 |
|
|
} /* for PCI_DEVICES */
|
9457 |
|
|
} /* PCI BIOS present */
|
9458 |
|
|
#endif CONFIG_PCI
|
9459 |
|
|
/*
|
9460 |
|
|
* Now, we re-order the probed devices by BIOS address and BUS class.
|
9461 |
|
|
* In general, we follow this algorithm to make the adapters show up
|
9462 |
|
|
* in the same order under linux that the computer finds them.
|
9463 |
|
|
* 1: All VLB/EISA cards with BIOS_ENABLED first, according to BIOS
|
9464 |
|
|
* address, going from lowest to highest.
|
9465 |
|
|
* 2: All PCI controllers with BIOS_ENABLED next, according to BIOS
|
9466 |
|
|
* address, going from lowest to highest.
|
9467 |
|
|
* 3: Remaining VLB/EISA controllers going in slot order.
|
9468 |
|
|
* 4: Remaining PCI controllers, going in PCI device order (reversable)
|
9469 |
|
|
*/
|
9470 |
|
|
|
9471 |
|
|
{
|
9472 |
|
|
struct aic7xxx_host *sort_list[4] = { NULL, NULL, NULL, NULL };
|
9473 |
|
|
struct aic7xxx_host *vlb, *pci;
|
9474 |
|
|
struct aic7xxx_host *prev_p;
|
9475 |
|
|
struct aic7xxx_host *p;
|
9476 |
|
|
unsigned char left;
|
9477 |
|
|
|
9478 |
|
|
prev_p = vlb = pci = NULL;
|
9479 |
|
|
|
9480 |
|
|
temp_p = list_p;
|
9481 |
|
|
while (temp_p != NULL)
|
9482 |
|
|
{
|
9483 |
|
|
switch(temp_p->chip & ~AHC_CHIPID_MASK)
|
9484 |
|
|
{
|
9485 |
|
|
case AHC_EISA:
|
9486 |
|
|
case AHC_VL:
|
9487 |
|
|
{
|
9488 |
|
|
p = temp_p;
|
9489 |
|
|
if (p->flags & AHC_BIOS_ENABLED)
|
9490 |
|
|
vlb = sort_list[0];
|
9491 |
|
|
else
|
9492 |
|
|
vlb = sort_list[2];
|
9493 |
|
|
|
9494 |
|
|
if (vlb == NULL)
|
9495 |
|
|
{
|
9496 |
|
|
vlb = temp_p;
|
9497 |
|
|
temp_p = temp_p->next;
|
9498 |
|
|
vlb->next = NULL;
|
9499 |
|
|
}
|
9500 |
|
|
else
|
9501 |
|
|
{
|
9502 |
|
|
current_p = vlb;
|
9503 |
|
|
prev_p = NULL;
|
9504 |
|
|
while ( (current_p != NULL) &&
|
9505 |
|
|
(current_p->bios_address < temp_p->bios_address))
|
9506 |
|
|
{
|
9507 |
|
|
prev_p = current_p;
|
9508 |
|
|
current_p = current_p->next;
|
9509 |
|
|
}
|
9510 |
|
|
if (prev_p != NULL)
|
9511 |
|
|
{
|
9512 |
|
|
prev_p->next = temp_p;
|
9513 |
|
|
temp_p = temp_p->next;
|
9514 |
|
|
prev_p->next->next = current_p;
|
9515 |
|
|
}
|
9516 |
|
|
else
|
9517 |
|
|
{
|
9518 |
|
|
vlb = temp_p;
|
9519 |
|
|
temp_p = temp_p->next;
|
9520 |
|
|
vlb->next = current_p;
|
9521 |
|
|
}
|
9522 |
|
|
}
|
9523 |
|
|
|
9524 |
|
|
if (p->flags & AHC_BIOS_ENABLED)
|
9525 |
|
|
sort_list[0] = vlb;
|
9526 |
|
|
else
|
9527 |
|
|
sort_list[2] = vlb;
|
9528 |
|
|
|
9529 |
|
|
break;
|
9530 |
|
|
}
|
9531 |
|
|
default: /* All PCI controllers fall through to default */
|
9532 |
|
|
{
|
9533 |
|
|
|
9534 |
|
|
p = temp_p;
|
9535 |
|
|
if (p->flags & AHC_BIOS_ENABLED)
|
9536 |
|
|
pci = sort_list[1];
|
9537 |
|
|
else
|
9538 |
|
|
pci = sort_list[3];
|
9539 |
|
|
|
9540 |
|
|
if (pci == NULL)
|
9541 |
|
|
{
|
9542 |
|
|
pci = temp_p;
|
9543 |
|
|
temp_p = temp_p->next;
|
9544 |
|
|
pci->next = NULL;
|
9545 |
|
|
}
|
9546 |
|
|
else
|
9547 |
|
|
{
|
9548 |
|
|
current_p = pci;
|
9549 |
|
|
prev_p = NULL;
|
9550 |
|
|
if (!aic7xxx_reverse_scan)
|
9551 |
|
|
{
|
9552 |
|
|
while ( (current_p != NULL) &&
|
9553 |
|
|
( (PCI_SLOT(current_p->pci_device_fn) |
|
9554 |
|
|
(current_p->pci_bus << 8)) <
|
9555 |
|
|
(PCI_SLOT(temp_p->pci_device_fn) |
|
9556 |
|
|
(temp_p->pci_bus << 8)) ) )
|
9557 |
|
|
{
|
9558 |
|
|
prev_p = current_p;
|
9559 |
|
|
current_p = current_p->next;
|
9560 |
|
|
}
|
9561 |
|
|
}
|
9562 |
|
|
else
|
9563 |
|
|
{
|
9564 |
|
|
while ( (current_p != NULL) &&
|
9565 |
|
|
( (PCI_SLOT(current_p->pci_device_fn) |
|
9566 |
|
|
(current_p->pci_bus << 8)) >
|
9567 |
|
|
(PCI_SLOT(temp_p->pci_device_fn) |
|
9568 |
|
|
(temp_p->pci_bus << 8)) ) )
|
9569 |
|
|
{
|
9570 |
|
|
prev_p = current_p;
|
9571 |
|
|
current_p = current_p->next;
|
9572 |
|
|
}
|
9573 |
|
|
}
|
9574 |
|
|
/*
|
9575 |
|
|
* Are we dealing with a 7985 where we need to sort the
|
9576 |
|
|
* channels as well, if so, the bios_address values should
|
9577 |
|
|
* be the same
|
9578 |
|
|
*/
|
9579 |
|
|
if ( (current_p) && (temp_p->flags & AHC_MULTI_CHANNEL) &&
|
9580 |
|
|
(temp_p->pci_bus == current_p->pci_bus) &&
|
9581 |
|
|
(PCI_SLOT(temp_p->pci_device_fn) ==
|
9582 |
|
|
PCI_SLOT(current_p->pci_device_fn)) )
|
9583 |
|
|
{
|
9584 |
|
|
if (temp_p->flags & AHC_CHNLB)
|
9585 |
|
|
{
|
9586 |
|
|
if ( !(temp_p->flags & AHC_CHANNEL_B_PRIMARY) )
|
9587 |
|
|
{
|
9588 |
|
|
prev_p = current_p;
|
9589 |
|
|
current_p = current_p->next;
|
9590 |
|
|
}
|
9591 |
|
|
}
|
9592 |
|
|
else
|
9593 |
|
|
{
|
9594 |
|
|
if (temp_p->flags & AHC_CHANNEL_B_PRIMARY)
|
9595 |
|
|
{
|
9596 |
|
|
prev_p = current_p;
|
9597 |
|
|
current_p = current_p->next;
|
9598 |
|
|
}
|
9599 |
|
|
}
|
9600 |
|
|
}
|
9601 |
|
|
if (prev_p != NULL)
|
9602 |
|
|
{
|
9603 |
|
|
prev_p->next = temp_p;
|
9604 |
|
|
temp_p = temp_p->next;
|
9605 |
|
|
prev_p->next->next = current_p;
|
9606 |
|
|
}
|
9607 |
|
|
else
|
9608 |
|
|
{
|
9609 |
|
|
pci = temp_p;
|
9610 |
|
|
temp_p = temp_p->next;
|
9611 |
|
|
pci->next = current_p;
|
9612 |
|
|
}
|
9613 |
|
|
}
|
9614 |
|
|
|
9615 |
|
|
if (p->flags & AHC_BIOS_ENABLED)
|
9616 |
|
|
sort_list[1] = pci;
|
9617 |
|
|
else
|
9618 |
|
|
sort_list[3] = pci;
|
9619 |
|
|
|
9620 |
|
|
break;
|
9621 |
|
|
}
|
9622 |
|
|
} /* End of switch(temp_p->type) */
|
9623 |
|
|
} /* End of while (temp_p != NULL) */
|
9624 |
|
|
/*
|
9625 |
|
|
* At this point, the cards have been broken into 4 sorted lists, now
|
9626 |
|
|
* we run through the lists in order and register each controller
|
9627 |
|
|
*/
|
9628 |
|
|
{
|
9629 |
|
|
int i;
|
9630 |
|
|
|
9631 |
|
|
left = found;
|
9632 |
|
|
for (i=0; i<NUMBER(sort_list); i++)
|
9633 |
|
|
{
|
9634 |
|
|
temp_p = sort_list[i];
|
9635 |
|
|
while(temp_p != NULL)
|
9636 |
|
|
{
|
9637 |
|
|
template->name = board_names[temp_p->board_name_index];
|
9638 |
|
|
p = aic7xxx_alloc(template, temp_p);
|
9639 |
|
|
if (p != NULL)
|
9640 |
|
|
{
|
9641 |
|
|
p->instance = found - left;
|
9642 |
|
|
if (aic7xxx_register(template, p, (--left)) == 0)
|
9643 |
|
|
{
|
9644 |
|
|
found--;
|
9645 |
|
|
aic7xxx_release(p->host);
|
9646 |
|
|
scsi_unregister(p->host);
|
9647 |
|
|
}
|
9648 |
|
|
else if (aic7xxx_dump_card)
|
9649 |
|
|
{
|
9650 |
|
|
pause_sequencer(p);
|
9651 |
|
|
aic7xxx_print_card(p);
|
9652 |
|
|
aic7xxx_print_scratch_ram(p);
|
9653 |
|
|
unpause_sequencer(p, TRUE);
|
9654 |
|
|
}
|
9655 |
|
|
}
|
9656 |
|
|
current_p = temp_p;
|
9657 |
|
|
temp_p = (struct aic7xxx_host *)temp_p->next;
|
9658 |
|
|
kfree(current_p);
|
9659 |
|
|
}
|
9660 |
|
|
}
|
9661 |
|
|
}
|
9662 |
|
|
}
|
9663 |
|
|
return (found);
|
9664 |
|
|
}
|
9665 |
|
|
|
9666 |
|
|
#ifdef AIC7XXX_FAKE_NEGOTIATION_CMDS
|
9667 |
|
|
|
9668 |
|
|
/*+F*************************************************************************
|
9669 |
|
|
* Function:
|
9670 |
|
|
* aic7xxx_negotiation_complete
|
9671 |
|
|
*
|
9672 |
|
|
* Description:
|
9673 |
|
|
* Handle completion events for our Negotiation commands. Clear out the
|
9674 |
|
|
* struct and get it ready for its next use.
|
9675 |
|
|
*-F*************************************************************************/
|
9676 |
|
|
static void
|
9677 |
|
|
aic7xxx_negotiation_complete(Scsi_Cmnd *cmd)
|
9678 |
|
|
{
|
9679 |
|
|
return;
|
9680 |
|
|
}
|
9681 |
|
|
|
9682 |
|
|
/*+F*************************************************************************
|
9683 |
|
|
* Function:
|
9684 |
|
|
* aic7xxx_build_negotiation_command
|
9685 |
|
|
*
|
9686 |
|
|
* Description:
|
9687 |
|
|
* Build a Scsi_Cmnd structure to perform negotiation with or else send
|
9688 |
|
|
* a pre-built command specifically for this purpose.
|
9689 |
|
|
*-F*************************************************************************/
|
9690 |
|
|
static void
|
9691 |
|
|
aic7xxx_build_negotiation_cmnd(struct aic7xxx_host *p, Scsi_Cmnd *old_cmd,
|
9692 |
|
|
int tindex)
|
9693 |
|
|
{
|
9694 |
|
|
|
9695 |
|
|
if ( (p->needwdtr & (1<<tindex)) && !(p->wdtr_pending & (1<<tindex)) )
|
9696 |
|
|
{
|
9697 |
|
|
if(p->dev_wdtr_cmnd[tindex] == NULL)
|
9698 |
|
|
{
|
9699 |
|
|
Scsi_Cmnd *cmd;
|
9700 |
|
|
|
9701 |
|
|
if (!(p->dev_wdtr_cmnd[tindex] = kmalloc(sizeof(Scsi_Cmnd), GFP_ATOMIC)) )
|
9702 |
|
|
{
|
9703 |
|
|
return;
|
9704 |
|
|
}
|
9705 |
|
|
cmd = p->dev_wdtr_cmnd[tindex];
|
9706 |
|
|
memset(cmd, 0, sizeof(Scsi_Cmnd));
|
9707 |
|
|
memcpy(cmd, old_cmd, sizeof(Scsi_Cmnd));
|
9708 |
|
|
memset(&cmd->cmnd[0], 0, sizeof(cmd->cmnd));
|
9709 |
|
|
memset(&cmd->data_cmnd[0], 0, sizeof(cmd->data_cmnd));
|
9710 |
|
|
cmd->lun = 0;
|
9711 |
|
|
cmd->request_bufflen = 0;
|
9712 |
|
|
cmd->request_buffer = NULL;
|
9713 |
|
|
cmd->use_sg = cmd->old_use_sg = cmd->sglist_len = 0;
|
9714 |
|
|
cmd->bufflen = 0;
|
9715 |
|
|
cmd->buffer = NULL;
|
9716 |
|
|
cmd->underflow = 0;
|
9717 |
|
|
cmd->cmd_len = 6;
|
9718 |
|
|
}
|
9719 |
|
|
/*
|
9720 |
|
|
* Before sending this thing out, we also amke the cmd->next pointer
|
9721 |
|
|
* point to the real command so we can stuff any possible SENSE data
|
9722 |
|
|
* intp the real command instead of this fake command. This has to be
|
9723 |
|
|
* done each time the command is built, not just the first time, hence
|
9724 |
|
|
* it's outside of the above if()...
|
9725 |
|
|
*/
|
9726 |
|
|
p->dev_wdtr_cmnd[tindex]->next = old_cmd;
|
9727 |
|
|
aic7xxx_queue(p->dev_wdtr_cmnd[tindex],
|
9728 |
|
|
aic7xxx_negotiation_complete);
|
9729 |
|
|
}
|
9730 |
|
|
else if ( (p->needsdtr & (1<<tindex)) && !(p->sdtr_pending & (1<<tindex)) &&
|
9731 |
|
|
!(p->wdtr_pending & (1<<tindex)) )
|
9732 |
|
|
{
|
9733 |
|
|
if(p->dev_sdtr_cmnd[tindex] == NULL)
|
9734 |
|
|
{
|
9735 |
|
|
Scsi_Cmnd *cmd;
|
9736 |
|
|
|
9737 |
|
|
if (!(p->dev_sdtr_cmnd[tindex] = kmalloc(sizeof(Scsi_Cmnd), GFP_ATOMIC)) )
|
9738 |
|
|
{
|
9739 |
|
|
return;
|
9740 |
|
|
}
|
9741 |
|
|
cmd = p->dev_sdtr_cmnd[tindex];
|
9742 |
|
|
memset(cmd, 0, sizeof(Scsi_Cmnd));
|
9743 |
|
|
memcpy(cmd, old_cmd, sizeof(Scsi_Cmnd));
|
9744 |
|
|
memset(&cmd->cmnd[0], 0, sizeof(cmd->cmnd));
|
9745 |
|
|
memset(&cmd->data_cmnd[0], 0, sizeof(cmd->data_cmnd));
|
9746 |
|
|
cmd->lun = 0;
|
9747 |
|
|
cmd->request_bufflen = 0;
|
9748 |
|
|
cmd->request_buffer = NULL;
|
9749 |
|
|
cmd->use_sg = cmd->old_use_sg = cmd->sglist_len = 0;
|
9750 |
|
|
cmd->bufflen = 0;
|
9751 |
|
|
cmd->buffer = NULL;
|
9752 |
|
|
cmd->underflow = 0;
|
9753 |
|
|
cmd->cmd_len = 6;
|
9754 |
|
|
}
|
9755 |
|
|
/*
|
9756 |
|
|
* Before sending this thing out, we also amke the cmd->next pointer
|
9757 |
|
|
* point to the real command so we can stuff any possible SENSE data
|
9758 |
|
|
* intp the real command instead of this fake command. This has to be
|
9759 |
|
|
* done each time the command is built, not just the first time, hence
|
9760 |
|
|
* it's outside of the above if()...
|
9761 |
|
|
*/
|
9762 |
|
|
p->dev_sdtr_cmnd[tindex]->next = old_cmd;
|
9763 |
|
|
aic7xxx_queue(p->dev_sdtr_cmnd[tindex],
|
9764 |
|
|
aic7xxx_negotiation_complete);
|
9765 |
|
|
}
|
9766 |
|
|
}
|
9767 |
|
|
|
9768 |
|
|
#endif
|
9769 |
|
|
|
9770 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
9771 |
|
|
/*+F*************************************************************************
|
9772 |
|
|
* Function:
|
9773 |
|
|
* aic7xxx_print_scb
|
9774 |
|
|
*
|
9775 |
|
|
* Description:
|
9776 |
|
|
* Dump the byte codes for an about to be sent SCB.
|
9777 |
|
|
*-F*************************************************************************/
|
9778 |
|
|
static void
|
9779 |
|
|
aic7xxx_print_scb(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
|
9780 |
|
|
{
|
9781 |
|
|
int i;
|
9782 |
|
|
unsigned char *x;
|
9783 |
|
|
|
9784 |
|
|
x = (unsigned char *)&scb->hscb->control;
|
9785 |
|
|
|
9786 |
|
|
for(i=0; i<32; i++)
|
9787 |
|
|
{
|
9788 |
|
|
printk("%02x ", x[i]);
|
9789 |
|
|
}
|
9790 |
|
|
printk("\n");
|
9791 |
|
|
}
|
9792 |
|
|
#endif
|
9793 |
|
|
|
9794 |
|
|
/*+F*************************************************************************
|
9795 |
|
|
* Function:
|
9796 |
|
|
* aic7xxx_buildscb
|
9797 |
|
|
*
|
9798 |
|
|
* Description:
|
9799 |
|
|
* Build a SCB.
|
9800 |
|
|
*-F*************************************************************************/
|
9801 |
|
|
static void
|
9802 |
|
|
aic7xxx_buildscb(struct aic7xxx_host *p, Scsi_Cmnd *cmd,
|
9803 |
|
|
struct aic7xxx_scb *scb)
|
9804 |
|
|
{
|
9805 |
|
|
unsigned short mask;
|
9806 |
|
|
struct aic7xxx_hwscb *hscb;
|
9807 |
|
|
|
9808 |
|
|
mask = (0x01 << TARGET_INDEX(cmd));
|
9809 |
|
|
hscb = scb->hscb;
|
9810 |
|
|
|
9811 |
|
|
/*
|
9812 |
|
|
* Setup the control byte if we need negotiation and have not
|
9813 |
|
|
* already requested it.
|
9814 |
|
|
*/
|
9815 |
|
|
hscb->control = 0;
|
9816 |
|
|
scb->tag_action = 0;
|
9817 |
|
|
if (p->discenable & mask)
|
9818 |
|
|
{
|
9819 |
|
|
hscb->control |= DISCENB;
|
9820 |
|
|
if (p->tagenable & mask)
|
9821 |
|
|
{
|
9822 |
|
|
cmd->tag = hscb->tag;
|
9823 |
|
|
p->dev_commands_sent[TARGET_INDEX(cmd)]++;
|
9824 |
|
|
if (p->dev_commands_sent[TARGET_INDEX(cmd)] < 200)
|
9825 |
|
|
{
|
9826 |
|
|
hscb->control |= MSG_SIMPLE_Q_TAG;
|
9827 |
|
|
scb->tag_action = MSG_SIMPLE_Q_TAG;
|
9828 |
|
|
}
|
9829 |
|
|
else
|
9830 |
|
|
{
|
9831 |
|
|
if (p->orderedtag & mask)
|
9832 |
|
|
{
|
9833 |
|
|
hscb->control |= MSG_ORDERED_Q_TAG;
|
9834 |
|
|
scb->tag_action = MSG_ORDERED_Q_TAG;
|
9835 |
|
|
}
|
9836 |
|
|
else
|
9837 |
|
|
{
|
9838 |
|
|
hscb->control |= MSG_SIMPLE_Q_TAG;
|
9839 |
|
|
scb->tag_action = MSG_SIMPLE_Q_TAG;
|
9840 |
|
|
}
|
9841 |
|
|
p->dev_commands_sent[TARGET_INDEX(cmd)] = 0;
|
9842 |
|
|
}
|
9843 |
|
|
}
|
9844 |
|
|
}
|
9845 |
|
|
if (p->dev_flags[TARGET_INDEX(cmd)] & DEVICE_SCANNED)
|
9846 |
|
|
{
|
9847 |
|
|
#ifdef AIC7XXX_FAKE_NEGOTIATION_CMDS
|
9848 |
|
|
if ( (p->needwdtr & mask) && !(p->wdtr_pending & mask) )
|
9849 |
|
|
{
|
9850 |
|
|
if (cmd == p->dev_wdtr_cmnd[TARGET_INDEX(cmd)])
|
9851 |
|
|
{
|
9852 |
|
|
p->wdtr_pending |= mask;
|
9853 |
|
|
scb->flags |= SCB_MSGOUT_WDTR;
|
9854 |
|
|
hscb->control &= DISCENB;
|
9855 |
|
|
hscb->control |= MK_MESSAGE;
|
9856 |
|
|
scb->tag_action = 0;
|
9857 |
|
|
}
|
9858 |
|
|
else
|
9859 |
|
|
{
|
9860 |
|
|
aic7xxx_build_negotiation_cmnd(p, cmd, TARGET_INDEX(cmd));
|
9861 |
|
|
}
|
9862 |
|
|
}
|
9863 |
|
|
else if ( (p->needsdtr & mask) && !(p->sdtr_pending & mask) &&
|
9864 |
|
|
!(p->wdtr_pending & mask) )
|
9865 |
|
|
{
|
9866 |
|
|
if (cmd == p->dev_sdtr_cmnd[TARGET_INDEX(cmd)])
|
9867 |
|
|
{
|
9868 |
|
|
p->sdtr_pending |= mask;
|
9869 |
|
|
scb->flags |= SCB_MSGOUT_SDTR;
|
9870 |
|
|
hscb->control &= DISCENB;
|
9871 |
|
|
hscb->control |= MK_MESSAGE;
|
9872 |
|
|
scb->tag_action = 0;
|
9873 |
|
|
}
|
9874 |
|
|
else if (cmd != p->dev_wdtr_cmnd[TARGET_INDEX(cmd)])
|
9875 |
|
|
{
|
9876 |
|
|
aic7xxx_build_negotiation_cmnd(p, cmd, TARGET_INDEX(cmd));
|
9877 |
|
|
}
|
9878 |
|
|
}
|
9879 |
|
|
#else
|
9880 |
|
|
if ( (p->needwdtr & mask) && !(p->wdtr_pending & mask) &&
|
9881 |
|
|
!(p->sdtr_pending & mask) && (cmd->lun == 0) )
|
9882 |
|
|
{
|
9883 |
|
|
p->wdtr_pending |= mask;
|
9884 |
|
|
scb->flags |= SCB_MSGOUT_WDTR;
|
9885 |
|
|
hscb->control &= DISCENB;
|
9886 |
|
|
hscb->control |= MK_MESSAGE;
|
9887 |
|
|
scb->tag_action = 0;
|
9888 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
9889 |
|
|
if (aic7xxx_verbose > 0xffff)
|
9890 |
|
|
printk(INFO_LEAD "Building WDTR command.\n", p->host_no,
|
9891 |
|
|
CTL_OF_CMD(cmd));
|
9892 |
|
|
#endif
|
9893 |
|
|
}
|
9894 |
|
|
else if ( (p->needsdtr & mask) && !(p->wdtr_pending & mask) &&
|
9895 |
|
|
!(p->sdtr_pending & mask) && (cmd->lun == 0) )
|
9896 |
|
|
{
|
9897 |
|
|
p->sdtr_pending |= mask;
|
9898 |
|
|
scb->flags |= SCB_MSGOUT_SDTR;
|
9899 |
|
|
hscb->control &= DISCENB;
|
9900 |
|
|
hscb->control |= MK_MESSAGE;
|
9901 |
|
|
scb->tag_action = 0;
|
9902 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
9903 |
|
|
if (aic7xxx_verbose > 0xffff)
|
9904 |
|
|
printk(INFO_LEAD "Building SDTR command.\n", p->host_no,
|
9905 |
|
|
CTL_OF_CMD(cmd));
|
9906 |
|
|
#endif
|
9907 |
|
|
}
|
9908 |
|
|
#endif
|
9909 |
|
|
}
|
9910 |
|
|
hscb->target_channel_lun = ((cmd->target << 4) & 0xF0) |
|
9911 |
|
|
((cmd->channel & 0x01) << 3) | (cmd->lun & 0x07);
|
9912 |
|
|
|
9913 |
|
|
/*
|
9914 |
|
|
* The interpretation of request_buffer and request_bufflen
|
9915 |
|
|
* changes depending on whether or not use_sg is zero; a
|
9916 |
|
|
* non-zero use_sg indicates the number of elements in the
|
9917 |
|
|
* scatter-gather array.
|
9918 |
|
|
*/
|
9919 |
|
|
|
9920 |
|
|
/*
|
9921 |
|
|
* XXX - this relies on the host data being stored in a
|
9922 |
|
|
* little-endian format.
|
9923 |
|
|
*/
|
9924 |
|
|
hscb->SCSI_cmd_length = cmd->cmd_len;
|
9925 |
|
|
hscb->SCSI_cmd_pointer = cpu_to_le32(VIRT_TO_BUS(cmd->cmnd));
|
9926 |
|
|
|
9927 |
|
|
if (cmd->use_sg)
|
9928 |
|
|
{
|
9929 |
|
|
struct scatterlist *sg; /* Must be mid-level SCSI code scatterlist */
|
9930 |
|
|
|
9931 |
|
|
/*
|
9932 |
|
|
* We must build an SG list in adapter format, as the kernel's SG list
|
9933 |
|
|
* cannot be used directly because of data field size (__alpha__)
|
9934 |
|
|
* differences and the kernel SG list uses virtual addresses where
|
9935 |
|
|
* we need physical addresses.
|
9936 |
|
|
*/
|
9937 |
|
|
int i;
|
9938 |
|
|
|
9939 |
|
|
sg = (struct scatterlist *)cmd->request_buffer;
|
9940 |
|
|
scb->sg_length = 0;
|
9941 |
|
|
/*
|
9942 |
|
|
* Copy the segments into the SG array. NOTE!!! - We used to
|
9943 |
|
|
* have the first entry both in the data_pointer area and the first
|
9944 |
|
|
* SG element. That has changed somewhat. We still have the first
|
9945 |
|
|
* entry in both places, but now we download the address of
|
9946 |
|
|
* scb->sg_list[1] instead of 0 to the sg pointer in the hscb.
|
9947 |
|
|
*/
|
9948 |
|
|
for (i = 0; i < cmd->use_sg; i++)
|
9949 |
|
|
{
|
9950 |
|
|
scb->sg_list[i].address = cpu_to_le32(VIRT_TO_BUS(sg[i].address));
|
9951 |
|
|
scb->sg_list[i].length = cpu_to_le32(sg[i].length);
|
9952 |
|
|
scb->sg_length += sg[i].length;
|
9953 |
|
|
}
|
9954 |
|
|
/* Copy the first SG into the data pointer area. */
|
9955 |
|
|
hscb->data_pointer = scb->sg_list[0].address;
|
9956 |
|
|
hscb->data_count = scb->sg_list[0].length;
|
9957 |
|
|
scb->sg_count = cmd->use_sg;
|
9958 |
|
|
hscb->SG_segment_count = cmd->use_sg;
|
9959 |
|
|
hscb->SG_list_pointer = cpu_to_le32(VIRT_TO_BUS(&scb->sg_list[1]));
|
9960 |
|
|
|
9961 |
|
|
}
|
9962 |
|
|
else
|
9963 |
|
|
{
|
9964 |
|
|
if (cmd->request_bufflen)
|
9965 |
|
|
{
|
9966 |
|
|
scb->sg_count = 1;
|
9967 |
|
|
scb->sg_list[0].address = cpu_to_le32(VIRT_TO_BUS(cmd->request_buffer));
|
9968 |
|
|
scb->sg_list[0].length = cpu_to_le32(cmd->request_bufflen);
|
9969 |
|
|
scb->sg_length = cmd->request_bufflen;
|
9970 |
|
|
hscb->SG_segment_count = 1;
|
9971 |
|
|
hscb->SG_list_pointer = cpu_to_le32(VIRT_TO_BUS(&scb->sg_list[0]));
|
9972 |
|
|
hscb->data_count = scb->sg_list[0].length;
|
9973 |
|
|
hscb->data_pointer = scb->sg_list[0].address;
|
9974 |
|
|
}
|
9975 |
|
|
else
|
9976 |
|
|
{
|
9977 |
|
|
scb->sg_count = 0;
|
9978 |
|
|
scb->sg_length = 0;
|
9979 |
|
|
hscb->SG_segment_count = 0;
|
9980 |
|
|
hscb->SG_list_pointer = 0;
|
9981 |
|
|
hscb->data_count = 0;
|
9982 |
|
|
hscb->data_pointer = 0;
|
9983 |
|
|
}
|
9984 |
|
|
}
|
9985 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
9986 |
|
|
if((cmd->cmnd[0] == TEST_UNIT_READY) && (aic7xxx_verbose & VERBOSE_PROBE2))
|
9987 |
|
|
{
|
9988 |
|
|
aic7xxx_print_scb(p, scb);
|
9989 |
|
|
}
|
9990 |
|
|
#endif
|
9991 |
|
|
}
|
9992 |
|
|
|
9993 |
|
|
/*+F*************************************************************************
|
9994 |
|
|
* Function:
|
9995 |
|
|
* aic7xxx_queue
|
9996 |
|
|
*
|
9997 |
|
|
* Description:
|
9998 |
|
|
* Queue a SCB to the controller.
|
9999 |
|
|
*-F*************************************************************************/
|
10000 |
|
|
int
|
10001 |
|
|
aic7xxx_queue(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
|
10002 |
|
|
{
|
10003 |
|
|
struct aic7xxx_host *p;
|
10004 |
|
|
struct aic7xxx_scb *scb;
|
10005 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
10006 |
|
|
int tindex = TARGET_INDEX(cmd);
|
10007 |
|
|
#endif
|
10008 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
|
10009 |
|
|
unsigned long cpu_flags = 0;
|
10010 |
|
|
#endif
|
10011 |
|
|
|
10012 |
|
|
p = (struct aic7xxx_host *) cmd->host->hostdata;
|
10013 |
|
|
/*
|
10014 |
|
|
* Check to see if channel was scanned.
|
10015 |
|
|
*/
|
10016 |
|
|
|
10017 |
|
|
#ifdef AIC7XXX_VERBOSE_DEBUGGING
|
10018 |
|
|
if (!(p->flags & AHC_A_SCANNED) && (cmd->channel == 0))
|
10019 |
|
|
{
|
10020 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
10021 |
|
|
printk(INFO_LEAD "Scanning channel for devices.\n",
|
10022 |
|
|
p->host_no, 0, -1, -1);
|
10023 |
|
|
p->flags |= AHC_A_SCANNED;
|
10024 |
|
|
}
|
10025 |
|
|
else
|
10026 |
|
|
{
|
10027 |
|
|
if (!(p->flags & AHC_B_SCANNED) && (cmd->channel == 1))
|
10028 |
|
|
{
|
10029 |
|
|
if (aic7xxx_verbose & VERBOSE_PROBE2)
|
10030 |
|
|
printk(INFO_LEAD "Scanning channel for devices.\n",
|
10031 |
|
|
p->host_no, 1, -1, -1);
|
10032 |
|
|
p->flags |= AHC_B_SCANNED;
|
10033 |
|
|
}
|
10034 |
|
|
}
|
10035 |
|
|
|
10036 |
|
|
if (p->dev_active_cmds[tindex] > (cmd->device->queue_depth + 1))
|
10037 |
|
|
{
|
10038 |
|
|
printk(WARN_LEAD "Commands queued exceeds queue "
|
10039 |
|
|
"depth, active=%d\n",
|
10040 |
|
|
p->host_no, CTL_OF_CMD(cmd),
|
10041 |
|
|
p->dev_active_cmds[tindex]);
|
10042 |
|
|
if ( p->dev_active_cmds[tindex] > 220 )
|
10043 |
|
|
p->dev_active_cmds[tindex] = 0;
|
10044 |
|
|
}
|
10045 |
|
|
#endif
|
10046 |
|
|
|
10047 |
|
|
scb = scbq_remove_head(&p->scb_data->free_scbs);
|
10048 |
|
|
if (scb == NULL)
|
10049 |
|
|
{
|
10050 |
|
|
DRIVER_LOCK
|
10051 |
|
|
aic7xxx_allocate_scb(p);
|
10052 |
|
|
DRIVER_UNLOCK
|
10053 |
|
|
scb = scbq_remove_head(&p->scb_data->free_scbs);
|
10054 |
|
|
}
|
10055 |
|
|
if (scb == NULL)
|
10056 |
|
|
{
|
10057 |
|
|
printk(WARN_LEAD "Couldn't get a free SCB.\n", p->host_no,
|
10058 |
|
|
CTL_OF_CMD(cmd));
|
10059 |
|
|
cmd->result = (DID_BUS_BUSY << 16);
|
10060 |
|
|
DRIVER_LOCK
|
10061 |
|
|
aic7xxx_queue_cmd_complete(p, cmd);
|
10062 |
|
|
DRIVER_UNLOCK
|
10063 |
|
|
return 0;
|
10064 |
|
|
}
|
10065 |
|
|
else
|
10066 |
|
|
{
|
10067 |
|
|
scb->cmd = cmd;
|
10068 |
|
|
aic7xxx_position(cmd) = scb->hscb->tag;
|
10069 |
|
|
|
10070 |
|
|
/*
|
10071 |
|
|
* Construct the SCB beforehand, so the sequencer is
|
10072 |
|
|
* paused a minimal amount of time.
|
10073 |
|
|
*/
|
10074 |
|
|
aic7xxx_buildscb(p, cmd, scb);
|
10075 |
|
|
|
10076 |
|
|
/*
|
10077 |
|
|
* Make sure the Scsi_Cmnd pointer is saved, the struct it points to
|
10078 |
|
|
* is set up properly, and the parity error flag is reset, then send
|
10079 |
|
|
* the SCB to the sequencer and watch the fun begin.
|
10080 |
|
|
*/
|
10081 |
|
|
cmd->scsi_done = fn;
|
10082 |
|
|
cmd->result = DID_OK;
|
10083 |
|
|
memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
|
10084 |
|
|
aic7xxx_error(cmd) = DID_OK;
|
10085 |
|
|
aic7xxx_status(cmd) = 0;
|
10086 |
|
|
cmd->host_scribble = NULL;
|
10087 |
|
|
|
10088 |
|
|
scb->flags |= SCB_ACTIVE | SCB_WAITINGQ;
|
10089 |
|
|
|
10090 |
|
|
DRIVER_LOCK
|
10091 |
|
|
scbq_insert_tail(&p->waiting_scbs, scb);
|
10092 |
|
|
if ( (p->flags & (AHC_IN_ISR | AHC_IN_ABORT | AHC_IN_RESET)) == 0)
|
10093 |
|
|
{
|
10094 |
|
|
aic7xxx_run_waiting_queues(p);
|
10095 |
|
|
}
|
10096 |
|
|
DRIVER_UNLOCK
|
10097 |
|
|
}
|
10098 |
|
|
return (0);
|
10099 |
|
|
}
|
10100 |
|
|
|
10101 |
|
|
/*+F*************************************************************************
|
10102 |
|
|
* Function:
|
10103 |
|
|
* aic7xxx_bus_device_reset
|
10104 |
|
|
*
|
10105 |
|
|
* Description:
|
10106 |
|
|
* Abort or reset the current SCSI command(s). If the scb has not
|
10107 |
|
|
* previously been aborted, then we attempt to send a BUS_DEVICE_RESET
|
10108 |
|
|
* message to the target. If the scb has previously been unsuccessfully
|
10109 |
|
|
* aborted, then we will reset the channel and have all devices renegotiate.
|
10110 |
|
|
* Returns an enumerated type that indicates the status of the operation.
|
10111 |
|
|
*-F*************************************************************************/
|
10112 |
|
|
static int
|
10113 |
|
|
aic7xxx_bus_device_reset(struct aic7xxx_host *p, Scsi_Cmnd *cmd)
|
10114 |
|
|
{
|
10115 |
|
|
struct aic7xxx_scb *scb;
|
10116 |
|
|
struct aic7xxx_hwscb *hscb;
|
10117 |
|
|
int result = -1;
|
10118 |
|
|
int channel;
|
10119 |
|
|
unsigned char saved_scbptr, lastphase;
|
10120 |
|
|
unsigned char hscb_index;
|
10121 |
|
|
int disconnected;
|
10122 |
|
|
|
10123 |
|
|
scb = (p->scb_data->scb_array[aic7xxx_position(cmd)]);
|
10124 |
|
|
hscb = scb->hscb;
|
10125 |
|
|
|
10126 |
|
|
lastphase = aic_inb(p, LASTPHASE);
|
10127 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
|
10128 |
|
|
{
|
10129 |
|
|
printk(INFO_LEAD "Bus Device reset, scb flags 0x%x, ",
|
10130 |
|
|
p->host_no, CTL_OF_SCB(scb), scb->flags);
|
10131 |
|
|
switch (lastphase)
|
10132 |
|
|
{
|
10133 |
|
|
case P_DATAOUT:
|
10134 |
|
|
printk("Data-Out phase\n");
|
10135 |
|
|
break;
|
10136 |
|
|
case P_DATAIN:
|
10137 |
|
|
printk("Data-In phase\n");
|
10138 |
|
|
break;
|
10139 |
|
|
case P_COMMAND:
|
10140 |
|
|
printk("Command phase\n");
|
10141 |
|
|
break;
|
10142 |
|
|
case P_MESGOUT:
|
10143 |
|
|
printk("Message-Out phase\n");
|
10144 |
|
|
break;
|
10145 |
|
|
case P_STATUS:
|
10146 |
|
|
printk("Status phase\n");
|
10147 |
|
|
break;
|
10148 |
|
|
case P_MESGIN:
|
10149 |
|
|
printk("Message-In phase\n");
|
10150 |
|
|
break;
|
10151 |
|
|
default:
|
10152 |
|
|
/*
|
10153 |
|
|
* We're not in a valid phase, so assume we're idle.
|
10154 |
|
|
*/
|
10155 |
|
|
printk("while idle, LASTPHASE = 0x%x\n", lastphase);
|
10156 |
|
|
break;
|
10157 |
|
|
}
|
10158 |
|
|
printk(INFO_LEAD "SCSISIGI 0x%x, SEQADDR 0x%x, SSTAT0 0x%x, SSTAT1 "
|
10159 |
|
|
"0x%x\n", p->host_no, CTL_OF_SCB(scb),
|
10160 |
|
|
aic_inb(p, SCSISIGI),
|
10161 |
|
|
aic_inb(p, SEQADDR0) | (aic_inb(p, SEQADDR1) << 8),
|
10162 |
|
|
aic_inb(p, SSTAT0), aic_inb(p, SSTAT1));
|
10163 |
|
|
}
|
10164 |
|
|
|
10165 |
|
|
channel = cmd->channel;
|
10166 |
|
|
|
10167 |
|
|
/*
|
10168 |
|
|
* Send a Device Reset Message:
|
10169 |
|
|
* The target that is holding up the bus may not be the same as
|
10170 |
|
|
* the one that triggered this timeout (different commands have
|
10171 |
|
|
* different timeout lengths). Our strategy here is to queue an
|
10172 |
|
|
* abort message to the timed out target if it is disconnected.
|
10173 |
|
|
* Otherwise, if we have an active target we stuff the message buffer
|
10174 |
|
|
* with an abort message and assert ATN in the hopes that the target
|
10175 |
|
|
* will let go of the bus and go to the mesgout phase. If this
|
10176 |
|
|
* fails, we'll get another timeout a few seconds later which will
|
10177 |
|
|
* attempt a bus reset.
|
10178 |
|
|
*/
|
10179 |
|
|
saved_scbptr = aic_inb(p, SCBPTR);
|
10180 |
|
|
disconnected = FALSE;
|
10181 |
|
|
|
10182 |
|
|
if (lastphase != P_BUSFREE)
|
10183 |
|
|
{
|
10184 |
|
|
if (aic_inb(p, SCB_TAG) >= p->scb_data->numscbs)
|
10185 |
|
|
{
|
10186 |
|
|
printk(WARN_LEAD "Invalid SCB ID %d is active, "
|
10187 |
|
|
"SCB flags = 0x%x.\n", p->host_no,
|
10188 |
|
|
CTL_OF_CMD(cmd), scb->hscb->tag, scb->flags);
|
10189 |
|
|
return(SCSI_RESET_ERROR);
|
10190 |
|
|
}
|
10191 |
|
|
if (scb->hscb->tag == aic_inb(p, SCB_TAG))
|
10192 |
|
|
{
|
10193 |
|
|
if ( (lastphase != P_MESGOUT) && (lastphase != P_MESGIN) )
|
10194 |
|
|
{
|
10195 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
|
10196 |
|
|
printk(INFO_LEAD "Device reset message in "
|
10197 |
|
|
"message buffer\n", p->host_no, CTL_OF_SCB(scb));
|
10198 |
|
|
scb->flags |= SCB_RESET | SCB_DEVICE_RESET;
|
10199 |
|
|
aic7xxx_error(scb->cmd) = DID_RESET;
|
10200 |
|
|
p->dev_flags[TARGET_INDEX(scb->cmd)] |=
|
10201 |
|
|
BUS_DEVICE_RESET_PENDING;
|
10202 |
|
|
/* Send the abort message to the active SCB. */
|
10203 |
|
|
aic_outb(p, HOST_MSG, MSG_OUT);
|
10204 |
|
|
aic_outb(p, lastphase | ATNO, SCSISIGO);
|
10205 |
|
|
return(SCSI_RESET_PENDING);
|
10206 |
|
|
}
|
10207 |
|
|
else
|
10208 |
|
|
{
|
10209 |
|
|
/* We want to send out the message, but it could screw an already */
|
10210 |
|
|
/* in place and being used message. Instead, we return an error */
|
10211 |
|
|
/* to try and start the bus reset phase since this command is */
|
10212 |
|
|
/* probably hung (aborts failed, and now reset is failing). We */
|
10213 |
|
|
/* also make sure to set BUS_DEVICE_RESET_PENDING so we won't try */
|
10214 |
|
|
/* any more on this device, but instead will escalate to a bus or */
|
10215 |
|
|
/* host reset (additionally, we won't try to abort any more). */
|
10216 |
|
|
printk(WARN_LEAD "Device reset, Message buffer "
|
10217 |
|
|
"in use\n", p->host_no, CTL_OF_SCB(scb));
|
10218 |
|
|
scb->flags |= SCB_RESET | SCB_DEVICE_RESET;
|
10219 |
|
|
aic7xxx_error(scb->cmd) = DID_RESET;
|
10220 |
|
|
p->dev_flags[TARGET_INDEX(scb->cmd)] |=
|
10221 |
|
|
BUS_DEVICE_RESET_PENDING;
|
10222 |
|
|
return(SCSI_RESET_ERROR);
|
10223 |
|
|
}
|
10224 |
|
|
}
|
10225 |
|
|
} /* if (last_phase != P_BUSFREE).....indicates we are idle and can work */
|
10226 |
|
|
hscb_index = aic7xxx_find_scb(p, scb);
|
10227 |
|
|
if (hscb_index == SCB_LIST_NULL)
|
10228 |
|
|
{
|
10229 |
|
|
disconnected = (aic7xxx_scb_on_qoutfifo(p, scb)) ? FALSE : TRUE;
|
10230 |
|
|
}
|
10231 |
|
|
else
|
10232 |
|
|
{
|
10233 |
|
|
aic_outb(p, hscb_index, SCBPTR);
|
10234 |
|
|
if (aic_inb(p, SCB_CONTROL) & DISCONNECTED)
|
10235 |
|
|
{
|
10236 |
|
|
disconnected = TRUE;
|
10237 |
|
|
}
|
10238 |
|
|
}
|
10239 |
|
|
if (disconnected)
|
10240 |
|
|
{
|
10241 |
|
|
/*
|
10242 |
|
|
* Simply set the MK_MESSAGE flag and the SEQINT handler will do
|
10243 |
|
|
* the rest on a reconnect.
|
10244 |
|
|
*/
|
10245 |
|
|
scb->hscb->control |= MK_MESSAGE;
|
10246 |
|
|
scb->flags |= SCB_RESET | SCB_DEVICE_RESET;
|
10247 |
|
|
p->dev_flags[TARGET_INDEX(scb->cmd)] |=
|
10248 |
|
|
BUS_DEVICE_RESET_PENDING;
|
10249 |
|
|
if (hscb_index != SCB_LIST_NULL)
|
10250 |
|
|
{
|
10251 |
|
|
unsigned char scb_control;
|
10252 |
|
|
|
10253 |
|
|
aic_outb(p, hscb_index, SCBPTR);
|
10254 |
|
|
scb_control = aic_inb(p, SCB_CONTROL);
|
10255 |
|
|
aic_outb(p, scb_control | MK_MESSAGE, SCB_CONTROL);
|
10256 |
|
|
}
|
10257 |
|
|
/*
|
10258 |
|
|
* Actually requeue this SCB in case we can select the
|
10259 |
|
|
* device before it reconnects. If the transaction we
|
10260 |
|
|
* want to abort is not tagged, then this will be the only
|
10261 |
|
|
* outstanding command and we can simply shove it on the
|
10262 |
|
|
* qoutfifo and be done. If it is tagged, then it goes right
|
10263 |
|
|
* in with all the others, no problem :) We need to add it
|
10264 |
|
|
* to the qinfifo and let the sequencer know it is there.
|
10265 |
|
|
* Now, the only problem left to deal with is, *IF* this
|
10266 |
|
|
* command completes, in spite of the MK_MESSAGE bit in the
|
10267 |
|
|
* control byte, then we need to pick that up in the interrupt
|
10268 |
|
|
* routine and clean things up. This *shouldn't* ever happen.
|
10269 |
|
|
*/
|
10270 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
|
10271 |
|
|
printk(INFO_LEAD "Queueing device reset "
|
10272 |
|
|
"command.\n", p->host_no, CTL_OF_SCB(scb));
|
10273 |
|
|
p->qinfifo[p->qinfifonext++] = scb->hscb->tag;
|
10274 |
|
|
if (p->features & AHC_QUEUE_REGS)
|
10275 |
|
|
aic_outb(p, p->qinfifonext, HNSCB_QOFF);
|
10276 |
|
|
else
|
10277 |
|
|
aic_outb(p, p->qinfifonext, KERNEL_QINPOS);
|
10278 |
|
|
scb->flags |= SCB_QUEUED_ABORT;
|
10279 |
|
|
result = SCSI_RESET_PENDING;
|
10280 |
|
|
}
|
10281 |
|
|
else if (result == -1)
|
10282 |
|
|
{
|
10283 |
|
|
result = SCSI_RESET_ERROR;
|
10284 |
|
|
}
|
10285 |
|
|
aic_outb(p, saved_scbptr, SCBPTR);
|
10286 |
|
|
return (result);
|
10287 |
|
|
}
|
10288 |
|
|
|
10289 |
|
|
|
10290 |
|
|
/*+F*************************************************************************
|
10291 |
|
|
* Function:
|
10292 |
|
|
* aic7xxx_panic_abort
|
10293 |
|
|
*
|
10294 |
|
|
* Description:
|
10295 |
|
|
* Abort the current SCSI command(s).
|
10296 |
|
|
*-F*************************************************************************/
|
10297 |
|
|
void
|
10298 |
|
|
aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd)
|
10299 |
|
|
{
|
10300 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
|
10301 |
|
|
int i, mask, found, need_tag;
|
10302 |
|
|
struct aic7xxx_scb *scb;
|
10303 |
|
|
unsigned char qinpos, hscbp;
|
10304 |
|
|
|
10305 |
|
|
found = FALSE;
|
10306 |
|
|
#endif
|
10307 |
|
|
|
10308 |
|
|
printk("aic7xxx driver version %s/%s\n", AIC7XXX_C_VERSION,
|
10309 |
|
|
UTS_RELEASE);
|
10310 |
|
|
printk("Controller type:\n %s\n", board_names[p->board_name_index]);
|
10311 |
|
|
printk("p->flags=0x%x, p->chip=0x%x, p->features=0x%x, "
|
10312 |
|
|
"sequencer %s paused\n",
|
10313 |
|
|
p->flags, p->chip, p->features,
|
10314 |
|
|
(aic_inb(p, HCNTRL) & PAUSE) ? "is" : "isn't" );
|
10315 |
|
|
pause_sequencer(p);
|
10316 |
|
|
disable_irq(p->irq);
|
10317 |
|
|
aic7xxx_print_card(p);
|
10318 |
|
|
aic7xxx_print_scratch_ram(p);
|
10319 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
|
10320 |
|
|
for(i=0; i<MAX_TARGETS; i++)
|
10321 |
|
|
{
|
10322 |
|
|
if(p->dev_flags[i] & DEVICE_PRESENT)
|
10323 |
|
|
{
|
10324 |
|
|
mask = (0x01 << i);
|
10325 |
|
|
printk(INFO_LEAD "dev_flags=0x%x, WDTR:%c/%c/%c, SDTR:%c/%c/%c,"
|
10326 |
|
|
" q_depth=%d:%d\n",
|
10327 |
|
|
p->host_no, 0, i, 0, p->dev_flags[i],
|
10328 |
|
|
(p->wdtr_pending & mask) ? 'Y' : 'N',
|
10329 |
|
|
(p->needwdtr & mask) ? 'Y' : 'N',
|
10330 |
|
|
(p->needwdtr_copy & mask) ? 'Y' : 'N',
|
10331 |
|
|
(p->sdtr_pending & mask) ? 'Y' : 'N',
|
10332 |
|
|
(p->needsdtr & mask) ? 'Y' : 'N',
|
10333 |
|
|
(p->needsdtr_copy & mask) ? 'Y' : 'N',
|
10334 |
|
|
p->dev_active_cmds[i],
|
10335 |
|
|
p->dev_max_queue_depth[i] );
|
10336 |
|
|
printk(INFO_LEAD "targ_scsirate=0x%x", p->host_no, 0, i, 0,
|
10337 |
|
|
aic_inb(p, TARG_SCSIRATE + i));
|
10338 |
|
|
if (p->features & AHC_ULTRA2)
|
10339 |
|
|
printk(", targ_offset=%d", aic_inb(p, TARG_OFFSET + i));
|
10340 |
|
|
printk("\n");
|
10341 |
|
|
}
|
10342 |
|
|
}
|
10343 |
|
|
/*
|
10344 |
|
|
* Search for this command and see if we can't track it down, it's the
|
10345 |
|
|
* one causing the timeout. Print out this command first, then all other
|
10346 |
|
|
* active commands afterwords.
|
10347 |
|
|
*/
|
10348 |
|
|
need_tag = -1;
|
10349 |
|
|
if ( cmd )
|
10350 |
|
|
{
|
10351 |
|
|
scb = p->scb_data->scb_array[aic7xxx_position(cmd)];
|
10352 |
|
|
if ( (scb->flags & SCB_ACTIVE) && (scb->cmd == cmd) )
|
10353 |
|
|
{
|
10354 |
|
|
printk("Timed out command is scb #%d:\n", scb->hscb->tag);
|
10355 |
|
|
printk("Tag%d: flags=0x%x, control=0x%x, TCL=0x%x, %s\n", scb->hscb->tag,
|
10356 |
|
|
scb->flags, scb->hscb->control, scb->hscb->target_channel_lun,
|
10357 |
|
|
(scb->flags & SCB_WAITINGQ) ? "WAITINGQ" : "Sent" );
|
10358 |
|
|
need_tag = scb->hscb->tag;
|
10359 |
|
|
if (scb->flags & SCB_WAITINGQ) found=TRUE;
|
10360 |
|
|
}
|
10361 |
|
|
}
|
10362 |
|
|
printk("QINFIFO: (TAG) ");
|
10363 |
|
|
qinpos = aic_inb(p, QINPOS);
|
10364 |
|
|
while ( qinpos != p->qinfifonext )
|
10365 |
|
|
{
|
10366 |
|
|
if (p->qinfifo[qinpos] == need_tag)
|
10367 |
|
|
found=TRUE;
|
10368 |
|
|
printk("%d ", p->qinfifo[qinpos++]);
|
10369 |
|
|
}
|
10370 |
|
|
printk("\n");
|
10371 |
|
|
printk("Current SCB: (SCBPTR/TAG/CONTROL) %d/%d/0x%x\n", aic_inb(p, SCBPTR),
|
10372 |
|
|
aic_inb(p, SCB_TAG), aic_inb(p, SCB_CONTROL) );
|
10373 |
|
|
if (aic_inb(p, SCB_TAG) == need_tag) found=TRUE;
|
10374 |
|
|
printk("WAITING_SCBS: (SCBPTR/TAG/CONTROL) %d->",
|
10375 |
|
|
hscbp = aic_inb(p, WAITING_SCBH));
|
10376 |
|
|
while (hscbp != SCB_LIST_NULL)
|
10377 |
|
|
{
|
10378 |
|
|
aic_outb(p, hscbp, SCBPTR);
|
10379 |
|
|
printk("%d/%d/0x%x ", hscbp, aic_inb(p, SCB_TAG), aic_inb(p, SCB_CONTROL));
|
10380 |
|
|
hscbp = aic_inb(p, SCB_NEXT);
|
10381 |
|
|
if (aic_inb(p, SCB_TAG) == need_tag) found=TRUE;
|
10382 |
|
|
}
|
10383 |
|
|
printk("\n");
|
10384 |
|
|
printk("DISCONNECTED_SCBS: (SCBPTR/TAG/CONTROL) %d->",
|
10385 |
|
|
hscbp = aic_inb(p, DISCONNECTED_SCBH));
|
10386 |
|
|
while (hscbp != SCB_LIST_NULL)
|
10387 |
|
|
{
|
10388 |
|
|
aic_outb(p, hscbp, SCBPTR);
|
10389 |
|
|
printk("%d/%d/0x%x ", hscbp, aic_inb(p, SCB_TAG), aic_inb(p, SCB_CONTROL));
|
10390 |
|
|
hscbp = aic_inb(p, SCB_NEXT);
|
10391 |
|
|
if (aic_inb(p, SCB_TAG) == need_tag) found=TRUE;
|
10392 |
|
|
}
|
10393 |
|
|
printk("\n");
|
10394 |
|
|
printk("FREE_SCBS: (SCBPTR/TAG/CONTROL) %d->",
|
10395 |
|
|
hscbp = aic_inb(p, FREE_SCBH));
|
10396 |
|
|
while (hscbp != SCB_LIST_NULL)
|
10397 |
|
|
{
|
10398 |
|
|
aic_outb(p, hscbp, SCBPTR);
|
10399 |
|
|
printk("%d/%d/0x%x ", hscbp, aic_inb(p, SCB_TAG), aic_inb(p, SCB_CONTROL));
|
10400 |
|
|
hscbp = aic_inb(p, SCB_NEXT);
|
10401 |
|
|
}
|
10402 |
|
|
printk("\n");
|
10403 |
|
|
|
10404 |
|
|
if (found == FALSE)
|
10405 |
|
|
{
|
10406 |
|
|
/*
|
10407 |
|
|
* We haven't found the offending SCB yet, and it should be around
|
10408 |
|
|
* somewhere, so go look for it in the cards SCBs.
|
10409 |
|
|
*/
|
10410 |
|
|
printk("SCBPTR CONTROL TAG PREV NEXT\n");
|
10411 |
|
|
for(i=0; i<p->scb_data->maxhscbs; i++)
|
10412 |
|
|
{
|
10413 |
|
|
aic_outb(p, i, SCBPTR);
|
10414 |
|
|
printk(" %3d %02x %02x %02x %02x\n", i,
|
10415 |
|
|
aic_inb(p, SCB_CONTROL), aic_inb(p, SCB_TAG),
|
10416 |
|
|
aic_inb(p, SCB_PREV), aic_inb(p, SCB_NEXT));
|
10417 |
|
|
}
|
10418 |
|
|
}
|
10419 |
|
|
|
10420 |
|
|
|
10421 |
|
|
for (i=0; i < p->scb_data->numscbs; i++)
|
10422 |
|
|
{
|
10423 |
|
|
scb = p->scb_data->scb_array[i];
|
10424 |
|
|
if ( (scb->flags & SCB_ACTIVE) && (scb->cmd != cmd) )
|
10425 |
|
|
{
|
10426 |
|
|
printk("Tag%d: flags=0x%x, control=0x%x, TCL=0x%x, %s\n", scb->hscb->tag,
|
10427 |
|
|
scb->flags, scb->hscb->control, scb->hscb->target_channel_lun,
|
10428 |
|
|
(scb->flags & SCB_WAITINGQ) ? "WAITINGQ" : "Sent" );
|
10429 |
|
|
}
|
10430 |
|
|
}
|
10431 |
|
|
#endif
|
10432 |
|
|
sti();
|
10433 |
|
|
for(;;) barrier();
|
10434 |
|
|
}
|
10435 |
|
|
|
10436 |
|
|
/*+F*************************************************************************
|
10437 |
|
|
* Function:
|
10438 |
|
|
* aic7xxx_abort
|
10439 |
|
|
*
|
10440 |
|
|
* Description:
|
10441 |
|
|
* Abort the current SCSI command(s).
|
10442 |
|
|
*-F*************************************************************************/
|
10443 |
|
|
int
|
10444 |
|
|
aic7xxx_abort(Scsi_Cmnd *cmd)
|
10445 |
|
|
{
|
10446 |
|
|
struct aic7xxx_scb *scb = NULL;
|
10447 |
|
|
struct aic7xxx_host *p;
|
10448 |
|
|
int result, found=0;
|
10449 |
|
|
unsigned char tmp_char, saved_hscbptr, next_hscbptr, prev_hscbptr;
|
10450 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
|
10451 |
|
|
unsigned long cpu_flags = 0;
|
10452 |
|
|
#endif
|
10453 |
|
|
Scsi_Cmnd *cmd_next, *cmd_prev;
|
10454 |
|
|
|
10455 |
|
|
p = (struct aic7xxx_host *) cmd->host->hostdata;
|
10456 |
|
|
scb = (p->scb_data->scb_array[aic7xxx_position(cmd)]);
|
10457 |
|
|
|
10458 |
|
|
/*
|
10459 |
|
|
* I added a new config option to the driver: "panic_on_abort" that will
|
10460 |
|
|
* cause the driver to panic and the machine to stop on the first abort
|
10461 |
|
|
* or reset call into the driver. At that point, it prints out a lot of
|
10462 |
|
|
* usefull information for me which I can then use to try and debug the
|
10463 |
|
|
* problem. Simply enable the boot time prompt in order to activate this
|
10464 |
|
|
* code.
|
10465 |
|
|
*/
|
10466 |
|
|
if (aic7xxx_panic_on_abort)
|
10467 |
|
|
aic7xxx_panic_abort(p, cmd);
|
10468 |
|
|
|
10469 |
|
|
DRIVER_LOCK
|
10470 |
|
|
|
10471 |
|
|
/*
|
10472 |
|
|
* Run the isr to grab any command in the QOUTFIFO and any other misc.
|
10473 |
|
|
* assundry tasks. This should also set up the bh handler if there is
|
10474 |
|
|
* anything to be done, but it won't run until we are done here since
|
10475 |
|
|
* we are following a straight code path without entering the scheduler
|
10476 |
|
|
* code.
|
10477 |
|
|
*/
|
10478 |
|
|
|
10479 |
|
|
pause_sequencer(p);
|
10480 |
|
|
while ( (aic_inb(p, INTSTAT) & INT_PEND) && !(p->flags & AHC_IN_ISR))
|
10481 |
|
|
{
|
10482 |
|
|
aic7xxx_isr(p->irq, p, (void *)NULL);
|
10483 |
|
|
pause_sequencer(p);
|
10484 |
|
|
aic7xxx_done_cmds_complete(p);
|
10485 |
|
|
}
|
10486 |
|
|
|
10487 |
|
|
if ((scb == NULL) || (cmd->serial_number != cmd->serial_number_at_timeout))
|
10488 |
|
|
/* Totally bogus cmd since it points beyond our */
|
10489 |
|
|
{ /* valid SCB range or doesn't even match it's own*/
|
10490 |
|
|
/* timeout serial number. */
|
10491 |
|
|
if (aic7xxx_verbose & VERBOSE_ABORT_MID)
|
10492 |
|
|
printk(INFO_LEAD "Abort called with bogus Scsi_Cmnd "
|
10493 |
|
|
"pointer.\n", p->host_no, CTL_OF_CMD(cmd));
|
10494 |
|
|
unpause_sequencer(p, FALSE);
|
10495 |
|
|
DRIVER_UNLOCK
|
10496 |
|
|
return(SCSI_ABORT_NOT_RUNNING);
|
10497 |
|
|
}
|
10498 |
|
|
if (scb->cmd != cmd) /* Hmmm...either this SCB is currently free with a */
|
10499 |
|
|
{ /* NULL cmd pointer (NULLed out when freed) or it */
|
10500 |
|
|
/* has already been recycled for another command */
|
10501 |
|
|
/* Either way, this SCB has nothing to do with this*/
|
10502 |
|
|
/* command and we need to deal with cmd without */
|
10503 |
|
|
/* touching the SCB. */
|
10504 |
|
|
/* The theory here is to return a value that will */
|
10505 |
|
|
/* make the queued for complete command actually */
|
10506 |
|
|
/* finish successfully, or to indicate that we */
|
10507 |
|
|
/* don't have this cmd any more and the mid level */
|
10508 |
|
|
/* code needs to find it. */
|
10509 |
|
|
cmd_next = p->completeq.head;
|
10510 |
|
|
cmd_prev = NULL;
|
10511 |
|
|
while (cmd_next != NULL)
|
10512 |
|
|
{
|
10513 |
|
|
if (cmd_next == cmd)
|
10514 |
|
|
{
|
10515 |
|
|
if (aic7xxx_verbose & VERBOSE_ABORT_PROCESS)
|
10516 |
|
|
printk(INFO_LEAD "Abort called for command "
|
10517 |
|
|
"on completeq, completing.\n", p->host_no, CTL_OF_CMD(cmd));
|
10518 |
|
|
if ( cmd_prev == NULL )
|
10519 |
|
|
p->completeq.head = (Scsi_Cmnd *)cmd_next->host_scribble;
|
10520 |
|
|
else
|
10521 |
|
|
cmd_prev->host_scribble = cmd_next->host_scribble;
|
10522 |
|
|
cmd_next->scsi_done(cmd_next);
|
10523 |
|
|
unpause_sequencer(p, FALSE);
|
10524 |
|
|
DRIVER_UNLOCK
|
10525 |
|
|
return(SCSI_ABORT_NOT_RUNNING); /* It's already back as a successful
|
10526 |
|
|
* completion */
|
10527 |
|
|
}
|
10528 |
|
|
cmd_prev = cmd_next;
|
10529 |
|
|
cmd_next = (Scsi_Cmnd *)cmd_next->host_scribble;
|
10530 |
|
|
}
|
10531 |
|
|
if (aic7xxx_verbose & VERBOSE_ABORT_MID)
|
10532 |
|
|
printk(INFO_LEAD "Abort called for already completed"
|
10533 |
|
|
" command.\n", p->host_no, CTL_OF_CMD(cmd));
|
10534 |
|
|
unpause_sequencer(p, FALSE);
|
10535 |
|
|
DRIVER_UNLOCK
|
10536 |
|
|
return(SCSI_ABORT_NOT_RUNNING);
|
10537 |
|
|
}
|
10538 |
|
|
|
10539 |
|
|
/* At this point we know the following:
|
10540 |
|
|
* the SCB pointer is valid
|
10541 |
|
|
* the command pointer passed in to us and the scb->cmd pointer match
|
10542 |
|
|
* this then means that the command we need to abort is the same as the
|
10543 |
|
|
* command held by the scb pointer and is a valid abort request.
|
10544 |
|
|
* Now, we just have to figure out what to do from here. Current plan is:
|
10545 |
|
|
* if we have already been here on this command, escalate to a reset
|
10546 |
|
|
* if scb is on waiting list or QINFIFO, send it back as aborted, but
|
10547 |
|
|
* we also need to be aware of the possibility that we could be using
|
10548 |
|
|
* a faked negotiation command that is holding this command up, if
|
10549 |
|
|
* so we need to take care of that command instead, which means we
|
10550 |
|
|
* would then treat this one like it was sitting around disconnected
|
10551 |
|
|
* instead.
|
10552 |
|
|
* if scb is on WAITING_SCB list in sequencer, free scb and send back
|
10553 |
|
|
* if scb is disconnected and not completed, abort with abort message
|
10554 |
|
|
* if scb is currently running, then it may be causing the bus to hang
|
10555 |
|
|
* so we want a return value that indicates a reset would be appropriate
|
10556 |
|
|
* if the command does not finish shortly
|
10557 |
|
|
* if scb is already complete but not on completeq, we're screwed because
|
10558 |
|
|
* this can't happen (except if the command is in the QOUTFIFO, in which
|
10559 |
|
|
* case we would like it to complete successfully instead of having to
|
10560 |
|
|
* to be re-done)
|
10561 |
|
|
* All other scenarios already dealt with by previous code.
|
10562 |
|
|
*/
|
10563 |
|
|
|
10564 |
|
|
if ( scb->flags & (SCB_ABORT | SCB_RESET | SCB_QUEUED_ABORT) )
|
10565 |
|
|
{
|
10566 |
|
|
if (aic7xxx_verbose & VERBOSE_ABORT_PROCESS)
|
10567 |
|
|
printk(INFO_LEAD "SCB aborted once already, "
|
10568 |
|
|
"escalating.\n", p->host_no, CTL_OF_SCB(scb));
|
10569 |
|
|
unpause_sequencer(p, FALSE);
|
10570 |
|
|
DRIVER_UNLOCK
|
10571 |
|
|
return(SCSI_ABORT_SNOOZE);
|
10572 |
|
|
}
|
10573 |
|
|
if ( (p->flags & (AHC_RESET_PENDING | AHC_ABORT_PENDING)) ||
|
10574 |
|
|
(p->dev_flags[TARGET_INDEX(scb->cmd)] &
|
10575 |
|
|
BUS_DEVICE_RESET_PENDING) )
|
10576 |
|
|
{
|
10577 |
|
|
if (aic7xxx_verbose & VERBOSE_ABORT_PROCESS)
|
10578 |
|
|
printk(INFO_LEAD "Reset/Abort pending for this "
|
10579 |
|
|
"device, not wasting our time.\n", p->host_no, CTL_OF_SCB(scb));
|
10580 |
|
|
unpause_sequencer(p, FALSE);
|
10581 |
|
|
DRIVER_UNLOCK
|
10582 |
|
|
return(SCSI_ABORT_PENDING);
|
10583 |
|
|
}
|
10584 |
|
|
|
10585 |
|
|
found = 0;
|
10586 |
|
|
p->flags |= AHC_IN_ABORT;
|
10587 |
|
|
if (aic7xxx_verbose & VERBOSE_ABORT)
|
10588 |
|
|
printk(INFO_LEAD "Aborting scb %d, flags 0x%x\n",
|
10589 |
|
|
p->host_no, CTL_OF_SCB(scb), scb->hscb->tag, scb->flags);
|
10590 |
|
|
|
10591 |
|
|
/*
|
10592 |
|
|
* First, let's check to see if the currently running command is our target
|
10593 |
|
|
* since if it is, the return is fairly easy and quick since we don't want
|
10594 |
|
|
* to touch the command in case it might complete, but we do want a timeout
|
10595 |
|
|
* in case it's actually hung, so we really do nothing, but tell the mid
|
10596 |
|
|
* level code to reset the timeout.
|
10597 |
|
|
*/
|
10598 |
|
|
|
10599 |
|
|
if ( scb->hscb->tag == aic_inb(p, SCB_TAG) )
|
10600 |
|
|
{
|
10601 |
|
|
/*
|
10602 |
|
|
* Check to see if the sequencer is just sitting on this command, or
|
10603 |
|
|
* if it's actively being run.
|
10604 |
|
|
*/
|
10605 |
|
|
result = aic_inb(p, LASTPHASE);
|
10606 |
|
|
switch (result)
|
10607 |
|
|
{
|
10608 |
|
|
case P_DATAOUT: /* For any of these cases, we can assume we are */
|
10609 |
|
|
case P_DATAIN: /* an active command and act according. For */
|
10610 |
|
|
case P_COMMAND: /* anything else we are going to fall on through*/
|
10611 |
|
|
case P_STATUS: /* The SCSI_ABORT_SNOOZE will give us two abort */
|
10612 |
|
|
case P_MESGOUT: /* chances to finish and then escalate to a */
|
10613 |
|
|
case P_MESGIN: /* reset call */
|
10614 |
|
|
if (aic7xxx_verbose & VERBOSE_ABORT_PROCESS)
|
10615 |
|
|
printk(INFO_LEAD "SCB is currently active. "
|
10616 |
|
|
"Waiting on completion.\n", p->host_no, CTL_OF_SCB(scb));
|
10617 |
|
|
unpause_sequencer(p, FALSE);
|
10618 |
|
|
p->flags &= ~AHC_IN_ABORT;
|
10619 |
|
|
scb->flags |= SCB_RECOVERY_SCB; /* Note the fact that we've been */
|
10620 |
|
|
p->flags |= AHC_ABORT_PENDING; /* here so we will know not to */
|
10621 |
|
|
DRIVER_UNLOCK /* muck with other SCBs if this */
|
10622 |
|
|
return(SCSI_ABORT_PENDING); /* one doesn't complete and clear */
|
10623 |
|
|
break; /* out. */
|
10624 |
|
|
default:
|
10625 |
|
|
break;
|
10626 |
|
|
}
|
10627 |
|
|
}
|
10628 |
|
|
|
10629 |
|
|
if ((found == 0) && (scb->flags & SCB_WAITINGQ))
|
10630 |
|
|
{
|
10631 |
|
|
int tindex = TARGET_INDEX(cmd);
|
10632 |
|
|
#ifdef AIC7XXX_FAKE_NEGOTIATION_CMDS
|
10633 |
|
|
unsigned short mask;
|
10634 |
|
|
|
10635 |
|
|
mask = (1 << tindex);
|
10636 |
|
|
|
10637 |
|
|
if (p->wdtr_pending & mask)
|
10638 |
|
|
{
|
10639 |
|
|
if (p->dev_wdtr_cmnd[tindex]->next != cmd)
|
10640 |
|
|
found = 1;
|
10641 |
|
|
else
|
10642 |
|
|
found = 0;
|
10643 |
|
|
}
|
10644 |
|
|
else if (p->sdtr_pending & mask)
|
10645 |
|
|
{
|
10646 |
|
|
if (p->dev_sdtr_cmnd[tindex]->next != cmd)
|
10647 |
|
|
found = 1;
|
10648 |
|
|
else
|
10649 |
|
|
found = 0;
|
10650 |
|
|
}
|
10651 |
|
|
else
|
10652 |
|
|
{
|
10653 |
|
|
found = 1;
|
10654 |
|
|
}
|
10655 |
|
|
if (found == 0)
|
10656 |
|
|
{
|
10657 |
|
|
/*
|
10658 |
|
|
* OK..this means the command we are currently getting an abort
|
10659 |
|
|
* for has an outstanding negotiation command in front of it.
|
10660 |
|
|
* We don't really have a way to tie back into the negotiation
|
10661 |
|
|
* commands, so we just send this back as pending, then it
|
10662 |
|
|
* will get reset in 2 seconds.
|
10663 |
|
|
*/
|
10664 |
|
|
unpause_sequencer(p, TRUE);
|
10665 |
|
|
scb->flags |= SCB_ABORT;
|
10666 |
|
|
DRIVER_UNLOCK
|
10667 |
|
|
return(SCSI_ABORT_PENDING);
|
10668 |
|
|
}
|
10669 |
|
|
#endif
|
10670 |
|
|
if (aic7xxx_verbose & VERBOSE_ABORT_PROCESS)
|
10671 |
|
|
printk(INFO_LEAD "SCB found on waiting list and "
|
10672 |
|
|
"aborted.\n", p->host_no, CTL_OF_SCB(scb));
|
10673 |
|
|
scbq_remove(&p->waiting_scbs, scb);
|
10674 |
|
|
scbq_remove(&p->delayed_scbs[tindex], scb);
|
10675 |
|
|
p->dev_active_cmds[tindex]++;
|
10676 |
|
|
p->activescbs++;
|
10677 |
|
|
scb->flags &= ~(SCB_WAITINGQ | SCB_ACTIVE);
|
10678 |
|
|
scb->flags |= SCB_ABORT | SCB_QUEUED_FOR_DONE;
|
10679 |
|
|
found = 1;
|
10680 |
|
|
}
|
10681 |
|
|
|
10682 |
|
|
/*
|
10683 |
|
|
* We just checked the waiting_q, now for the QINFIFO
|
10684 |
|
|
*/
|
10685 |
|
|
if ( found == 0 )
|
10686 |
|
|
{
|
10687 |
|
|
if ( ((found = aic7xxx_search_qinfifo(p, cmd->target,
|
10688 |
|
|
cmd->channel,
|
10689 |
|
|
cmd->lun, scb->hscb->tag, SCB_ABORT | SCB_QUEUED_FOR_DONE,
|
10690 |
|
|
FALSE, NULL)) != 0) &&
|
10691 |
|
|
(aic7xxx_verbose & VERBOSE_ABORT_PROCESS))
|
10692 |
|
|
printk(INFO_LEAD "SCB found in QINFIFO and "
|
10693 |
|
|
"aborted.\n", p->host_no, CTL_OF_SCB(scb));
|
10694 |
|
|
}
|
10695 |
|
|
|
10696 |
|
|
/*
|
10697 |
|
|
* QINFIFO, waitingq, completeq done. Next, check WAITING_SCB list in card
|
10698 |
|
|
*/
|
10699 |
|
|
|
10700 |
|
|
if ( found == 0 )
|
10701 |
|
|
{
|
10702 |
|
|
unsigned char scb_next_ptr;
|
10703 |
|
|
prev_hscbptr = SCB_LIST_NULL;
|
10704 |
|
|
saved_hscbptr = aic_inb(p, SCBPTR);
|
10705 |
|
|
next_hscbptr = aic_inb(p, WAITING_SCBH);
|
10706 |
|
|
while ( next_hscbptr != SCB_LIST_NULL )
|
10707 |
|
|
{
|
10708 |
|
|
aic_outb(p, next_hscbptr, SCBPTR );
|
10709 |
|
|
if ( scb->hscb->tag == aic_inb(p, SCB_TAG) )
|
10710 |
|
|
{
|
10711 |
|
|
found = 1;
|
10712 |
|
|
if (aic7xxx_verbose & VERBOSE_ABORT_PROCESS)
|
10713 |
|
|
printk(INFO_LEAD "SCB found on hardware waiting"
|
10714 |
|
|
" list and aborted.\n", p->host_no, CTL_OF_SCB(scb));
|
10715 |
|
|
if ( prev_hscbptr == SCB_LIST_NULL )
|
10716 |
|
|
{
|
10717 |
|
|
aic_outb(p, aic_inb(p, SCB_NEXT), WAITING_SCBH);
|
10718 |
|
|
/* stop the selection since we just
|
10719 |
|
|
* grabbed the scb out from under the
|
10720 |
|
|
* card
|
10721 |
|
|
*/
|
10722 |
|
|
aic_outb(p, aic_inb(p, SCSISEQ) & ~ENSELO, SCSISEQ);
|
10723 |
|
|
aic_outb(p, CLRSELTIMEO, CLRSINT1);
|
10724 |
|
|
}
|
10725 |
|
|
else
|
10726 |
|
|
{
|
10727 |
|
|
scb_next_ptr = aic_inb(p, SCB_NEXT);
|
10728 |
|
|
aic_outb(p, prev_hscbptr, SCBPTR);
|
10729 |
|
|
aic_outb(p, scb_next_ptr, SCB_NEXT);
|
10730 |
|
|
aic_outb(p, next_hscbptr, SCBPTR);
|
10731 |
|
|
}
|
10732 |
|
|
aic_outb(p, SCB_LIST_NULL, SCB_TAG);
|
10733 |
|
|
aic_outb(p, 0, SCB_CONTROL);
|
10734 |
|
|
aic7xxx_add_curscb_to_free_list(p);
|
10735 |
|
|
scb->flags = SCB_ABORT | SCB_QUEUED_FOR_DONE;
|
10736 |
|
|
break;
|
10737 |
|
|
}
|
10738 |
|
|
prev_hscbptr = next_hscbptr;
|
10739 |
|
|
next_hscbptr = aic_inb(p, SCB_NEXT);
|
10740 |
|
|
}
|
10741 |
|
|
aic_outb(p, saved_hscbptr, SCBPTR );
|
10742 |
|
|
}
|
10743 |
|
|
|
10744 |
|
|
/*
|
10745 |
|
|
* Hmmm...completeq, QOUTFIFO, QINFIFO, WAITING_SCBH, waitingq all checked.
|
10746 |
|
|
* OK...the sequencer's paused, interrupts are off, and we haven't found the
|
10747 |
|
|
* command anyplace where it could be easily aborted. Time for the hard
|
10748 |
|
|
* work. We also know the command is valid. This essentially means the
|
10749 |
|
|
* command is disconnected, or connected but not into any phases yet, which
|
10750 |
|
|
* we know due to the tests we ran earlier on the current active scb phase.
|
10751 |
|
|
* At this point we can queue the abort tag and go on with life.
|
10752 |
|
|
*/
|
10753 |
|
|
|
10754 |
|
|
if ( found == 0 )
|
10755 |
|
|
{
|
10756 |
|
|
p->flags |= AHC_ABORT_PENDING;
|
10757 |
|
|
scb->flags |= SCB_QUEUED_ABORT | SCB_ABORT | SCB_RECOVERY_SCB;
|
10758 |
|
|
scb->hscb->control |= MK_MESSAGE;
|
10759 |
|
|
result=aic7xxx_find_scb(p, scb);
|
10760 |
|
|
if ( result != SCB_LIST_NULL )
|
10761 |
|
|
{
|
10762 |
|
|
saved_hscbptr = aic_inb(p, SCBPTR);
|
10763 |
|
|
aic_outb(p, result, SCBPTR);
|
10764 |
|
|
tmp_char = aic_inb(p, SCB_CONTROL);
|
10765 |
|
|
aic_outb(p, tmp_char | MK_MESSAGE, SCB_CONTROL);
|
10766 |
|
|
aic_outb(p, saved_hscbptr, SCBPTR);
|
10767 |
|
|
}
|
10768 |
|
|
if (aic7xxx_verbose & VERBOSE_ABORT_PROCESS)
|
10769 |
|
|
printk(INFO_LEAD "SCB disconnected. Queueing Abort"
|
10770 |
|
|
" SCB.\n", p->host_no, CTL_OF_SCB(scb));
|
10771 |
|
|
p->qinfifo[p->qinfifonext++] = scb->hscb->tag;
|
10772 |
|
|
if (p->features & AHC_QUEUE_REGS)
|
10773 |
|
|
aic_outb(p, p->qinfifonext, HNSCB_QOFF);
|
10774 |
|
|
else
|
10775 |
|
|
aic_outb(p, p->qinfifonext, KERNEL_QINPOS);
|
10776 |
|
|
}
|
10777 |
|
|
if (found)
|
10778 |
|
|
{
|
10779 |
|
|
aic7xxx_run_done_queue(p, TRUE);
|
10780 |
|
|
aic7xxx_run_waiting_queues(p);
|
10781 |
|
|
}
|
10782 |
|
|
p->flags &= ~AHC_IN_ABORT;
|
10783 |
|
|
unpause_sequencer(p, FALSE);
|
10784 |
|
|
DRIVER_UNLOCK
|
10785 |
|
|
|
10786 |
|
|
/*
|
10787 |
|
|
* On the return value. If we found the command and aborted it, then we know
|
10788 |
|
|
* it's already sent back and there is no reason for a further timeout, so
|
10789 |
|
|
* we use SCSI_ABORT_SUCCESS. On the queued abort side, we aren't so certain
|
10790 |
|
|
* there hasn't been a bus hang or something that might keep the abort from
|
10791 |
|
|
* from completing. Therefore, we use SCSI_ABORT_PENDING. The first time this
|
10792 |
|
|
* is passed back, the timeout on the command gets extended, the second time
|
10793 |
|
|
* we pass this back, the mid level SCSI code calls our reset function, which
|
10794 |
|
|
* would shake loose a hung bus.
|
10795 |
|
|
*/
|
10796 |
|
|
if ( found != 0 )
|
10797 |
|
|
return(SCSI_ABORT_SUCCESS);
|
10798 |
|
|
else
|
10799 |
|
|
return(SCSI_ABORT_PENDING);
|
10800 |
|
|
}
|
10801 |
|
|
|
10802 |
|
|
|
10803 |
|
|
/*+F*************************************************************************
|
10804 |
|
|
* Function:
|
10805 |
|
|
* aic7xxx_reset
|
10806 |
|
|
*
|
10807 |
|
|
* Description:
|
10808 |
|
|
* Resetting the bus always succeeds - is has to, otherwise the
|
10809 |
|
|
* kernel will panic! Try a surgical technique - sending a BUS
|
10810 |
|
|
* DEVICE RESET message - on the offending target before pulling
|
10811 |
|
|
* the SCSI bus reset line.
|
10812 |
|
|
*-F*************************************************************************/
|
10813 |
|
|
int
|
10814 |
|
|
aic7xxx_reset(Scsi_Cmnd *cmd, unsigned int flags)
|
10815 |
|
|
{
|
10816 |
|
|
struct aic7xxx_scb *scb = NULL;
|
10817 |
|
|
struct aic7xxx_host *p;
|
10818 |
|
|
int tindex;
|
10819 |
|
|
int result = -1;
|
10820 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
|
10821 |
|
|
unsigned long cpu_flags = 0;
|
10822 |
|
|
#endif
|
10823 |
|
|
#define DEVICE_RESET 0x01
|
10824 |
|
|
#define BUS_RESET 0x02
|
10825 |
|
|
#define HOST_RESET 0x04
|
10826 |
|
|
#define FAIL 0x08
|
10827 |
|
|
#define RESET_DELAY 0x10
|
10828 |
|
|
int action;
|
10829 |
|
|
Scsi_Cmnd *cmd_prev, *cmd_next;
|
10830 |
|
|
|
10831 |
|
|
|
10832 |
|
|
if ( cmd == NULL )
|
10833 |
|
|
{
|
10834 |
|
|
printk(KERN_WARNING "(scsi?:?:?:?) Reset called with NULL Scsi_Cmnd "
|
10835 |
|
|
"pointer, failing.\n");
|
10836 |
|
|
return(SCSI_RESET_SNOOZE);
|
10837 |
|
|
}
|
10838 |
|
|
|
10839 |
|
|
p = (struct aic7xxx_host *) cmd->host->hostdata;
|
10840 |
|
|
scb = (p->scb_data->scb_array[aic7xxx_position(cmd)]);
|
10841 |
|
|
tindex = TARGET_INDEX(cmd);
|
10842 |
|
|
|
10843 |
|
|
/*
|
10844 |
|
|
* I added a new config option to the driver: "panic_on_abort" that will
|
10845 |
|
|
* cause the driver to panic and the machine to stop on the first abort
|
10846 |
|
|
* or reset call into the driver. At that point, it prints out a lot of
|
10847 |
|
|
* usefull information for me which I can then use to try and debug the
|
10848 |
|
|
* problem. Simply enable the boot time prompt in order to activate this
|
10849 |
|
|
* code.
|
10850 |
|
|
*/
|
10851 |
|
|
if (aic7xxx_panic_on_abort)
|
10852 |
|
|
aic7xxx_panic_abort(p, cmd);
|
10853 |
|
|
|
10854 |
|
|
DRIVER_LOCK
|
10855 |
|
|
|
10856 |
|
|
pause_sequencer(p);
|
10857 |
|
|
while ( (aic_inb(p, INTSTAT) & INT_PEND) && !(p->flags & AHC_IN_ISR))
|
10858 |
|
|
{
|
10859 |
|
|
aic7xxx_isr(p->irq, p, (void *)NULL );
|
10860 |
|
|
pause_sequencer(p);
|
10861 |
|
|
aic7xxx_done_cmds_complete(p);
|
10862 |
|
|
}
|
10863 |
|
|
|
10864 |
|
|
if (scb == NULL)
|
10865 |
|
|
{
|
10866 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_MID)
|
10867 |
|
|
printk(INFO_LEAD "Reset called with bogus Scsi_Cmnd"
|
10868 |
|
|
"->SCB mapping, improvising.\n", p->host_no, CTL_OF_CMD(cmd));
|
10869 |
|
|
if ( flags & SCSI_RESET_SUGGEST_HOST_RESET )
|
10870 |
|
|
{
|
10871 |
|
|
action = HOST_RESET;
|
10872 |
|
|
}
|
10873 |
|
|
else
|
10874 |
|
|
{
|
10875 |
|
|
action = BUS_RESET;
|
10876 |
|
|
}
|
10877 |
|
|
}
|
10878 |
|
|
else if (scb->cmd != cmd)
|
10879 |
|
|
{
|
10880 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_MID)
|
10881 |
|
|
printk(INFO_LEAD "Reset called with recycled SCB "
|
10882 |
|
|
"for cmd.\n", p->host_no, CTL_OF_CMD(cmd));
|
10883 |
|
|
cmd_prev = NULL;
|
10884 |
|
|
cmd_next = p->completeq.head;
|
10885 |
|
|
while ( cmd_next != NULL )
|
10886 |
|
|
{
|
10887 |
|
|
if (cmd_next == cmd)
|
10888 |
|
|
{
|
10889 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_RETURN)
|
10890 |
|
|
printk(INFO_LEAD "Reset, found cmd on completeq"
|
10891 |
|
|
", completing.\n", p->host_no, CTL_OF_CMD(cmd));
|
10892 |
|
|
unpause_sequencer(p, FALSE);
|
10893 |
|
|
DRIVER_UNLOCK
|
10894 |
|
|
return(SCSI_RESET_NOT_RUNNING);
|
10895 |
|
|
}
|
10896 |
|
|
cmd_prev = cmd_next;
|
10897 |
|
|
cmd_next = (Scsi_Cmnd *)cmd_next->host_scribble;
|
10898 |
|
|
}
|
10899 |
|
|
if ( !(flags & SCSI_RESET_SYNCHRONOUS) )
|
10900 |
|
|
{
|
10901 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_RETURN)
|
10902 |
|
|
printk(INFO_LEAD "Reset, cmd not found,"
|
10903 |
|
|
" failing.\n", p->host_no, CTL_OF_CMD(cmd));
|
10904 |
|
|
unpause_sequencer(p, FALSE);
|
10905 |
|
|
DRIVER_UNLOCK
|
10906 |
|
|
return(SCSI_RESET_NOT_RUNNING);
|
10907 |
|
|
}
|
10908 |
|
|
else
|
10909 |
|
|
{
|
10910 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_MID)
|
10911 |
|
|
printk(INFO_LEAD "Reset called, no scb, "
|
10912 |
|
|
"flags 0x%x\n", p->host_no, CTL_OF_CMD(cmd), flags);
|
10913 |
|
|
scb = NULL;
|
10914 |
|
|
action = HOST_RESET;
|
10915 |
|
|
}
|
10916 |
|
|
}
|
10917 |
|
|
else
|
10918 |
|
|
{
|
10919 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_MID)
|
10920 |
|
|
printk(INFO_LEAD "Reset called, scb %d, flags "
|
10921 |
|
|
"0x%x\n", p->host_no, CTL_OF_SCB(scb), scb->hscb->tag, scb->flags);
|
10922 |
|
|
if ( aic7xxx_scb_on_qoutfifo(p, scb) )
|
10923 |
|
|
{
|
10924 |
|
|
if(aic7xxx_verbose & VERBOSE_RESET_RETURN)
|
10925 |
|
|
printk(INFO_LEAD "SCB on qoutfifo, returning.\n", p->host_no,
|
10926 |
|
|
CTL_OF_SCB(scb));
|
10927 |
|
|
unpause_sequencer(p, FALSE);
|
10928 |
|
|
DRIVER_UNLOCK
|
10929 |
|
|
return(SCSI_RESET_NOT_RUNNING);
|
10930 |
|
|
}
|
10931 |
|
|
if ( flags & SCSI_RESET_SUGGEST_HOST_RESET )
|
10932 |
|
|
{
|
10933 |
|
|
action = HOST_RESET;
|
10934 |
|
|
}
|
10935 |
|
|
else if ( flags & SCSI_RESET_SUGGEST_BUS_RESET )
|
10936 |
|
|
{
|
10937 |
|
|
action = BUS_RESET;
|
10938 |
|
|
}
|
10939 |
|
|
else
|
10940 |
|
|
{
|
10941 |
|
|
action = DEVICE_RESET;
|
10942 |
|
|
}
|
10943 |
|
|
}
|
10944 |
|
|
if ( (action & DEVICE_RESET) &&
|
10945 |
|
|
(p->dev_flags[tindex] & BUS_DEVICE_RESET_PENDING) )
|
10946 |
|
|
{
|
10947 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
|
10948 |
|
|
printk(INFO_LEAD "Bus device reset already sent to "
|
10949 |
|
|
"device, escalating.\n", p->host_no, CTL_OF_CMD(cmd));
|
10950 |
|
|
action = BUS_RESET;
|
10951 |
|
|
}
|
10952 |
|
|
if ( (action & DEVICE_RESET) &&
|
10953 |
|
|
(scb->flags & SCB_QUEUED_ABORT) )
|
10954 |
|
|
{
|
10955 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
|
10956 |
|
|
{
|
10957 |
|
|
printk(INFO_LEAD "Have already attempted to reach "
|
10958 |
|
|
"device with queued\n", p->host_no, CTL_OF_CMD(cmd));
|
10959 |
|
|
printk(INFO_LEAD "message, will escalate to bus "
|
10960 |
|
|
"reset.\n", p->host_no, CTL_OF_CMD(cmd));
|
10961 |
|
|
}
|
10962 |
|
|
action = BUS_RESET;
|
10963 |
|
|
}
|
10964 |
|
|
if ( (action & DEVICE_RESET) &&
|
10965 |
|
|
(p->flags & (AHC_RESET_PENDING | AHC_ABORT_PENDING)) )
|
10966 |
|
|
{
|
10967 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
|
10968 |
|
|
printk(INFO_LEAD "Bus device reset stupid when "
|
10969 |
|
|
"other action has failed.\n", p->host_no, CTL_OF_CMD(cmd));
|
10970 |
|
|
action = BUS_RESET;
|
10971 |
|
|
}
|
10972 |
|
|
if ( (action & BUS_RESET) && !(p->features & AHC_TWIN) )
|
10973 |
|
|
{
|
10974 |
|
|
action = HOST_RESET;
|
10975 |
|
|
}
|
10976 |
|
|
if ( (p->dev_flags[tindex] & DEVICE_RESET_DELAY) &&
|
10977 |
|
|
!(action & (HOST_RESET | BUS_RESET)))
|
10978 |
|
|
{
|
10979 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
|
10980 |
|
|
{
|
10981 |
|
|
printk(INFO_LEAD "Reset called too soon after last "
|
10982 |
|
|
"reset without requesting\n", p->host_no, CTL_OF_CMD(cmd));
|
10983 |
|
|
printk(INFO_LEAD "bus or host reset, escalating.\n", p->host_no,
|
10984 |
|
|
CTL_OF_CMD(cmd));
|
10985 |
|
|
}
|
10986 |
|
|
action = BUS_RESET;
|
10987 |
|
|
}
|
10988 |
|
|
if ( (p->flags & AHC_RESET_DELAY) &&
|
10989 |
|
|
(action & (HOST_RESET | BUS_RESET)) )
|
10990 |
|
|
{
|
10991 |
|
|
if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
|
10992 |
|
|
printk(INFO_LEAD "Reset called too soon after "
|
10993 |
|
|
"last bus reset, delaying.\n", p->host_no, CTL_OF_CMD(cmd));
|
10994 |
|
|
action = RESET_DELAY;
|
10995 |
|
|
}
|
10996 |
|
|
/*
|
10997 |
|
|
* By this point, we want to already know what we are going to do and
|
10998 |
|
|
* only have the following code implement our course of action.
|
10999 |
|
|
*/
|
11000 |
|
|
switch (action)
|
11001 |
|
|
{
|
11002 |
|
|
case RESET_DELAY:
|
11003 |
|
|
unpause_sequencer(p, FALSE);
|
11004 |
|
|
DRIVER_UNLOCK
|
11005 |
|
|
return(SCSI_RESET_PENDING);
|
11006 |
|
|
break;
|
11007 |
|
|
case FAIL:
|
11008 |
|
|
unpause_sequencer(p, FALSE);
|
11009 |
|
|
DRIVER_UNLOCK
|
11010 |
|
|
return(SCSI_RESET_ERROR);
|
11011 |
|
|
break;
|
11012 |
|
|
case DEVICE_RESET:
|
11013 |
|
|
p->flags |= AHC_IN_RESET;
|
11014 |
|
|
result = aic7xxx_bus_device_reset(p, cmd);
|
11015 |
|
|
aic7xxx_run_done_queue(p, TRUE);
|
11016 |
|
|
/* We can't rely on run_waiting_queues to unpause the sequencer for
|
11017 |
|
|
* PCI based controllers since we use AAP */
|
11018 |
|
|
aic7xxx_run_waiting_queues(p);
|
11019 |
|
|
unpause_sequencer(p, FALSE);
|
11020 |
|
|
p->flags &= ~AHC_IN_RESET;
|
11021 |
|
|
DRIVER_UNLOCK
|
11022 |
|
|
return(result);
|
11023 |
|
|
break;
|
11024 |
|
|
case BUS_RESET:
|
11025 |
|
|
case HOST_RESET:
|
11026 |
|
|
default:
|
11027 |
|
|
p->flags |= AHC_IN_RESET | AHC_RESET_DELAY;
|
11028 |
|
|
p->dev_expires[p->scsi_id] = jiffies + (3 * HZ);
|
11029 |
|
|
p->dev_timer_active |= (0x01 << p->scsi_id);
|
11030 |
|
|
if ( !(p->dev_timer_active & (0x01 << MAX_TARGETS)) ||
|
11031 |
|
|
time_after_eq(p->dev_timer.expires, p->dev_expires[p->scsi_id]) )
|
11032 |
|
|
{
|
11033 |
|
|
del_timer(&p->dev_timer);
|
11034 |
|
|
p->dev_timer.expires = p->dev_expires[p->scsi_id];
|
11035 |
|
|
add_timer(&p->dev_timer);
|
11036 |
|
|
p->dev_timer_active |= (0x01 << MAX_TARGETS);
|
11037 |
|
|
}
|
11038 |
|
|
aic7xxx_reset_channel(p, cmd->channel, TRUE);
|
11039 |
|
|
if ( (p->features & AHC_TWIN) && (action & HOST_RESET) )
|
11040 |
|
|
{
|
11041 |
|
|
aic7xxx_reset_channel(p, cmd->channel ^ 0x01, TRUE);
|
11042 |
|
|
restart_sequencer(p);
|
11043 |
|
|
}
|
11044 |
|
|
if (action != HOST_RESET)
|
11045 |
|
|
result = SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
|
11046 |
|
|
else
|
11047 |
|
|
{
|
11048 |
|
|
result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET;
|
11049 |
|
|
aic_outb(p, aic_inb(p, SIMODE1) & ~(ENREQINIT|ENBUSFREE),
|
11050 |
|
|
SIMODE1);
|
11051 |
|
|
aic7xxx_clear_intstat(p);
|
11052 |
|
|
p->flags &= ~AHC_HANDLING_REQINITS;
|
11053 |
|
|
p->msg_type = MSG_TYPE_NONE;
|
11054 |
|
|
p->msg_index = 0;
|
11055 |
|
|
p->msg_len = 0;
|
11056 |
|
|
}
|
11057 |
|
|
aic7xxx_run_done_queue(p, TRUE);
|
11058 |
|
|
/*
|
11059 |
|
|
* If this a SCSI_RESET_SYNCHRONOUS then the command we were given is
|
11060 |
|
|
* in need of being re-started, so send it on through to aic7xxx_queue
|
11061 |
|
|
* and let it set until the delay is over. This keeps it from dying
|
11062 |
|
|
* entirely and avoids getting a bogus dead command back through the
|
11063 |
|
|
* mid-level code due to too many retries.
|
11064 |
|
|
*/
|
11065 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,132)
|
11066 |
|
|
if ( flags & SCSI_RESET_SYNCHRONOUS )
|
11067 |
|
|
{
|
11068 |
|
|
cmd->result = DID_BUS_BUSY << 16;
|
11069 |
|
|
cmd->done(cmd);
|
11070 |
|
|
}
|
11071 |
|
|
#endif
|
11072 |
|
|
p->flags &= ~AHC_IN_RESET;
|
11073 |
|
|
/*
|
11074 |
|
|
* We can't rely on run_waiting_queues to unpause the sequencer for
|
11075 |
|
|
* PCI based controllers since we use AAP. NOTE: this also sets
|
11076 |
|
|
* the timer for the one command we might have queued in the case
|
11077 |
|
|
* of a synch reset.
|
11078 |
|
|
*/
|
11079 |
|
|
aic7xxx_run_waiting_queues(p);
|
11080 |
|
|
unpause_sequencer(p, FALSE);
|
11081 |
|
|
DRIVER_UNLOCK
|
11082 |
|
|
return(result);
|
11083 |
|
|
break;
|
11084 |
|
|
}
|
11085 |
|
|
}
|
11086 |
|
|
|
11087 |
|
|
/*+F*************************************************************************
|
11088 |
|
|
* Function:
|
11089 |
|
|
* aic7xxx_biosparam
|
11090 |
|
|
*
|
11091 |
|
|
* Description:
|
11092 |
|
|
* Return the disk geometry for the given SCSI device.
|
11093 |
|
|
*-F*************************************************************************/
|
11094 |
|
|
int
|
11095 |
|
|
aic7xxx_biosparam(Disk *disk, kdev_t dev, int geom[])
|
11096 |
|
|
{
|
11097 |
|
|
int heads, sectors, cylinders, ret;
|
11098 |
|
|
struct aic7xxx_host *p;
|
11099 |
|
|
struct buffer_head *bh;
|
11100 |
|
|
|
11101 |
|
|
p = (struct aic7xxx_host *) disk->device->host->hostdata;
|
11102 |
|
|
bh = bread(MKDEV(MAJOR(dev), MINOR(dev)&~0xf), 0, 1024);
|
11103 |
|
|
|
11104 |
|
|
if ( bh )
|
11105 |
|
|
{
|
11106 |
|
|
ret = scsi_partsize(bh, disk->capacity, &geom[2], &geom[0], &geom[1]);
|
11107 |
|
|
brelse(bh);
|
11108 |
|
|
if ( ret != -1 )
|
11109 |
|
|
return(ret);
|
11110 |
|
|
}
|
11111 |
|
|
|
11112 |
|
|
heads = 64;
|
11113 |
|
|
sectors = 32;
|
11114 |
|
|
cylinders = disk->capacity / (heads * sectors);
|
11115 |
|
|
|
11116 |
|
|
if ((p->flags & AHC_EXTEND_TRANS_A) && (cylinders > 1024))
|
11117 |
|
|
{
|
11118 |
|
|
heads = 255;
|
11119 |
|
|
sectors = 63;
|
11120 |
|
|
cylinders = disk->capacity / (heads * sectors);
|
11121 |
|
|
}
|
11122 |
|
|
|
11123 |
|
|
geom[0] = heads;
|
11124 |
|
|
geom[1] = sectors;
|
11125 |
|
|
geom[2] = cylinders;
|
11126 |
|
|
|
11127 |
|
|
return (0);
|
11128 |
|
|
}
|
11129 |
|
|
|
11130 |
|
|
/*+F*************************************************************************
|
11131 |
|
|
* Function:
|
11132 |
|
|
* aic7xxx_release
|
11133 |
|
|
*
|
11134 |
|
|
* Description:
|
11135 |
|
|
* Free the passed in Scsi_Host memory structures prior to unloading the
|
11136 |
|
|
* module.
|
11137 |
|
|
*-F*************************************************************************/
|
11138 |
|
|
int
|
11139 |
|
|
aic7xxx_release(struct Scsi_Host *host)
|
11140 |
|
|
{
|
11141 |
|
|
struct aic7xxx_host *p = (struct aic7xxx_host *) host->hostdata;
|
11142 |
|
|
struct aic7xxx_host *next, *prev;
|
11143 |
|
|
|
11144 |
|
|
if(p->irq)
|
11145 |
|
|
free_irq(p->irq, p);
|
11146 |
|
|
release_region(p->base, MAXREG - MINREG);
|
11147 |
|
|
#ifdef MMAPIO
|
11148 |
|
|
if(p->maddr)
|
11149 |
|
|
{
|
11150 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
|
11151 |
|
|
vfree((void *) (((unsigned long) p->maddr) & PAGE_MASK));
|
11152 |
|
|
#else
|
11153 |
|
|
iounmap((void *) (((unsigned long) p->maddr) & PAGE_MASK));
|
11154 |
|
|
#endif
|
11155 |
|
|
}
|
11156 |
|
|
#endif /* MMAPIO */
|
11157 |
|
|
prev = NULL;
|
11158 |
|
|
next = first_aic7xxx;
|
11159 |
|
|
while(next != NULL)
|
11160 |
|
|
{
|
11161 |
|
|
if(next == p)
|
11162 |
|
|
{
|
11163 |
|
|
if(prev == NULL)
|
11164 |
|
|
first_aic7xxx = next->next;
|
11165 |
|
|
else
|
11166 |
|
|
prev->next = next->next;
|
11167 |
|
|
}
|
11168 |
|
|
else
|
11169 |
|
|
{
|
11170 |
|
|
prev = next;
|
11171 |
|
|
}
|
11172 |
|
|
next = next->next;
|
11173 |
|
|
}
|
11174 |
|
|
aic7xxx_free(p);
|
11175 |
|
|
return(0);
|
11176 |
|
|
}
|
11177 |
|
|
|
11178 |
|
|
/*+F*************************************************************************
|
11179 |
|
|
* Function:
|
11180 |
|
|
* aic7xxx_print_card
|
11181 |
|
|
*
|
11182 |
|
|
* Description:
|
11183 |
|
|
* Print out all of the control registers on the card
|
11184 |
|
|
*
|
11185 |
|
|
* NOTE: This function is not yet safe for use on the VLB and EISA
|
11186 |
|
|
* controllers, so it isn't used on those controllers at all.
|
11187 |
|
|
*-F*************************************************************************/
|
11188 |
|
|
static void
|
11189 |
|
|
aic7xxx_print_card(struct aic7xxx_host *p)
|
11190 |
|
|
{
|
11191 |
|
|
int i, j, k, chip;
|
11192 |
|
|
static struct register_ranges {
|
11193 |
|
|
int num_ranges;
|
11194 |
|
|
int range_val[32];
|
11195 |
|
|
} cards_ds[] = {
|
11196 |
|
|
{ 0, {0,} }, /* none */
|
11197 |
|
|
{10, {0x00, 0x05, 0x08, 0x11, 0x18, 0x19, 0x1f, 0x1f, 0x60, 0x60, /*7771*/
|
11198 |
|
|
0x62, 0x66, 0x80, 0x8e, 0x90, 0x95, 0x97, 0x97, 0x9b, 0x9f} },
|
11199 |
|
|
{ 9, {0x00, 0x05, 0x08, 0x11, 0x18, 0x1f, 0x60, 0x60, 0x62, 0x66, /*7850*/
|
11200 |
|
|
0x80, 0x8e, 0x90, 0x95, 0x97, 0x97, 0x9a, 0x9f} },
|
11201 |
|
|
{ 9, {0x00, 0x05, 0x08, 0x11, 0x18, 0x1f, 0x60, 0x60, 0x62, 0x66, /*7860*/
|
11202 |
|
|
0x80, 0x8e, 0x90, 0x95, 0x97, 0x97, 0x9a, 0x9f} },
|
11203 |
|
|
{10, {0x00, 0x05, 0x08, 0x11, 0x18, 0x19, 0x1c, 0x1f, 0x60, 0x60, /*7870*/
|
11204 |
|
|
0x62, 0x66, 0x80, 0x8e, 0x90, 0x95, 0x97, 0x97, 0x9a, 0x9f} },
|
11205 |
|
|
{10, {0x00, 0x05, 0x08, 0x11, 0x18, 0x1a, 0x1c, 0x1f, 0x60, 0x60, /*7880*/
|
11206 |
|
|
0x62, 0x66, 0x80, 0x8e, 0x90, 0x95, 0x97, 0x97, 0x9a, 0x9f} },
|
11207 |
|
|
{16, {0x00, 0x05, 0x08, 0x11, 0x18, 0x1f, 0x60, 0x60, 0x62, 0x66, /*7890*/
|
11208 |
|
|
0x84, 0x8e, 0x90, 0x95, 0x97, 0x97, 0x9a, 0x9a, 0x9f, 0x9f,
|
11209 |
|
|
0xe0, 0xf1, 0xf4, 0xf4, 0xf6, 0xf6, 0xf8, 0xf8, 0xfa, 0xfc,
|
11210 |
|
|
0xfe, 0xff} },
|
11211 |
|
|
{12, {0x00, 0x05, 0x08, 0x11, 0x18, 0x19, 0x1b, 0x1f, 0x60, 0x60, /*7895*/
|
11212 |
|
|
0x62, 0x66, 0x80, 0x8e, 0x90, 0x95, 0x97, 0x97, 0x9a, 0x9a,
|
11213 |
|
|
0x9f, 0x9f, 0xe0, 0xf1} },
|
11214 |
|
|
{16, {0x00, 0x05, 0x08, 0x11, 0x18, 0x1f, 0x60, 0x60, 0x62, 0x66, /*7896*/
|
11215 |
|
|
0x84, 0x8e, 0x90, 0x95, 0x97, 0x97, 0x9a, 0x9a, 0x9f, 0x9f,
|
11216 |
|
|
0xe0, 0xf1, 0xf4, 0xf4, 0xf6, 0xf6, 0xf8, 0xf8, 0xfa, 0xfc,
|
11217 |
|
|
0xfe, 0xff} },
|
11218 |
|
|
};
|
11219 |
|
|
#ifdef CONFIG_PCI
|
11220 |
|
|
static struct register_ranges cards_ns[] = {
|
11221 |
|
|
{ 0, {0,} }, /* none */
|
11222 |
|
|
{ 0, {0,} }, /* 7771 */
|
11223 |
|
|
{ 7, {0x04, 0x08, 0x0c, 0x0e, 0x10, 0x17, 0x28, 0x2b, 0x30, 0x33,
|
11224 |
|
|
0x3c, 0x41, 0x43, 0x47} },
|
11225 |
|
|
{ 7, {0x04, 0x08, 0x0c, 0x0e, 0x10, 0x17, 0x28, 0x2b, 0x30, 0x33,
|
11226 |
|
|
0x3c, 0x41, 0x43, 0x47} },
|
11227 |
|
|
{ 5, {0x04, 0x08, 0x0c, 0x0e, 0x10, 0x17, 0x30, 0x33, 0x3c, 0x41} },
|
11228 |
|
|
{ 5, {0x04, 0x08, 0x0c, 0x0e, 0x10, 0x17, 0x30, 0x34, 0x3c, 0x47} },
|
11229 |
|
|
{ 5, {0x04, 0x08, 0x0c, 0x1b, 0x30, 0x34, 0x3c, 0x43, 0xdc, 0xe3} },
|
11230 |
|
|
{ 6, {0x04, 0x08, 0x0c, 0x0e, 0x10, 0x17, 0x30, 0x34, 0x3c, 0x47,
|
11231 |
|
|
0xdc, 0xe3} },
|
11232 |
|
|
{ 6, {0x04, 0x08, 0x0c, 0x1b, 0x30, 0x34, 0x3c, 0x43, 0xdc, 0xe3,
|
11233 |
|
|
0xff, 0xff} }
|
11234 |
|
|
};
|
11235 |
|
|
#endif
|
11236 |
|
|
chip = p->chip & AHC_CHIPID_MASK;
|
11237 |
|
|
/*
|
11238 |
|
|
* Let's run through the PCI space first....
|
11239 |
|
|
*/
|
11240 |
|
|
printk("%s at ",
|
11241 |
|
|
board_names[p->board_name_index]);
|
11242 |
|
|
switch(p->chip & ~AHC_CHIPID_MASK)
|
11243 |
|
|
{
|
11244 |
|
|
case AHC_VL:
|
11245 |
|
|
printk("VLB Slot %d.\n", p->pci_device_fn);
|
11246 |
|
|
break;
|
11247 |
|
|
case AHC_EISA:
|
11248 |
|
|
printk("EISA Slot %d.\n", p->pci_device_fn);
|
11249 |
|
|
break;
|
11250 |
|
|
case AHC_PCI:
|
11251 |
|
|
default:
|
11252 |
|
|
printk("PCI %d/%d.\n", PCI_SLOT(p->pci_device_fn),
|
11253 |
|
|
PCI_FUNC(p->pci_device_fn));
|
11254 |
|
|
break;
|
11255 |
|
|
}
|
11256 |
|
|
|
11257 |
|
|
#ifdef CONFIG_PCI
|
11258 |
|
|
{
|
11259 |
|
|
unsigned char temp;
|
11260 |
|
|
|
11261 |
|
|
printk("PCI Dump:\n");
|
11262 |
|
|
k=0;
|
11263 |
|
|
for(i=0; i<cards_ns[chip].num_ranges; i++)
|
11264 |
|
|
{
|
11265 |
|
|
for(j = cards_ns[chip].range_val[ i * 2 ];
|
11266 |
|
|
j <= cards_ns[chip].range_val[ i * 2 + 1 ] ;
|
11267 |
|
|
j++)
|
11268 |
|
|
{
|
11269 |
|
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
|
11270 |
|
|
pci_read_config_byte(p->pdev, j, &temp);
|
11271 |
|
|
#else
|
11272 |
|
|
pcibios_read_config_byte(p->pci_bus, p->pci_device_fn, j, &temp);
|
11273 |
|
|
#endif
|
11274 |
|
|
printk("%02x:%02x ", j, temp);
|
11275 |
|
|
if(++k == 13)
|
11276 |
|
|
{
|
11277 |
|
|
printk("\n");
|
11278 |
|
|
k = 0;
|
11279 |
|
|
}
|
11280 |
|
|
}
|
11281 |
|
|
}
|
11282 |
|
|
}
|
11283 |
|
|
if(k != 0)
|
11284 |
|
|
printk("\n");
|
11285 |
|
|
#endif /* CONFIG_PCI */
|
11286 |
|
|
|
11287 |
|
|
/*
|
11288 |
|
|
* Now the registers on the card....
|
11289 |
|
|
*/
|
11290 |
|
|
printk("Card Dump:\n");
|
11291 |
|
|
k = 0;
|
11292 |
|
|
for(i=0; i<cards_ds[chip].num_ranges; i++)
|
11293 |
|
|
{
|
11294 |
|
|
for(j = cards_ds[chip].range_val[ i * 2 ];
|
11295 |
|
|
j <= cards_ds[chip].range_val[ i * 2 + 1 ] ;
|
11296 |
|
|
j++)
|
11297 |
|
|
{
|
11298 |
|
|
printk("%02x:%02x ", j, aic_inb(p, j));
|
11299 |
|
|
if(++k == 13)
|
11300 |
|
|
{
|
11301 |
|
|
printk("\n");
|
11302 |
|
|
k=0;
|
11303 |
|
|
}
|
11304 |
|
|
}
|
11305 |
|
|
}
|
11306 |
|
|
if(k != 0)
|
11307 |
|
|
printk("\n");
|
11308 |
|
|
if (p->flags & AHC_SEEPROM_FOUND)
|
11309 |
|
|
{
|
11310 |
|
|
unsigned short *sc1;
|
11311 |
|
|
sc1 = (unsigned short *)&p->sc;
|
11312 |
|
|
|
11313 |
|
|
printk("SEEPROM dump.\n");
|
11314 |
|
|
for(i=1; i<=32; i++)
|
11315 |
|
|
{
|
11316 |
|
|
printk("0x%04x", sc1[i-1]);
|
11317 |
|
|
if ( (i % 8) == 0 )
|
11318 |
|
|
printk("\n");
|
11319 |
|
|
else
|
11320 |
|
|
printk(" ");
|
11321 |
|
|
}
|
11322 |
|
|
}
|
11323 |
|
|
|
11324 |
|
|
/*
|
11325 |
|
|
* If this was an Ultra2 controller, then we just hosed the card in terms
|
11326 |
|
|
* of the QUEUE REGS. This function is only called at init time or by
|
11327 |
|
|
* the panic_abort function, so it's safe to assume a generic init time
|
11328 |
|
|
* setting here
|
11329 |
|
|
*/
|
11330 |
|
|
|
11331 |
|
|
if(p->features & AHC_QUEUE_REGS)
|
11332 |
|
|
{
|
11333 |
|
|
aic_outb(p, 0, SDSCB_QOFF);
|
11334 |
|
|
aic_outb(p, 0, SNSCB_QOFF);
|
11335 |
|
|
aic_outb(p, 0, HNSCB_QOFF);
|
11336 |
|
|
}
|
11337 |
|
|
|
11338 |
|
|
}
|
11339 |
|
|
|
11340 |
|
|
/*+F*************************************************************************
|
11341 |
|
|
* Function:
|
11342 |
|
|
* aic7xxx_print_scratch_ram
|
11343 |
|
|
*
|
11344 |
|
|
* Description:
|
11345 |
|
|
* Print out the scratch RAM values on the card.
|
11346 |
|
|
*-F*************************************************************************/
|
11347 |
|
|
static void
|
11348 |
|
|
aic7xxx_print_scratch_ram(struct aic7xxx_host *p)
|
11349 |
|
|
{
|
11350 |
|
|
int i, k;
|
11351 |
|
|
|
11352 |
|
|
k = 0;
|
11353 |
|
|
printk("Scratch RAM:\n");
|
11354 |
|
|
for(i = SRAM_BASE; i < SEQCTL; i++)
|
11355 |
|
|
{
|
11356 |
|
|
printk("%02x:%02x ", i, aic_inb(p, i));
|
11357 |
|
|
if(++k == 13)
|
11358 |
|
|
{
|
11359 |
|
|
printk("\n");
|
11360 |
|
|
k=0;
|
11361 |
|
|
}
|
11362 |
|
|
}
|
11363 |
|
|
if (p->features & AHC_MORE_SRAM)
|
11364 |
|
|
{
|
11365 |
|
|
for(i = TARG_OFFSET; i < 0x80; i++)
|
11366 |
|
|
{
|
11367 |
|
|
printk("%02x:%02x ", i, aic_inb(p, i));
|
11368 |
|
|
if(++k == 13)
|
11369 |
|
|
{
|
11370 |
|
|
printk("\n");
|
11371 |
|
|
k=0;
|
11372 |
|
|
}
|
11373 |
|
|
}
|
11374 |
|
|
}
|
11375 |
|
|
printk("\n");
|
11376 |
|
|
}
|
11377 |
|
|
|
11378 |
|
|
|
11379 |
|
|
#include "aic7xxx_proc.c"
|
11380 |
|
|
|
11381 |
|
|
#ifdef MODULE
|
11382 |
|
|
/* Eventually this will go into an include file, but this will be later */
|
11383 |
|
|
Scsi_Host_Template driver_template = AIC7XXX;
|
11384 |
|
|
|
11385 |
|
|
#include "scsi_module.c"
|
11386 |
|
|
#endif
|
11387 |
|
|
|
11388 |
|
|
/*
|
11389 |
|
|
* Overrides for Emacs so that we almost follow Linus's tabbing style.
|
11390 |
|
|
* Emacs will notice this stuff at the end of the file and automatically
|
11391 |
|
|
* adjust the settings for this buffer only. This must remain at the end
|
11392 |
|
|
* of the file.
|
11393 |
|
|
* ---------------------------------------------------------------------------
|
11394 |
|
|
* Local variables:
|
11395 |
|
|
* c-indent-level: 2
|
11396 |
|
|
* c-brace-imaginary-offset: 0
|
11397 |
|
|
* c-brace-offset: -2
|
11398 |
|
|
* c-argdecl-indent: 2
|
11399 |
|
|
* c-label-offset: -2
|
11400 |
|
|
* c-continued-statement-offset: 2
|
11401 |
|
|
* c-continued-brace-offset: 0
|
11402 |
|
|
* indent-tabs-mode: nil
|
11403 |
|
|
* tab-width: 8
|
11404 |
|
|
* End:
|
11405 |
|
|
*/
|