diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/scsi/advansys.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/scsi/advansys.c')
-rw-r--r-- | drivers/scsi/advansys.c | 18237 |
1 files changed, 18237 insertions, 0 deletions
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c new file mode 100644 index 000000000000..9962c51dc2a7 --- /dev/null +++ b/drivers/scsi/advansys.c | |||
@@ -0,0 +1,18237 @@ | |||
1 | #define ASC_VERSION "3.3K" /* AdvanSys Driver Version */ | ||
2 | |||
3 | /* | ||
4 | * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters | ||
5 | * | ||
6 | * Copyright (c) 1995-2000 Advanced System Products, Inc. | ||
7 | * Copyright (c) 2000-2001 ConnectCom Solutions, Inc. | ||
8 | * All Rights Reserved. | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that redistributions of source | ||
12 | * code retain the above copyright notice and this comment without | ||
13 | * modification. | ||
14 | * | ||
15 | * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys) | ||
16 | * changed its name to ConnectCom Solutions, Inc. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | /* | ||
21 | |||
22 | Documentation for the AdvanSys Driver | ||
23 | |||
24 | A. Linux Kernels Supported by this Driver | ||
25 | B. Adapters Supported by this Driver | ||
26 | C. Linux source files modified by AdvanSys Driver | ||
27 | D. Source Comments | ||
28 | E. Driver Compile Time Options and Debugging | ||
29 | F. Driver LILO Option | ||
30 | G. Tests to run before releasing new driver | ||
31 | H. Release History | ||
32 | I. Known Problems/Fix List | ||
33 | J. Credits (Chronological Order) | ||
34 | |||
35 | A. Linux Kernels Supported by this Driver | ||
36 | |||
37 | This driver has been tested in the following Linux kernels: v2.2.18 | ||
38 | v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86, | ||
39 | alpha, and PowerPC platforms. | ||
40 | |||
41 | B. Adapters Supported by this Driver | ||
42 | |||
43 | AdvanSys (Advanced System Products, Inc.) manufactures the following | ||
44 | RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow | ||
45 | (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI | ||
46 | buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit | ||
47 | transfer) SCSI Host Adapters for the PCI bus. | ||
48 | |||
49 | The CDB counts below indicate the number of SCSI CDB (Command | ||
50 | Descriptor Block) requests that can be stored in the RISC chip | ||
51 | cache and board LRAM. A CDB is a single SCSI command. The driver | ||
52 | detect routine will display the number of CDBs available for each | ||
53 | adapter detected. The number of CDBs used by the driver can be | ||
54 | lowered in the BIOS by changing the 'Host Queue Size' adapter setting. | ||
55 | |||
56 | Laptop Products: | ||
57 | ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater) | ||
58 | |||
59 | Connectivity Products: | ||
60 | ABP510/5150 - Bus-Master ISA (240 CDB) | ||
61 | ABP5140 - Bus-Master ISA PnP (16 CDB) | ||
62 | ABP5142 - Bus-Master ISA PnP with floppy (16 CDB) | ||
63 | ABP902/3902 - Bus-Master PCI (16 CDB) | ||
64 | ABP3905 - Bus-Master PCI (16 CDB) | ||
65 | ABP915 - Bus-Master PCI (16 CDB) | ||
66 | ABP920 - Bus-Master PCI (16 CDB) | ||
67 | ABP3922 - Bus-Master PCI (16 CDB) | ||
68 | ABP3925 - Bus-Master PCI (16 CDB) | ||
69 | ABP930 - Bus-Master PCI (16 CDB) | ||
70 | ABP930U - Bus-Master PCI Ultra (16 CDB) | ||
71 | ABP930UA - Bus-Master PCI Ultra (16 CDB) | ||
72 | ABP960 - Bus-Master PCI MAC/PC (16 CDB) | ||
73 | ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB) | ||
74 | |||
75 | Single Channel Products: | ||
76 | ABP542 - Bus-Master ISA with floppy (240 CDB) | ||
77 | ABP742 - Bus-Master EISA (240 CDB) | ||
78 | ABP842 - Bus-Master VL (240 CDB) | ||
79 | ABP940 - Bus-Master PCI (240 CDB) | ||
80 | ABP940U - Bus-Master PCI Ultra (240 CDB) | ||
81 | ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB) | ||
82 | ABP970 - Bus-Master PCI MAC/PC (240 CDB) | ||
83 | ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB) | ||
84 | ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB) | ||
85 | ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB) | ||
86 | ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB) | ||
87 | ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB) | ||
88 | |||
89 | Multi-Channel Products: | ||
90 | ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel) | ||
91 | ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel) | ||
92 | ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel) | ||
93 | ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel) | ||
94 | ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel) | ||
95 | ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel) | ||
96 | ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.) | ||
97 | ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB) | ||
98 | ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB) | ||
99 | |||
100 | C. Linux source files modified by AdvanSys Driver | ||
101 | |||
102 | This section for historical purposes documents the changes | ||
103 | originally made to the Linux kernel source to add the advansys | ||
104 | driver. As Linux has changed some of these files have also | ||
105 | been modified. | ||
106 | |||
107 | 1. linux/arch/i386/config.in: | ||
108 | |||
109 | bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y | ||
110 | |||
111 | 2. linux/drivers/scsi/hosts.c: | ||
112 | |||
113 | #ifdef CONFIG_SCSI_ADVANSYS | ||
114 | #include "advansys.h" | ||
115 | #endif | ||
116 | |||
117 | and after "static Scsi_Host_Template builtin_scsi_hosts[] =": | ||
118 | |||
119 | #ifdef CONFIG_SCSI_ADVANSYS | ||
120 | ADVANSYS, | ||
121 | #endif | ||
122 | |||
123 | 3. linux/drivers/scsi/Makefile: | ||
124 | |||
125 | ifdef CONFIG_SCSI_ADVANSYS | ||
126 | SCSI_SRCS := $(SCSI_SRCS) advansys.c | ||
127 | SCSI_OBJS := $(SCSI_OBJS) advansys.o | ||
128 | else | ||
129 | SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o | ||
130 | endif | ||
131 | |||
132 | 4. linux/init/main.c: | ||
133 | |||
134 | extern void advansys_setup(char *str, int *ints); | ||
135 | |||
136 | and add the following lines to the bootsetups[] array. | ||
137 | |||
138 | #ifdef CONFIG_SCSI_ADVANSYS | ||
139 | { "advansys=", advansys_setup }, | ||
140 | #endif | ||
141 | |||
142 | D. Source Comments | ||
143 | |||
144 | 1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'. | ||
145 | |||
146 | 2. This driver should be maintained in multiple files. But to make | ||
147 | it easier to include with Linux and to follow Linux conventions, | ||
148 | the whole driver is maintained in the source files advansys.h and | ||
149 | advansys.c. In this file logical sections of the driver begin with | ||
150 | a comment that contains '---'. The following are the logical sections | ||
151 | of the driver below. | ||
152 | |||
153 | --- Linux Version | ||
154 | --- Linux Include File | ||
155 | --- Driver Options | ||
156 | --- Debugging Header | ||
157 | --- Asc Library Constants and Macros | ||
158 | --- Adv Library Constants and Macros | ||
159 | --- Driver Constants and Macros | ||
160 | --- Driver Structures | ||
161 | --- Driver Data | ||
162 | --- Driver Function Prototypes | ||
163 | --- Linux 'Scsi_Host_Template' and advansys_setup() Functions | ||
164 | --- Loadable Driver Support | ||
165 | --- Miscellaneous Driver Functions | ||
166 | --- Functions Required by the Asc Library | ||
167 | --- Functions Required by the Adv Library | ||
168 | --- Tracing and Debugging Functions | ||
169 | --- Asc Library Functions | ||
170 | --- Adv Library Functions | ||
171 | |||
172 | 3. The string 'XXX' is used to flag code that needs to be re-written | ||
173 | or that contains a problem that needs to be addressed. | ||
174 | |||
175 | 4. I have stripped comments from and reformatted the source for the | ||
176 | Asc Library and Adv Library to reduce the size of this file. This | ||
177 | source can be found under the following headings. The Asc Library | ||
178 | is used to support Narrow Boards. The Adv Library is used to | ||
179 | support Wide Boards. | ||
180 | |||
181 | --- Asc Library Constants and Macros | ||
182 | --- Adv Library Constants and Macros | ||
183 | --- Asc Library Functions | ||
184 | --- Adv Library Functions | ||
185 | |||
186 | E. Driver Compile Time Options and Debugging | ||
187 | |||
188 | In this source file the following constants can be defined. They are | ||
189 | defined in the source below. Both of these options are enabled by | ||
190 | default. | ||
191 | |||
192 | 1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled) | ||
193 | |||
194 | Enabling this option adds assertion logic statements to the | ||
195 | driver. If an assertion fails a message will be displayed to | ||
196 | the console, but the system will continue to operate. Any | ||
197 | assertions encountered should be reported to the person | ||
198 | responsible for the driver. Assertion statements may proactively | ||
199 | detect problems with the driver and facilitate fixing these | ||
200 | problems. Enabling assertions will add a small overhead to the | ||
201 | execution of the driver. | ||
202 | |||
203 | 2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled) | ||
204 | |||
205 | Enabling this option adds tracing functions to the driver and | ||
206 | the ability to set a driver tracing level at boot time. This | ||
207 | option will also export symbols not required outside the driver to | ||
208 | the kernel name space. This option is very useful for debugging | ||
209 | the driver, but it will add to the size of the driver execution | ||
210 | image and add overhead to the execution of the driver. | ||
211 | |||
212 | The amount of debugging output can be controlled with the global | ||
213 | variable 'asc_dbglvl'. The higher the number the more output. By | ||
214 | default the debug level is 0. | ||
215 | |||
216 | If the driver is loaded at boot time and the LILO Driver Option | ||
217 | is included in the system, the debug level can be changed by | ||
218 | specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The | ||
219 | first three hex digits of the pseudo I/O Port must be set to | ||
220 | 'deb' and the fourth hex digit specifies the debug level: 0 - F. | ||
221 | The following command line will look for an adapter at 0x330 | ||
222 | and set the debug level to 2. | ||
223 | |||
224 | linux advansys=0x330,0,0,0,0xdeb2 | ||
225 | |||
226 | If the driver is built as a loadable module this variable can be | ||
227 | defined when the driver is loaded. The following insmod command | ||
228 | will set the debug level to one. | ||
229 | |||
230 | insmod advansys.o asc_dbglvl=1 | ||
231 | |||
232 | Debugging Message Levels: | ||
233 | 0: Errors Only | ||
234 | 1: High-Level Tracing | ||
235 | 2-N: Verbose Tracing | ||
236 | |||
237 | To enable debug output to console, please make sure that: | ||
238 | |||
239 | a. System and kernel logging is enabled (syslogd, klogd running). | ||
240 | b. Kernel messages are routed to console output. Check | ||
241 | /etc/syslog.conf for an entry similar to this: | ||
242 | |||
243 | kern.* /dev/console | ||
244 | |||
245 | c. klogd is started with the appropriate -c parameter | ||
246 | (e.g. klogd -c 8) | ||
247 | |||
248 | This will cause printk() messages to be be displayed on the | ||
249 | current console. Refer to the klogd(8) and syslogd(8) man pages | ||
250 | for details. | ||
251 | |||
252 | Alternatively you can enable printk() to console with this | ||
253 | program. However, this is not the 'official' way to do this. | ||
254 | Debug output is logged in /var/log/messages. | ||
255 | |||
256 | main() | ||
257 | { | ||
258 | syscall(103, 7, 0, 0); | ||
259 | } | ||
260 | |||
261 | Increasing LOG_BUF_LEN in kernel/printk.c to something like | ||
262 | 40960 allows more debug messages to be buffered in the kernel | ||
263 | and written to the console or log file. | ||
264 | |||
265 | 3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0) | ||
266 | |||
267 | Enabling this option adds statistics collection and display | ||
268 | through /proc to the driver. The information is useful for | ||
269 | monitoring driver and device performance. It will add to the | ||
270 | size of the driver execution image and add minor overhead to | ||
271 | the execution of the driver. | ||
272 | |||
273 | Statistics are maintained on a per adapter basis. Driver entry | ||
274 | point call counts and transfer size counts are maintained. | ||
275 | Statistics are only available for kernels greater than or equal | ||
276 | to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured. | ||
277 | |||
278 | AdvanSys SCSI adapter files have the following path name format: | ||
279 | |||
280 | /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)] | ||
281 | |||
282 | This information can be displayed with cat. For example: | ||
283 | |||
284 | cat /proc/scsi/advansys/0 | ||
285 | |||
286 | When ADVANSYS_STATS is not defined the AdvanSys /proc files only | ||
287 | contain adapter and device configuration information. | ||
288 | |||
289 | F. Driver LILO Option | ||
290 | |||
291 | If init/main.c is modified as described in the 'Directions for Adding | ||
292 | the AdvanSys Driver to Linux' section (B.4.) above, the driver will | ||
293 | recognize the 'advansys' LILO command line and /etc/lilo.conf option. | ||
294 | This option can be used to either disable I/O port scanning or to limit | ||
295 | scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and | ||
296 | PCI boards will still be searched for and detected. This option only | ||
297 | affects searching for ISA and VL boards. | ||
298 | |||
299 | Examples: | ||
300 | 1. Eliminate I/O port scanning: | ||
301 | boot: linux advansys= | ||
302 | or | ||
303 | boot: linux advansys=0x0 | ||
304 | 2. Limit I/O port scanning to one I/O port: | ||
305 | boot: linux advansys=0x110 | ||
306 | 3. Limit I/O port scanning to four I/O ports: | ||
307 | boot: linux advansys=0x110,0x210,0x230,0x330 | ||
308 | |||
309 | For a loadable module the same effect can be achieved by setting | ||
310 | the 'asc_iopflag' variable and 'asc_ioport' array when loading | ||
311 | the driver, e.g. | ||
312 | |||
313 | insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330 | ||
314 | |||
315 | If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1) | ||
316 | I/O Port may be added to specify the driver debug level. Refer to | ||
317 | the 'Driver Compile Time Options and Debugging' section above for | ||
318 | more information. | ||
319 | |||
320 | G. Tests to run before releasing new driver | ||
321 | |||
322 | 1. In the supported kernels verify there are no warning or compile | ||
323 | errors when the kernel is built as both a driver and as a module | ||
324 | and with the following options: | ||
325 | |||
326 | ADVANSYS_DEBUG - enabled and disabled | ||
327 | CONFIG_SMP - enabled and disabled | ||
328 | CONFIG_PROC_FS - enabled and disabled | ||
329 | |||
330 | 2. Run tests on an x86, alpha, and PowerPC with at least one narrow | ||
331 | card and one wide card attached to a hard disk and CD-ROM drive: | ||
332 | fdisk, mkfs, fsck, bonnie, copy/compare test from the | ||
333 | CD-ROM to the hard drive. | ||
334 | |||
335 | H. Release History | ||
336 | |||
337 | BETA-1.0 (12/23/95): | ||
338 | First Release | ||
339 | |||
340 | BETA-1.1 (12/28/95): | ||
341 | 1. Prevent advansys_detect() from being called twice. | ||
342 | 2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'. | ||
343 | |||
344 | 1.2 (1/12/96): | ||
345 | 1. Prevent re-entrancy in the interrupt handler which | ||
346 | resulted in the driver hanging Linux. | ||
347 | 2. Fix problem that prevented ABP-940 cards from being | ||
348 | recognized on some PCI motherboards. | ||
349 | 3. Add support for the ABP-5140 PnP ISA card. | ||
350 | 4. Fix check condition return status. | ||
351 | 5. Add conditionally compiled code for Linux v1.3.X. | ||
352 | |||
353 | 1.3 (2/23/96): | ||
354 | 1. Fix problem in advansys_biosparam() that resulted in the | ||
355 | wrong drive geometry being returned for drives > 1GB with | ||
356 | extended translation enabled. | ||
357 | 2. Add additional tracing during device initialization. | ||
358 | 3. Change code that only applies to ISA PnP adapter. | ||
359 | 4. Eliminate 'make dep' warning. | ||
360 | 5. Try to fix problem with handling resets by increasing their | ||
361 | timeout value. | ||
362 | |||
363 | 1.4 (5/8/96): | ||
364 | 1. Change definitions to eliminate conflicts with other subsystems. | ||
365 | 2. Add versioning code for the shared interrupt changes. | ||
366 | 3. Eliminate problem in asc_rmqueue() with iterating after removing | ||
367 | a request. | ||
368 | 4. Remove reset request loop problem from the "Known Problems or | ||
369 | Issues" section. This problem was isolated and fixed in the | ||
370 | mid-level SCSI driver. | ||
371 | |||
372 | 1.5 (8/8/96): | ||
373 | 1. Add support for ABP-940U (PCI Ultra) adapter. | ||
374 | 2. Add support for IRQ sharing by setting the SA_SHIRQ flag for | ||
375 | request_irq and supplying a dev_id pointer to both request_irq() | ||
376 | and free_irq(). | ||
377 | 3. In AscSearchIOPortAddr11() restore a call to check_region() which | ||
378 | should be used before I/O port probing. | ||
379 | 4. Fix bug in asc_prt_hex() which resulted in the displaying | ||
380 | the wrong data. | ||
381 | 5. Incorporate miscellaneous Asc Library bug fixes and new microcode. | ||
382 | 6. Change driver versioning to be specific to each Linux sub-level. | ||
383 | 7. Change statistics gathering to be per adapter instead of global | ||
384 | to the driver. | ||
385 | 8. Add more information and statistics to the adapter /proc file: | ||
386 | /proc/scsi/advansys[0...]. | ||
387 | 9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list. | ||
388 | This problem has been addressed with the SCSI mid-level changes | ||
389 | made in v1.3.89. The advansys_select_queue_depths() function | ||
390 | was added for the v1.3.89 changes. | ||
391 | |||
392 | 1.6 (9/10/96): | ||
393 | 1. Incorporate miscellaneous Asc Library bug fixes and new microcode. | ||
394 | |||
395 | 1.7 (9/25/96): | ||
396 | 1. Enable clustering and optimize the setting of the maximum number | ||
397 | of scatter gather elements for any particular board. Clustering | ||
398 | increases CPU utilization, but results in a relatively larger | ||
399 | increase in I/O throughput. | ||
400 | 2. Improve the performance of the request queuing functions by | ||
401 | adding a last pointer to the queue structure. | ||
402 | 3. Correct problems with reset and abort request handling that | ||
403 | could have hung or crashed Linux. | ||
404 | 4. Add more information to the adapter /proc file: | ||
405 | /proc/scsi/advansys[0...]. | ||
406 | 5. Remove the request timeout issue form the driver issues list. | ||
407 | 6. Miscellaneous documentation additions and changes. | ||
408 | |||
409 | 1.8 (10/4/96): | ||
410 | 1. Make changes to handle the new v2.1.0 kernel memory mapping | ||
411 | in which a kernel virtual address may not be equivalent to its | ||
412 | bus or DMA memory address. | ||
413 | 2. Change abort and reset request handling to make it yet even | ||
414 | more robust. | ||
415 | 3. Try to mitigate request starvation by sending ordered requests | ||
416 | to heavily loaded, tag queuing enabled devices. | ||
417 | 4. Maintain statistics on request response time. | ||
418 | 5. Add request response time statistics and other information to | ||
419 | the adapter /proc file: /proc/scsi/advansys[0...]. | ||
420 | |||
421 | 1.9 (10/21/96): | ||
422 | 1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to | ||
423 | make use of mid-level SCSI driver device queue depth flow | ||
424 | control mechanism. This will eliminate aborts caused by a | ||
425 | device being unable to keep up with requests and eliminate | ||
426 | repeat busy or QUEUE FULL status returned by a device. | ||
427 | 2. Incorporate miscellaneous Asc Library bug fixes. | ||
428 | 3. To allow the driver to work in kernels with broken module | ||
429 | support set 'cmd_per_lun' if the driver is compiled as a | ||
430 | module. This change affects kernels v1.3.89 to present. | ||
431 | 4. Remove PCI BIOS address from the driver banner. The PCI BIOS | ||
432 | is relocated by the motherboard BIOS and its new address can | ||
433 | not be determined by the driver. | ||
434 | 5. Add mid-level SCSI queue depth information to the adapter | ||
435 | /proc file: /proc/scsi/advansys[0...]. | ||
436 | |||
437 | 2.0 (11/14/96): | ||
438 | 1. Change allocation of global structures used for device | ||
439 | initialization to guarantee they are in DMA-able memory. | ||
440 | Previously when the driver was loaded as a module these | ||
441 | structures might not have been in DMA-able memory, causing | ||
442 | device initialization to fail. | ||
443 | |||
444 | 2.1 (12/30/96): | ||
445 | 1. In advansys_reset(), if the request is a synchronous reset | ||
446 | request, even if the request serial number has changed, then | ||
447 | complete the request. | ||
448 | 2. Add Asc Library bug fixes including new microcode. | ||
449 | 3. Clear inquiry buffer before using it. | ||
450 | 4. Correct ifdef typo. | ||
451 | |||
452 | 2.2 (1/15/97): | ||
453 | 1. Add Asc Library bug fixes including new microcode. | ||
454 | 2. Add synchronous data transfer rate information to the | ||
455 | adapter /proc file: /proc/scsi/advansys[0...]. | ||
456 | 3. Change ADVANSYS_DEBUG to be disabled by default. This | ||
457 | will reduce the size of the driver image, eliminate execution | ||
458 | overhead, and remove unneeded symbols from the kernel symbol | ||
459 | space that were previously added by the driver. | ||
460 | 4. Add new compile-time option ADVANSYS_ASSERT for assertion | ||
461 | code that used to be defined within ADVANSYS_DEBUG. This | ||
462 | option is enabled by default. | ||
463 | |||
464 | 2.8 (5/26/97): | ||
465 | 1. Change version number to 2.8 to synchronize the Linux driver | ||
466 | version numbering with other AdvanSys drivers. | ||
467 | 2. Reformat source files without tabs to present the same view | ||
468 | of the file to everyone regardless of the editor tab setting | ||
469 | being used. | ||
470 | 3. Add Asc Library bug fixes. | ||
471 | |||
472 | 3.1A (1/8/98): | ||
473 | 1. Change version number to 3.1 to indicate that support for | ||
474 | Ultra-Wide adapters (ABP-940UW) is included in this release. | ||
475 | 2. Add Asc Library (Narrow Board) bug fixes. | ||
476 | 3. Report an underrun condition with the host status byte set | ||
477 | to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which | ||
478 | causes the underrun condition to be ignored. When Linux defines | ||
479 | its own DID_UNDERRUN the constant defined in this file can be | ||
480 | removed. | ||
481 | 4. Add patch to AscWaitTixISRDone(). | ||
482 | 5. Add support for up to 16 different AdvanSys host adapter SCSI | ||
483 | channels in one system. This allows four cards with four channels | ||
484 | to be used in one system. | ||
485 | |||
486 | 3.1B (1/9/98): | ||
487 | 1. Handle that PCI register base addresses are not always page | ||
488 | aligned even though ioremap() requires that the address argument | ||
489 | be page aligned. | ||
490 | |||
491 | 3.1C (1/10/98): | ||
492 | 1. Update latest BIOS version checked for from the /proc file. | ||
493 | 2. Don't set microcode SDTR variable at initialization. Instead | ||
494 | wait until device capabilities have been detected from an Inquiry | ||
495 | command. | ||
496 | |||
497 | 3.1D (1/21/98): | ||
498 | 1. Improve performance when the driver is compiled as module by | ||
499 | allowing up to 64 scatter-gather elements instead of 8. | ||
500 | |||
501 | 3.1E (5/1/98): | ||
502 | 1. Set time delay in AscWaitTixISRDone() to 1000 ms. | ||
503 | 2. Include SMP locking changes. | ||
504 | 3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS | ||
505 | access functions. | ||
506 | 4. Update board serial number printing. | ||
507 | 5. Try allocating an IRQ both with and without the SA_INTERRUPT | ||
508 | flag set to allow IRQ sharing with drivers that do not set | ||
509 | the SA_INTERRUPT flag. Also display a more descriptive error | ||
510 | message if request_irq() fails. | ||
511 | 6. Update to latest Asc and Adv Libraries. | ||
512 | |||
513 | 3.2A (7/22/99): | ||
514 | 1. Update Adv Library to 4.16 which includes support for | ||
515 | the ASC38C0800 (Ultra2/LVD) IC. | ||
516 | |||
517 | 3.2B (8/23/99): | ||
518 | 1. Correct PCI compile time option for v2.1.93 and greater | ||
519 | kernels, advansys_info() string, and debug compile time | ||
520 | option. | ||
521 | 2. Correct DvcSleepMilliSecond() for v2.1.0 and greater | ||
522 | kernels. This caused an LVD detection/BIST problem problem | ||
523 | among other things. | ||
524 | 3. Sort PCI cards by PCI Bus, Slot, Function ascending order | ||
525 | to be consistent with the BIOS. | ||
526 | 4. Update to Asc Library S121 and Adv Library 5.2. | ||
527 | |||
528 | 3.2C (8/24/99): | ||
529 | 1. Correct PCI card detection bug introduced in 3.2B that | ||
530 | prevented PCI cards from being detected in kernels older | ||
531 | than v2.1.93. | ||
532 | |||
533 | 3.2D (8/26/99): | ||
534 | 1. Correct /proc device synchronous speed information display. | ||
535 | Also when re-negotiation is pending for a target device | ||
536 | note this condition with an * and footnote. | ||
537 | 2. Correct initialization problem with Ultra-Wide cards that | ||
538 | have a pre-3.2 BIOS. A microcode variable changed locations | ||
539 | in 3.2 and greater BIOSes which caused WDTR to be attempted | ||
540 | erroneously with drives that don't support WDTR. | ||
541 | |||
542 | 3.2E (8/30/99): | ||
543 | 1. Fix compile error caused by v2.3.13 PCI structure change. | ||
544 | 2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM | ||
545 | checksum error for ISA cards. | ||
546 | 3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level | ||
547 | SCSI changes that it depended on were never included in Linux. | ||
548 | |||
549 | 3.2F (9/3/99): | ||
550 | 1. Handle new initial function code added in v2.3.16 for all | ||
551 | driver versions. | ||
552 | |||
553 | 3.2G (9/8/99): | ||
554 | 1. Fix PCI board detection in v2.3.13 and greater kernels. | ||
555 | 2. Fix comiple errors in v2.3.X with debugging enabled. | ||
556 | |||
557 | 3.2H (9/13/99): | ||
558 | 1. Add 64-bit address, long support for Alpha and UltraSPARC. | ||
559 | The driver has been verified to work on an Alpha system. | ||
560 | 2. Add partial byte order handling support for Power PC and | ||
561 | other big-endian platforms. This support has not yet been | ||
562 | completed or verified. | ||
563 | 3. For wide boards replace block zeroing of request and | ||
564 | scatter-gather structures with individual field initialization | ||
565 | to improve performance. | ||
566 | 4. Correct and clarify ROM BIOS version detection. | ||
567 | |||
568 | 3.2I (10/8/99): | ||
569 | 1. Update to Adv Library 5.4. | ||
570 | 2. Add v2.3.19 underrun reporting to asc_isr_callback() and | ||
571 | adv_isr_callback(). Remove DID_UNDERRUN constant and other | ||
572 | no longer needed code that previously documented the lack | ||
573 | of underrun handling. | ||
574 | |||
575 | 3.2J (10/14/99): | ||
576 | 1. Eliminate compile errors for v2.0 and earlier kernels. | ||
577 | |||
578 | 3.2K (11/15/99): | ||
579 | 1. Correct debug compile error in asc_prt_adv_scsi_req_q(). | ||
580 | 2. Update Adv Library to 5.5. | ||
581 | 3. Add ifdef handling for /proc changes added in v2.3.28. | ||
582 | 4. Increase Wide board scatter-gather list maximum length to | ||
583 | 255 when the driver is compiled into the kernel. | ||
584 | |||
585 | 3.2L (11/18/99): | ||
586 | 1. Fix bug in adv_get_sglist() that caused an assertion failure | ||
587 | at line 7475. The reqp->sgblkp pointer must be initialized | ||
588 | to NULL in adv_get_sglist(). | ||
589 | |||
590 | 3.2M (11/29/99): | ||
591 | 1. Really fix bug in adv_get_sglist(). | ||
592 | 2. Incorporate v2.3.29 changes into driver. | ||
593 | |||
594 | 3.2N (4/1/00): | ||
595 | 1. Add CONFIG_ISA ifdef code. | ||
596 | 2. Include advansys_interrupts_enabled name change patch. | ||
597 | 3. For >= v2.3.28 use new SCSI error handling with new function | ||
598 | advansys_eh_bus_reset(). Don't include an abort function | ||
599 | because of base library limitations. | ||
600 | 4. For >= v2.3.28 use per board lock instead of io_request_lock. | ||
601 | 5. For >= v2.3.28 eliminate advansys_command() and | ||
602 | advansys_command_done(). | ||
603 | 6. Add some changes for PowerPC (Big Endian) support, but it isn't | ||
604 | working yet. | ||
605 | 7. Fix "nonexistent resource free" problem that occurred on a module | ||
606 | unload for boards with an I/O space >= 255. The 'n_io_port' field | ||
607 | is only one byte and can not be used to hold an ioport length more | ||
608 | than 255. | ||
609 | |||
610 | 3.3A (4/4/00): | ||
611 | 1. Update to Adv Library 5.8. | ||
612 | 2. For wide cards add support for CDBs up to 16 bytes. | ||
613 | 3. Eliminate warnings when CONFIG_PROC_FS is not defined. | ||
614 | |||
615 | 3.3B (5/1/00): | ||
616 | 1. Support for PowerPC (Big Endian) wide cards. Narrow cards | ||
617 | still need work. | ||
618 | 2. Change bitfields to shift and mask access for endian | ||
619 | portability. | ||
620 | |||
621 | 3.3C (10/13/00): | ||
622 | 1. Update for latest 2.4 kernel. | ||
623 | 2. Test ABP-480 CardBus support in 2.4 kernel - works! | ||
624 | 3. Update to Asc Library S123. | ||
625 | 4. Update to Adv Library 5.12. | ||
626 | |||
627 | 3.3D (11/22/00): | ||
628 | 1. Update for latest 2.4 kernel. | ||
629 | 2. Create patches for 2.2 and 2.4 kernels. | ||
630 | |||
631 | 3.3E (1/9/01): | ||
632 | 1. Now that 2.4 is released remove ifdef code for kernel versions | ||
633 | less than 2.2. The driver is now only supported in kernels 2.2, | ||
634 | 2.4, and greater. | ||
635 | 2. Add code to release and acquire the io_request_lock in | ||
636 | the driver entrypoint functions: advansys_detect and | ||
637 | advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver | ||
638 | still holds the io_request_lock on entry to SCSI low-level drivers. | ||
639 | This was supposed to be removed before 2.4 was released but never | ||
640 | happened. When the mid-level SCSI driver is changed all references | ||
641 | to the io_request_lock should be removed from the driver. | ||
642 | 3. Simplify error handling by removing advansys_abort(), | ||
643 | AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are | ||
644 | now handled by resetting the SCSI bus and fully re-initializing | ||
645 | the chip. This simple method of error recovery has proven to work | ||
646 | most reliably after attempts at different methods. Also now only | ||
647 | support the "new" error handling method and remove the obsolete | ||
648 | error handling interface. | ||
649 | 4. Fix debug build errors. | ||
650 | |||
651 | 3.3F (1/24/01): | ||
652 | 1. Merge with ConnectCom version from Andy Kellner which | ||
653 | updates Adv Library to 5.14. | ||
654 | 2. Make PowerPC (Big Endian) work for narrow cards and | ||
655 | fix problems writing EEPROM for wide cards. | ||
656 | 3. Remove interrupts_enabled assertion function. | ||
657 | |||
658 | 3.3G (2/16/01): | ||
659 | 1. Return an error from narrow boards if passed a 16 byte | ||
660 | CDB. The wide board can already handle 16 byte CDBs. | ||
661 | |||
662 | 3.3GJ (4/15/02): | ||
663 | 1. hacks for lk 2.5 series (D. Gilbert) | ||
664 | |||
665 | 3.3GJD (10/14/02): | ||
666 | 1. change select_queue_depths to slave_configure | ||
667 | 2. make cmd_per_lun be sane again | ||
668 | |||
669 | 3.3K [2004/06/24]: | ||
670 | 1. continuing cleanup for lk 2.6 series | ||
671 | 2. Fix problem in lk 2.6.7-bk2 that broke PCI wide cards | ||
672 | 3. Fix problem that oopsed ISA cards | ||
673 | |||
674 | I. Known Problems/Fix List (XXX) | ||
675 | |||
676 | 1. Need to add memory mapping workaround. Test the memory mapping. | ||
677 | If it doesn't work revert to I/O port access. Can a test be done | ||
678 | safely? | ||
679 | 2. Handle an interrupt not working. Keep an interrupt counter in | ||
680 | the interrupt handler. In the timeout function if the interrupt | ||
681 | has not occurred then print a message and run in polled mode. | ||
682 | 3. Allow bus type scanning order to be changed. | ||
683 | 4. Need to add support for target mode commands, cf. CAM XPT. | ||
684 | |||
685 | J. Credits (Chronological Order) | ||
686 | |||
687 | Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver | ||
688 | and maintained it up to 3.3F. He continues to answer questions | ||
689 | and help maintain the driver. | ||
690 | |||
691 | Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and | ||
692 | basis for the Linux v1.3.X changes which were included in the | ||
693 | 1.2 release. | ||
694 | |||
695 | Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug | ||
696 | in advansys_biosparam() which was fixed in the 1.3 release. | ||
697 | |||
698 | Erik Ratcliffe <erik@caldera.com> has done testing of the | ||
699 | AdvanSys driver in the Caldera releases. | ||
700 | |||
701 | Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to | ||
702 | AscWaitTixISRDone() which he found necessary to make the | ||
703 | driver work with a SCSI-1 disk. | ||
704 | |||
705 | Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide | ||
706 | support in the 3.1A driver. | ||
707 | |||
708 | Doug Gilbert <dgilbert@interlog.com> has made changes and | ||
709 | suggestions to improve the driver and done a lot of testing. | ||
710 | |||
711 | Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed | ||
712 | in 3.2K. | ||
713 | |||
714 | Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA | ||
715 | patch and helped with PowerPC wide and narrow board support. | ||
716 | |||
717 | Philip Blundell <philb@gnu.org> provided an | ||
718 | advansys_interrupts_enabled patch. | ||
719 | |||
720 | Dave Jones <dave@denial.force9.co.uk> reported the compiler | ||
721 | warnings generated when CONFIG_PROC_FS was not defined in | ||
722 | the 3.2M driver. | ||
723 | |||
724 | Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian | ||
725 | problems) for wide cards. | ||
726 | |||
727 | Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow | ||
728 | card error handling. | ||
729 | |||
730 | Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow | ||
731 | board support and fixed a bug in AscGetEEPConfig(). | ||
732 | |||
733 | Arnaldo Carvalho de Melo <acme@conectiva.com.br> made | ||
734 | save_flags/restore_flags changes. | ||
735 | |||
736 | Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI | ||
737 | driver development for ConnectCom (Version > 3.3F). | ||
738 | |||
739 | K. ConnectCom (AdvanSys) Contact Information | ||
740 | |||
741 | Mail: ConnectCom Solutions, Inc. | ||
742 | 1150 Ringwood Court | ||
743 | San Jose, CA 95131 | ||
744 | Operator/Sales: 1-408-383-9400 | ||
745 | FAX: 1-408-383-9612 | ||
746 | Tech Support: 1-408-467-2930 | ||
747 | Tech Support E-Mail: linux@connectcom.net | ||
748 | FTP Site: ftp.connectcom.net (login: anonymous) | ||
749 | Web Site: http://www.connectcom.net | ||
750 | |||
751 | */ | ||
752 | |||
753 | /* | ||
754 | * --- Linux Include Files | ||
755 | */ | ||
756 | |||
757 | #include <linux/config.h> | ||
758 | #include <linux/module.h> | ||
759 | |||
760 | #if defined(CONFIG_X86) && !defined(CONFIG_ISA) | ||
761 | #define CONFIG_ISA | ||
762 | #endif /* CONFIG_X86 && !CONFIG_ISA */ | ||
763 | |||
764 | #include <linux/string.h> | ||
765 | #include <linux/kernel.h> | ||
766 | #include <linux/types.h> | ||
767 | #include <linux/ioport.h> | ||
768 | #include <linux/interrupt.h> | ||
769 | #include <linux/delay.h> | ||
770 | #include <linux/slab.h> | ||
771 | #include <linux/mm.h> | ||
772 | #include <linux/proc_fs.h> | ||
773 | #include <linux/init.h> | ||
774 | #include <linux/blkdev.h> | ||
775 | #include <linux/stat.h> | ||
776 | #include <linux/spinlock.h> | ||
777 | #include <linux/dma-mapping.h> | ||
778 | |||
779 | #include <asm/io.h> | ||
780 | #include <asm/system.h> | ||
781 | #include <asm/dma.h> | ||
782 | |||
783 | /* FIXME: (by jejb@steeleye.com) This warning is present for two | ||
784 | * reasons: | ||
785 | * | ||
786 | * 1) This driver badly needs converting to the correct driver model | ||
787 | * probing API | ||
788 | * | ||
789 | * 2) Although all of the necessary command mapping places have the | ||
790 | * appropriate dma_map.. APIs, the driver still processes its internal | ||
791 | * queue using bus_to_virt() and virt_to_bus() which are illegal under | ||
792 | * the API. The entire queue processing structure will need to be | ||
793 | * altered to fix this. | ||
794 | */ | ||
795 | #warning this driver is still not properly converted to the DMA API | ||
796 | |||
797 | #include <scsi/scsi_cmnd.h> | ||
798 | #include <scsi/scsi_device.h> | ||
799 | #include <scsi/scsi_tcq.h> | ||
800 | #include <scsi/scsi.h> | ||
801 | #include <scsi/scsi_host.h> | ||
802 | #include "advansys.h" | ||
803 | #ifdef CONFIG_PCI | ||
804 | #include <linux/pci.h> | ||
805 | #endif /* CONFIG_PCI */ | ||
806 | |||
807 | |||
808 | /* | ||
809 | * --- Driver Options | ||
810 | */ | ||
811 | |||
812 | /* Enable driver assertions. */ | ||
813 | #define ADVANSYS_ASSERT | ||
814 | |||
815 | /* Enable driver /proc statistics. */ | ||
816 | #define ADVANSYS_STATS | ||
817 | |||
818 | /* Enable driver tracing. */ | ||
819 | /* #define ADVANSYS_DEBUG */ | ||
820 | |||
821 | |||
822 | /* | ||
823 | * --- Debugging Header | ||
824 | */ | ||
825 | |||
826 | #ifdef ADVANSYS_DEBUG | ||
827 | #define STATIC | ||
828 | #else /* ADVANSYS_DEBUG */ | ||
829 | #define STATIC static | ||
830 | #endif /* ADVANSYS_DEBUG */ | ||
831 | |||
832 | |||
833 | /* | ||
834 | * --- Asc Library Constants and Macros | ||
835 | */ | ||
836 | |||
837 | #define ASC_LIB_VERSION_MAJOR 1 | ||
838 | #define ASC_LIB_VERSION_MINOR 24 | ||
839 | #define ASC_LIB_SERIAL_NUMBER 123 | ||
840 | |||
841 | /* | ||
842 | * Portable Data Types | ||
843 | * | ||
844 | * Any instance where a 32-bit long or pointer type is assumed | ||
845 | * for precision or HW defined structures, the following define | ||
846 | * types must be used. In Linux the char, short, and int types | ||
847 | * are all consistent at 8, 16, and 32 bits respectively. Pointers | ||
848 | * and long types are 64 bits on Alpha and UltraSPARC. | ||
849 | */ | ||
850 | #define ASC_PADDR __u32 /* Physical/Bus address data type. */ | ||
851 | #define ASC_VADDR __u32 /* Virtual address data type. */ | ||
852 | #define ASC_DCNT __u32 /* Unsigned Data count type. */ | ||
853 | #define ASC_SDCNT __s32 /* Signed Data count type. */ | ||
854 | |||
855 | /* | ||
856 | * These macros are used to convert a virtual address to a | ||
857 | * 32-bit value. This currently can be used on Linux Alpha | ||
858 | * which uses 64-bit virtual address but a 32-bit bus address. | ||
859 | * This is likely to break in the future, but doing this now | ||
860 | * will give us time to change the HW and FW to handle 64-bit | ||
861 | * addresses. | ||
862 | */ | ||
863 | #define ASC_VADDR_TO_U32 virt_to_bus | ||
864 | #define ASC_U32_TO_VADDR bus_to_virt | ||
865 | |||
866 | typedef unsigned char uchar; | ||
867 | |||
868 | #ifndef TRUE | ||
869 | #define TRUE (1) | ||
870 | #endif | ||
871 | #ifndef FALSE | ||
872 | #define FALSE (0) | ||
873 | #endif | ||
874 | |||
875 | #define EOF (-1) | ||
876 | #define ERR (-1) | ||
877 | #define UW_ERR (uint)(0xFFFF) | ||
878 | #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0) | ||
879 | #define AscPCIConfigVendorIDRegister 0x0000 | ||
880 | #define AscPCIConfigDeviceIDRegister 0x0002 | ||
881 | #define AscPCIConfigCommandRegister 0x0004 | ||
882 | #define AscPCIConfigStatusRegister 0x0006 | ||
883 | #define AscPCIConfigRevisionIDRegister 0x0008 | ||
884 | #define AscPCIConfigCacheSize 0x000C | ||
885 | #define AscPCIConfigLatencyTimer 0x000D | ||
886 | #define AscPCIIOBaseRegister 0x0010 | ||
887 | #define AscPCICmdRegBits_IOMemBusMaster 0x0007 | ||
888 | #define ASC_PCI_ID2BUS(id) ((id) & 0xFF) | ||
889 | #define ASC_PCI_ID2DEV(id) (((id) >> 11) & 0x1F) | ||
890 | #define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7) | ||
891 | #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF)) | ||
892 | #define ASC_PCI_VENDORID 0x10CD | ||
893 | #define ASC_PCI_DEVICEID_1200A 0x1100 | ||
894 | #define ASC_PCI_DEVICEID_1200B 0x1200 | ||
895 | #define ASC_PCI_DEVICEID_ULTRA 0x1300 | ||
896 | #define ASC_PCI_REVISION_3150 0x02 | ||
897 | #define ASC_PCI_REVISION_3050 0x03 | ||
898 | |||
899 | #define ASC_DVCLIB_CALL_DONE (1) | ||
900 | #define ASC_DVCLIB_CALL_FAILED (0) | ||
901 | #define ASC_DVCLIB_CALL_ERROR (-1) | ||
902 | |||
903 | /* | ||
904 | * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists. | ||
905 | * The SRB structure will have to be changed and the ASC_SRB2SCSIQ() | ||
906 | * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the | ||
907 | * SRB structure. | ||
908 | */ | ||
909 | #define CC_VERY_LONG_SG_LIST 0 | ||
910 | #define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr) | ||
911 | |||
912 | #define PortAddr unsigned short /* port address size */ | ||
913 | #define inp(port) inb(port) | ||
914 | #define outp(port, byte) outb((byte), (port)) | ||
915 | |||
916 | #define inpw(port) inw(port) | ||
917 | #define outpw(port, word) outw((word), (port)) | ||
918 | |||
919 | #define ASC_MAX_SG_QUEUE 7 | ||
920 | #define ASC_MAX_SG_LIST 255 | ||
921 | |||
922 | #define ASC_CS_TYPE unsigned short | ||
923 | |||
924 | #define ASC_IS_ISA (0x0001) | ||
925 | #define ASC_IS_ISAPNP (0x0081) | ||
926 | #define ASC_IS_EISA (0x0002) | ||
927 | #define ASC_IS_PCI (0x0004) | ||
928 | #define ASC_IS_PCI_ULTRA (0x0104) | ||
929 | #define ASC_IS_PCMCIA (0x0008) | ||
930 | #define ASC_IS_MCA (0x0020) | ||
931 | #define ASC_IS_VL (0x0040) | ||
932 | #define ASC_ISA_PNP_PORT_ADDR (0x279) | ||
933 | #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800) | ||
934 | #define ASC_IS_WIDESCSI_16 (0x0100) | ||
935 | #define ASC_IS_WIDESCSI_32 (0x0200) | ||
936 | #define ASC_IS_BIG_ENDIAN (0x8000) | ||
937 | #define ASC_CHIP_MIN_VER_VL (0x01) | ||
938 | #define ASC_CHIP_MAX_VER_VL (0x07) | ||
939 | #define ASC_CHIP_MIN_VER_PCI (0x09) | ||
940 | #define ASC_CHIP_MAX_VER_PCI (0x0F) | ||
941 | #define ASC_CHIP_VER_PCI_BIT (0x08) | ||
942 | #define ASC_CHIP_MIN_VER_ISA (0x11) | ||
943 | #define ASC_CHIP_MIN_VER_ISA_PNP (0x21) | ||
944 | #define ASC_CHIP_MAX_VER_ISA (0x27) | ||
945 | #define ASC_CHIP_VER_ISA_BIT (0x30) | ||
946 | #define ASC_CHIP_VER_ISAPNP_BIT (0x20) | ||
947 | #define ASC_CHIP_VER_ASYN_BUG (0x21) | ||
948 | #define ASC_CHIP_VER_PCI 0x08 | ||
949 | #define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02) | ||
950 | #define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03) | ||
951 | #define ASC_CHIP_MIN_VER_EISA (0x41) | ||
952 | #define ASC_CHIP_MAX_VER_EISA (0x47) | ||
953 | #define ASC_CHIP_VER_EISA_BIT (0x40) | ||
954 | #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3) | ||
955 | #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21 | ||
956 | #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A | ||
957 | #define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL) | ||
958 | #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL) | ||
959 | #define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL) | ||
960 | #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL) | ||
961 | #define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL) | ||
962 | #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL) | ||
963 | #define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL) | ||
964 | #define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL) | ||
965 | |||
966 | #define ASC_SCSI_ID_BITS 3 | ||
967 | #define ASC_SCSI_TIX_TYPE uchar | ||
968 | #define ASC_ALL_DEVICE_BIT_SET 0xFF | ||
969 | #define ASC_SCSI_BIT_ID_TYPE uchar | ||
970 | #define ASC_MAX_TID 7 | ||
971 | #define ASC_MAX_LUN 7 | ||
972 | #define ASC_SCSI_WIDTH_BIT_SET 0xFF | ||
973 | #define ASC_MAX_SENSE_LEN 32 | ||
974 | #define ASC_MIN_SENSE_LEN 14 | ||
975 | #define ASC_MAX_CDB_LEN 12 | ||
976 | #define ASC_SCSI_RESET_HOLD_TIME_US 60 | ||
977 | |||
978 | #define ADV_INQ_CLOCKING_ST_ONLY 0x0 | ||
979 | #define ADV_INQ_CLOCKING_DT_ONLY 0x1 | ||
980 | #define ADV_INQ_CLOCKING_ST_AND_DT 0x3 | ||
981 | |||
982 | /* | ||
983 | * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data) | ||
984 | * and CmdDt (Command Support Data) field bit definitions. | ||
985 | */ | ||
986 | #define ADV_INQ_RTN_VPD_AND_CMDDT 0x3 | ||
987 | #define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2 | ||
988 | #define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1 | ||
989 | #define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0 | ||
990 | |||
991 | #define ASC_SCSIDIR_NOCHK 0x00 | ||
992 | #define ASC_SCSIDIR_T2H 0x08 | ||
993 | #define ASC_SCSIDIR_H2T 0x10 | ||
994 | #define ASC_SCSIDIR_NODATA 0x18 | ||
995 | #define SCSI_ASC_NOMEDIA 0x3A | ||
996 | #define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4)) | ||
997 | #define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F)) | ||
998 | #define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13)) | ||
999 | #define PUT_CDB1(x) ((uchar)((uint)(x) >> 8)) | ||
1000 | #define MS_CMD_DONE 0x00 | ||
1001 | #define MS_EXTEND 0x01 | ||
1002 | #define MS_SDTR_LEN 0x03 | ||
1003 | #define MS_SDTR_CODE 0x01 | ||
1004 | #define MS_WDTR_LEN 0x02 | ||
1005 | #define MS_WDTR_CODE 0x03 | ||
1006 | #define MS_MDP_LEN 0x05 | ||
1007 | #define MS_MDP_CODE 0x00 | ||
1008 | |||
1009 | /* | ||
1010 | * Inquiry data structure and bitfield macros | ||
1011 | * | ||
1012 | * Only quantities of more than 1 bit are shifted, since the others are | ||
1013 | * just tested for true or false. C bitfields aren't portable between big | ||
1014 | * and little-endian platforms so they are not used. | ||
1015 | */ | ||
1016 | |||
1017 | #define ASC_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f) | ||
1018 | #define ASC_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5) | ||
1019 | #define ASC_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f) | ||
1020 | #define ASC_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80) | ||
1021 | #define ASC_INQ_ANSI_VER(inq) ((inq)->ver & 0x07) | ||
1022 | #define ASC_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3) | ||
1023 | #define ASC_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6) | ||
1024 | #define ASC_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f) | ||
1025 | #define ASC_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40) | ||
1026 | #define ASC_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80) | ||
1027 | #define ASC_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01) | ||
1028 | #define ASC_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02) | ||
1029 | #define ASC_INQ_LINK_CMD(inq) ((inq)->flags & 0x08) | ||
1030 | #define ASC_INQ_SYNC(inq) ((inq)->flags & 0x10) | ||
1031 | #define ASC_INQ_WIDE16(inq) ((inq)->flags & 0x20) | ||
1032 | #define ASC_INQ_WIDE32(inq) ((inq)->flags & 0x40) | ||
1033 | #define ASC_INQ_REL_ADDR(inq) ((inq)->flags & 0x80) | ||
1034 | #define ASC_INQ_INFO_UNIT(inq) ((inq)->info & 0x01) | ||
1035 | #define ASC_INQ_QUICK_ARB(inq) ((inq)->info & 0x02) | ||
1036 | #define ASC_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2) | ||
1037 | |||
1038 | typedef struct { | ||
1039 | uchar periph; | ||
1040 | uchar devtype; | ||
1041 | uchar ver; | ||
1042 | uchar byte3; | ||
1043 | uchar add_len; | ||
1044 | uchar res1; | ||
1045 | uchar res2; | ||
1046 | uchar flags; | ||
1047 | uchar vendor_id[8]; | ||
1048 | uchar product_id[16]; | ||
1049 | uchar product_rev_level[4]; | ||
1050 | } ASC_SCSI_INQUIRY; | ||
1051 | |||
1052 | #define ASC_SG_LIST_PER_Q 7 | ||
1053 | #define QS_FREE 0x00 | ||
1054 | #define QS_READY 0x01 | ||
1055 | #define QS_DISC1 0x02 | ||
1056 | #define QS_DISC2 0x04 | ||
1057 | #define QS_BUSY 0x08 | ||
1058 | #define QS_ABORTED 0x40 | ||
1059 | #define QS_DONE 0x80 | ||
1060 | #define QC_NO_CALLBACK 0x01 | ||
1061 | #define QC_SG_SWAP_QUEUE 0x02 | ||
1062 | #define QC_SG_HEAD 0x04 | ||
1063 | #define QC_DATA_IN 0x08 | ||
1064 | #define QC_DATA_OUT 0x10 | ||
1065 | #define QC_URGENT 0x20 | ||
1066 | #define QC_MSG_OUT 0x40 | ||
1067 | #define QC_REQ_SENSE 0x80 | ||
1068 | #define QCSG_SG_XFER_LIST 0x02 | ||
1069 | #define QCSG_SG_XFER_MORE 0x04 | ||
1070 | #define QCSG_SG_XFER_END 0x08 | ||
1071 | #define QD_IN_PROGRESS 0x00 | ||
1072 | #define QD_NO_ERROR 0x01 | ||
1073 | #define QD_ABORTED_BY_HOST 0x02 | ||
1074 | #define QD_WITH_ERROR 0x04 | ||
1075 | #define QD_INVALID_REQUEST 0x80 | ||
1076 | #define QD_INVALID_HOST_NUM 0x81 | ||
1077 | #define QD_INVALID_DEVICE 0x82 | ||
1078 | #define QD_ERR_INTERNAL 0xFF | ||
1079 | #define QHSTA_NO_ERROR 0x00 | ||
1080 | #define QHSTA_M_SEL_TIMEOUT 0x11 | ||
1081 | #define QHSTA_M_DATA_OVER_RUN 0x12 | ||
1082 | #define QHSTA_M_DATA_UNDER_RUN 0x12 | ||
1083 | #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13 | ||
1084 | #define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14 | ||
1085 | #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21 | ||
1086 | #define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22 | ||
1087 | #define QHSTA_D_HOST_ABORT_FAILED 0x23 | ||
1088 | #define QHSTA_D_EXE_SCSI_Q_FAILED 0x24 | ||
1089 | #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25 | ||
1090 | #define QHSTA_D_ASPI_NO_BUF_POOL 0x26 | ||
1091 | #define QHSTA_M_WTM_TIMEOUT 0x41 | ||
1092 | #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42 | ||
1093 | #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43 | ||
1094 | #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44 | ||
1095 | #define QHSTA_M_TARGET_STATUS_BUSY 0x45 | ||
1096 | #define QHSTA_M_BAD_TAG_CODE 0x46 | ||
1097 | #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47 | ||
1098 | #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48 | ||
1099 | #define QHSTA_D_LRAM_CMP_ERROR 0x81 | ||
1100 | #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1 | ||
1101 | #define ASC_FLAG_SCSIQ_REQ 0x01 | ||
1102 | #define ASC_FLAG_BIOS_SCSIQ_REQ 0x02 | ||
1103 | #define ASC_FLAG_BIOS_ASYNC_IO 0x04 | ||
1104 | #define ASC_FLAG_SRB_LINEAR_ADDR 0x08 | ||
1105 | #define ASC_FLAG_WIN16 0x10 | ||
1106 | #define ASC_FLAG_WIN32 0x20 | ||
1107 | #define ASC_FLAG_ISA_OVER_16MB 0x40 | ||
1108 | #define ASC_FLAG_DOS_VM_CALLBACK 0x80 | ||
1109 | #define ASC_TAG_FLAG_EXTRA_BYTES 0x10 | ||
1110 | #define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04 | ||
1111 | #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08 | ||
1112 | #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40 | ||
1113 | #define ASC_SCSIQ_CPY_BEG 4 | ||
1114 | #define ASC_SCSIQ_SGHD_CPY_BEG 2 | ||
1115 | #define ASC_SCSIQ_B_FWD 0 | ||
1116 | #define ASC_SCSIQ_B_BWD 1 | ||
1117 | #define ASC_SCSIQ_B_STATUS 2 | ||
1118 | #define ASC_SCSIQ_B_QNO 3 | ||
1119 | #define ASC_SCSIQ_B_CNTL 4 | ||
1120 | #define ASC_SCSIQ_B_SG_QUEUE_CNT 5 | ||
1121 | #define ASC_SCSIQ_D_DATA_ADDR 8 | ||
1122 | #define ASC_SCSIQ_D_DATA_CNT 12 | ||
1123 | #define ASC_SCSIQ_B_SENSE_LEN 20 | ||
1124 | #define ASC_SCSIQ_DONE_INFO_BEG 22 | ||
1125 | #define ASC_SCSIQ_D_SRBPTR 22 | ||
1126 | #define ASC_SCSIQ_B_TARGET_IX 26 | ||
1127 | #define ASC_SCSIQ_B_CDB_LEN 28 | ||
1128 | #define ASC_SCSIQ_B_TAG_CODE 29 | ||
1129 | #define ASC_SCSIQ_W_VM_ID 30 | ||
1130 | #define ASC_SCSIQ_DONE_STATUS 32 | ||
1131 | #define ASC_SCSIQ_HOST_STATUS 33 | ||
1132 | #define ASC_SCSIQ_SCSI_STATUS 34 | ||
1133 | #define ASC_SCSIQ_CDB_BEG 36 | ||
1134 | #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56 | ||
1135 | #define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60 | ||
1136 | #define ASC_SCSIQ_B_FIRST_SG_WK_QP 48 | ||
1137 | #define ASC_SCSIQ_B_SG_WK_QP 49 | ||
1138 | #define ASC_SCSIQ_B_SG_WK_IX 50 | ||
1139 | #define ASC_SCSIQ_W_ALT_DC1 52 | ||
1140 | #define ASC_SCSIQ_B_LIST_CNT 6 | ||
1141 | #define ASC_SCSIQ_B_CUR_LIST_CNT 7 | ||
1142 | #define ASC_SGQ_B_SG_CNTL 4 | ||
1143 | #define ASC_SGQ_B_SG_HEAD_QP 5 | ||
1144 | #define ASC_SGQ_B_SG_LIST_CNT 6 | ||
1145 | #define ASC_SGQ_B_SG_CUR_LIST_CNT 7 | ||
1146 | #define ASC_SGQ_LIST_BEG 8 | ||
1147 | #define ASC_DEF_SCSI1_QNG 4 | ||
1148 | #define ASC_MAX_SCSI1_QNG 4 | ||
1149 | #define ASC_DEF_SCSI2_QNG 16 | ||
1150 | #define ASC_MAX_SCSI2_QNG 32 | ||
1151 | #define ASC_TAG_CODE_MASK 0x23 | ||
1152 | #define ASC_STOP_REQ_RISC_STOP 0x01 | ||
1153 | #define ASC_STOP_ACK_RISC_STOP 0x03 | ||
1154 | #define ASC_STOP_CLEAN_UP_BUSY_Q 0x10 | ||
1155 | #define ASC_STOP_CLEAN_UP_DISC_Q 0x20 | ||
1156 | #define ASC_STOP_HOST_REQ_RISC_HALT 0x40 | ||
1157 | #define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS)) | ||
1158 | #define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid)) | ||
1159 | #define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID)) | ||
1160 | #define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID) | ||
1161 | #define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID) | ||
1162 | #define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN) | ||
1163 | #define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6)) | ||
1164 | |||
1165 | typedef struct asc_scsiq_1 { | ||
1166 | uchar status; | ||
1167 | uchar q_no; | ||
1168 | uchar cntl; | ||
1169 | uchar sg_queue_cnt; | ||
1170 | uchar target_id; | ||
1171 | uchar target_lun; | ||
1172 | ASC_PADDR data_addr; | ||
1173 | ASC_DCNT data_cnt; | ||
1174 | ASC_PADDR sense_addr; | ||
1175 | uchar sense_len; | ||
1176 | uchar extra_bytes; | ||
1177 | } ASC_SCSIQ_1; | ||
1178 | |||
1179 | typedef struct asc_scsiq_2 { | ||
1180 | ASC_VADDR srb_ptr; | ||
1181 | uchar target_ix; | ||
1182 | uchar flag; | ||
1183 | uchar cdb_len; | ||
1184 | uchar tag_code; | ||
1185 | ushort vm_id; | ||
1186 | } ASC_SCSIQ_2; | ||
1187 | |||
1188 | typedef struct asc_scsiq_3 { | ||
1189 | uchar done_stat; | ||
1190 | uchar host_stat; | ||
1191 | uchar scsi_stat; | ||
1192 | uchar scsi_msg; | ||
1193 | } ASC_SCSIQ_3; | ||
1194 | |||
1195 | typedef struct asc_scsiq_4 { | ||
1196 | uchar cdb[ASC_MAX_CDB_LEN]; | ||
1197 | uchar y_first_sg_list_qp; | ||
1198 | uchar y_working_sg_qp; | ||
1199 | uchar y_working_sg_ix; | ||
1200 | uchar y_res; | ||
1201 | ushort x_req_count; | ||
1202 | ushort x_reconnect_rtn; | ||
1203 | ASC_PADDR x_saved_data_addr; | ||
1204 | ASC_DCNT x_saved_data_cnt; | ||
1205 | } ASC_SCSIQ_4; | ||
1206 | |||
1207 | typedef struct asc_q_done_info { | ||
1208 | ASC_SCSIQ_2 d2; | ||
1209 | ASC_SCSIQ_3 d3; | ||
1210 | uchar q_status; | ||
1211 | uchar q_no; | ||
1212 | uchar cntl; | ||
1213 | uchar sense_len; | ||
1214 | uchar extra_bytes; | ||
1215 | uchar res; | ||
1216 | ASC_DCNT remain_bytes; | ||
1217 | } ASC_QDONE_INFO; | ||
1218 | |||
1219 | typedef struct asc_sg_list { | ||
1220 | ASC_PADDR addr; | ||
1221 | ASC_DCNT bytes; | ||
1222 | } ASC_SG_LIST; | ||
1223 | |||
1224 | typedef struct asc_sg_head { | ||
1225 | ushort entry_cnt; | ||
1226 | ushort queue_cnt; | ||
1227 | ushort entry_to_copy; | ||
1228 | ushort res; | ||
1229 | ASC_SG_LIST sg_list[ASC_MAX_SG_LIST]; | ||
1230 | } ASC_SG_HEAD; | ||
1231 | |||
1232 | #define ASC_MIN_SG_LIST 2 | ||
1233 | |||
1234 | typedef struct asc_min_sg_head { | ||
1235 | ushort entry_cnt; | ||
1236 | ushort queue_cnt; | ||
1237 | ushort entry_to_copy; | ||
1238 | ushort res; | ||
1239 | ASC_SG_LIST sg_list[ASC_MIN_SG_LIST]; | ||
1240 | } ASC_MIN_SG_HEAD; | ||
1241 | |||
1242 | #define QCX_SORT (0x0001) | ||
1243 | #define QCX_COALEASE (0x0002) | ||
1244 | |||
1245 | typedef struct asc_scsi_q { | ||
1246 | ASC_SCSIQ_1 q1; | ||
1247 | ASC_SCSIQ_2 q2; | ||
1248 | uchar *cdbptr; | ||
1249 | ASC_SG_HEAD *sg_head; | ||
1250 | ushort remain_sg_entry_cnt; | ||
1251 | ushort next_sg_index; | ||
1252 | } ASC_SCSI_Q; | ||
1253 | |||
1254 | typedef struct asc_scsi_req_q { | ||
1255 | ASC_SCSIQ_1 r1; | ||
1256 | ASC_SCSIQ_2 r2; | ||
1257 | uchar *cdbptr; | ||
1258 | ASC_SG_HEAD *sg_head; | ||
1259 | uchar *sense_ptr; | ||
1260 | ASC_SCSIQ_3 r3; | ||
1261 | uchar cdb[ASC_MAX_CDB_LEN]; | ||
1262 | uchar sense[ASC_MIN_SENSE_LEN]; | ||
1263 | } ASC_SCSI_REQ_Q; | ||
1264 | |||
1265 | typedef struct asc_scsi_bios_req_q { | ||
1266 | ASC_SCSIQ_1 r1; | ||
1267 | ASC_SCSIQ_2 r2; | ||
1268 | uchar *cdbptr; | ||
1269 | ASC_SG_HEAD *sg_head; | ||
1270 | uchar *sense_ptr; | ||
1271 | ASC_SCSIQ_3 r3; | ||
1272 | uchar cdb[ASC_MAX_CDB_LEN]; | ||
1273 | uchar sense[ASC_MIN_SENSE_LEN]; | ||
1274 | } ASC_SCSI_BIOS_REQ_Q; | ||
1275 | |||
1276 | typedef struct asc_risc_q { | ||
1277 | uchar fwd; | ||
1278 | uchar bwd; | ||
1279 | ASC_SCSIQ_1 i1; | ||
1280 | ASC_SCSIQ_2 i2; | ||
1281 | ASC_SCSIQ_3 i3; | ||
1282 | ASC_SCSIQ_4 i4; | ||
1283 | } ASC_RISC_Q; | ||
1284 | |||
1285 | typedef struct asc_sg_list_q { | ||
1286 | uchar seq_no; | ||
1287 | uchar q_no; | ||
1288 | uchar cntl; | ||
1289 | uchar sg_head_qp; | ||
1290 | uchar sg_list_cnt; | ||
1291 | uchar sg_cur_list_cnt; | ||
1292 | } ASC_SG_LIST_Q; | ||
1293 | |||
1294 | typedef struct asc_risc_sg_list_q { | ||
1295 | uchar fwd; | ||
1296 | uchar bwd; | ||
1297 | ASC_SG_LIST_Q sg; | ||
1298 | ASC_SG_LIST sg_list[7]; | ||
1299 | } ASC_RISC_SG_LIST_Q; | ||
1300 | |||
1301 | #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL | ||
1302 | #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024 | ||
1303 | #define ASCQ_ERR_NO_ERROR 0 | ||
1304 | #define ASCQ_ERR_IO_NOT_FOUND 1 | ||
1305 | #define ASCQ_ERR_LOCAL_MEM 2 | ||
1306 | #define ASCQ_ERR_CHKSUM 3 | ||
1307 | #define ASCQ_ERR_START_CHIP 4 | ||
1308 | #define ASCQ_ERR_INT_TARGET_ID 5 | ||
1309 | #define ASCQ_ERR_INT_LOCAL_MEM 6 | ||
1310 | #define ASCQ_ERR_HALT_RISC 7 | ||
1311 | #define ASCQ_ERR_GET_ASPI_ENTRY 8 | ||
1312 | #define ASCQ_ERR_CLOSE_ASPI 9 | ||
1313 | #define ASCQ_ERR_HOST_INQUIRY 0x0A | ||
1314 | #define ASCQ_ERR_SAVED_SRB_BAD 0x0B | ||
1315 | #define ASCQ_ERR_QCNTL_SG_LIST 0x0C | ||
1316 | #define ASCQ_ERR_Q_STATUS 0x0D | ||
1317 | #define ASCQ_ERR_WR_SCSIQ 0x0E | ||
1318 | #define ASCQ_ERR_PC_ADDR 0x0F | ||
1319 | #define ASCQ_ERR_SYN_OFFSET 0x10 | ||
1320 | #define ASCQ_ERR_SYN_XFER_TIME 0x11 | ||
1321 | #define ASCQ_ERR_LOCK_DMA 0x12 | ||
1322 | #define ASCQ_ERR_UNLOCK_DMA 0x13 | ||
1323 | #define ASCQ_ERR_VDS_CHK_INSTALL 0x14 | ||
1324 | #define ASCQ_ERR_MICRO_CODE_HALT 0x15 | ||
1325 | #define ASCQ_ERR_SET_LRAM_ADDR 0x16 | ||
1326 | #define ASCQ_ERR_CUR_QNG 0x17 | ||
1327 | #define ASCQ_ERR_SG_Q_LINKS 0x18 | ||
1328 | #define ASCQ_ERR_SCSIQ_PTR 0x19 | ||
1329 | #define ASCQ_ERR_ISR_RE_ENTRY 0x1A | ||
1330 | #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B | ||
1331 | #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C | ||
1332 | #define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D | ||
1333 | #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E | ||
1334 | #define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F | ||
1335 | #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20 | ||
1336 | #define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21 | ||
1337 | #define ASCQ_ERR_SEND_SCSI_Q 0x22 | ||
1338 | #define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23 | ||
1339 | #define ASCQ_ERR_RESET_SDTR 0x24 | ||
1340 | |||
1341 | /* | ||
1342 | * Warning code values are set in ASC_DVC_VAR 'warn_code'. | ||
1343 | */ | ||
1344 | #define ASC_WARN_NO_ERROR 0x0000 | ||
1345 | #define ASC_WARN_IO_PORT_ROTATE 0x0001 | ||
1346 | #define ASC_WARN_EEPROM_CHKSUM 0x0002 | ||
1347 | #define ASC_WARN_IRQ_MODIFIED 0x0004 | ||
1348 | #define ASC_WARN_AUTO_CONFIG 0x0008 | ||
1349 | #define ASC_WARN_CMD_QNG_CONFLICT 0x0010 | ||
1350 | #define ASC_WARN_EEPROM_RECOVER 0x0020 | ||
1351 | #define ASC_WARN_CFG_MSW_RECOVER 0x0040 | ||
1352 | #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 | ||
1353 | |||
1354 | /* | ||
1355 | * Error code values are set in ASC_DVC_VAR 'err_code'. | ||
1356 | */ | ||
1357 | #define ASC_IERR_WRITE_EEPROM 0x0001 | ||
1358 | #define ASC_IERR_MCODE_CHKSUM 0x0002 | ||
1359 | #define ASC_IERR_SET_PC_ADDR 0x0004 | ||
1360 | #define ASC_IERR_START_STOP_CHIP 0x0008 | ||
1361 | #define ASC_IERR_IRQ_NO 0x0010 | ||
1362 | #define ASC_IERR_SET_IRQ_NO 0x0020 | ||
1363 | #define ASC_IERR_CHIP_VERSION 0x0040 | ||
1364 | #define ASC_IERR_SET_SCSI_ID 0x0080 | ||
1365 | #define ASC_IERR_GET_PHY_ADDR 0x0100 | ||
1366 | #define ASC_IERR_BAD_SIGNATURE 0x0200 | ||
1367 | #define ASC_IERR_NO_BUS_TYPE 0x0400 | ||
1368 | #define ASC_IERR_SCAM 0x0800 | ||
1369 | #define ASC_IERR_SET_SDTR 0x1000 | ||
1370 | #define ASC_IERR_RW_LRAM 0x8000 | ||
1371 | |||
1372 | #define ASC_DEF_IRQ_NO 10 | ||
1373 | #define ASC_MAX_IRQ_NO 15 | ||
1374 | #define ASC_MIN_IRQ_NO 10 | ||
1375 | #define ASC_MIN_REMAIN_Q (0x02) | ||
1376 | #define ASC_DEF_MAX_TOTAL_QNG (0xF0) | ||
1377 | #define ASC_MIN_TAG_Q_PER_DVC (0x04) | ||
1378 | #define ASC_DEF_TAG_Q_PER_DVC (0x04) | ||
1379 | #define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q | ||
1380 | #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q)) | ||
1381 | #define ASC_MAX_TOTAL_QNG 240 | ||
1382 | #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16 | ||
1383 | #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8 | ||
1384 | #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20 | ||
1385 | #define ASC_MAX_INRAM_TAG_QNG 16 | ||
1386 | #define ASC_IOADR_TABLE_MAX_IX 11 | ||
1387 | #define ASC_IOADR_GAP 0x10 | ||
1388 | #define ASC_SEARCH_IOP_GAP 0x10 | ||
1389 | #define ASC_MIN_IOP_ADDR (PortAddr)0x0100 | ||
1390 | #define ASC_MAX_IOP_ADDR (PortAddr)0x3F0 | ||
1391 | #define ASC_IOADR_1 (PortAddr)0x0110 | ||
1392 | #define ASC_IOADR_2 (PortAddr)0x0130 | ||
1393 | #define ASC_IOADR_3 (PortAddr)0x0150 | ||
1394 | #define ASC_IOADR_4 (PortAddr)0x0190 | ||
1395 | #define ASC_IOADR_5 (PortAddr)0x0210 | ||
1396 | #define ASC_IOADR_6 (PortAddr)0x0230 | ||
1397 | #define ASC_IOADR_7 (PortAddr)0x0250 | ||
1398 | #define ASC_IOADR_8 (PortAddr)0x0330 | ||
1399 | #define ASC_IOADR_DEF ASC_IOADR_8 | ||
1400 | #define ASC_LIB_SCSIQ_WK_SP 256 | ||
1401 | #define ASC_MAX_SYN_XFER_NO 16 | ||
1402 | #define ASC_SYN_MAX_OFFSET 0x0F | ||
1403 | #define ASC_DEF_SDTR_OFFSET 0x0F | ||
1404 | #define ASC_DEF_SDTR_INDEX 0x00 | ||
1405 | #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02 | ||
1406 | #define SYN_XFER_NS_0 25 | ||
1407 | #define SYN_XFER_NS_1 30 | ||
1408 | #define SYN_XFER_NS_2 35 | ||
1409 | #define SYN_XFER_NS_3 40 | ||
1410 | #define SYN_XFER_NS_4 50 | ||
1411 | #define SYN_XFER_NS_5 60 | ||
1412 | #define SYN_XFER_NS_6 70 | ||
1413 | #define SYN_XFER_NS_7 85 | ||
1414 | #define SYN_ULTRA_XFER_NS_0 12 | ||
1415 | #define SYN_ULTRA_XFER_NS_1 19 | ||
1416 | #define SYN_ULTRA_XFER_NS_2 25 | ||
1417 | #define SYN_ULTRA_XFER_NS_3 32 | ||
1418 | #define SYN_ULTRA_XFER_NS_4 38 | ||
1419 | #define SYN_ULTRA_XFER_NS_5 44 | ||
1420 | #define SYN_ULTRA_XFER_NS_6 50 | ||
1421 | #define SYN_ULTRA_XFER_NS_7 57 | ||
1422 | #define SYN_ULTRA_XFER_NS_8 63 | ||
1423 | #define SYN_ULTRA_XFER_NS_9 69 | ||
1424 | #define SYN_ULTRA_XFER_NS_10 75 | ||
1425 | #define SYN_ULTRA_XFER_NS_11 82 | ||
1426 | #define SYN_ULTRA_XFER_NS_12 88 | ||
1427 | #define SYN_ULTRA_XFER_NS_13 94 | ||
1428 | #define SYN_ULTRA_XFER_NS_14 100 | ||
1429 | #define SYN_ULTRA_XFER_NS_15 107 | ||
1430 | |||
1431 | typedef struct ext_msg { | ||
1432 | uchar msg_type; | ||
1433 | uchar msg_len; | ||
1434 | uchar msg_req; | ||
1435 | union { | ||
1436 | struct { | ||
1437 | uchar sdtr_xfer_period; | ||
1438 | uchar sdtr_req_ack_offset; | ||
1439 | } sdtr; | ||
1440 | struct { | ||
1441 | uchar wdtr_width; | ||
1442 | } wdtr; | ||
1443 | struct { | ||
1444 | uchar mdp_b3; | ||
1445 | uchar mdp_b2; | ||
1446 | uchar mdp_b1; | ||
1447 | uchar mdp_b0; | ||
1448 | } mdp; | ||
1449 | } u_ext_msg; | ||
1450 | uchar res; | ||
1451 | } EXT_MSG; | ||
1452 | |||
1453 | #define xfer_period u_ext_msg.sdtr.sdtr_xfer_period | ||
1454 | #define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset | ||
1455 | #define wdtr_width u_ext_msg.wdtr.wdtr_width | ||
1456 | #define mdp_b3 u_ext_msg.mdp_b3 | ||
1457 | #define mdp_b2 u_ext_msg.mdp_b2 | ||
1458 | #define mdp_b1 u_ext_msg.mdp_b1 | ||
1459 | #define mdp_b0 u_ext_msg.mdp_b0 | ||
1460 | |||
1461 | typedef struct asc_dvc_cfg { | ||
1462 | ASC_SCSI_BIT_ID_TYPE can_tagged_qng; | ||
1463 | ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled; | ||
1464 | ASC_SCSI_BIT_ID_TYPE disc_enable; | ||
1465 | ASC_SCSI_BIT_ID_TYPE sdtr_enable; | ||
1466 | uchar chip_scsi_id; | ||
1467 | uchar isa_dma_speed; | ||
1468 | uchar isa_dma_channel; | ||
1469 | uchar chip_version; | ||
1470 | ushort lib_serial_no; | ||
1471 | ushort lib_version; | ||
1472 | ushort mcode_date; | ||
1473 | ushort mcode_version; | ||
1474 | uchar max_tag_qng[ASC_MAX_TID + 1]; | ||
1475 | uchar *overrun_buf; | ||
1476 | uchar sdtr_period_offset[ASC_MAX_TID + 1]; | ||
1477 | ushort pci_slot_info; | ||
1478 | uchar adapter_info[6]; | ||
1479 | struct device *dev; | ||
1480 | } ASC_DVC_CFG; | ||
1481 | |||
1482 | #define ASC_DEF_DVC_CNTL 0xFFFF | ||
1483 | #define ASC_DEF_CHIP_SCSI_ID 7 | ||
1484 | #define ASC_DEF_ISA_DMA_SPEED 4 | ||
1485 | #define ASC_INIT_STATE_NULL 0x0000 | ||
1486 | #define ASC_INIT_STATE_BEG_GET_CFG 0x0001 | ||
1487 | #define ASC_INIT_STATE_END_GET_CFG 0x0002 | ||
1488 | #define ASC_INIT_STATE_BEG_SET_CFG 0x0004 | ||
1489 | #define ASC_INIT_STATE_END_SET_CFG 0x0008 | ||
1490 | #define ASC_INIT_STATE_BEG_LOAD_MC 0x0010 | ||
1491 | #define ASC_INIT_STATE_END_LOAD_MC 0x0020 | ||
1492 | #define ASC_INIT_STATE_BEG_INQUIRY 0x0040 | ||
1493 | #define ASC_INIT_STATE_END_INQUIRY 0x0080 | ||
1494 | #define ASC_INIT_RESET_SCSI_DONE 0x0100 | ||
1495 | #define ASC_INIT_STATE_WITHOUT_EEP 0x8000 | ||
1496 | #define ASC_PCI_DEVICE_ID_REV_A 0x1100 | ||
1497 | #define ASC_PCI_DEVICE_ID_REV_B 0x1200 | ||
1498 | #define ASC_BUG_FIX_IF_NOT_DWB 0x0001 | ||
1499 | #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002 | ||
1500 | #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41 | ||
1501 | #define ASC_MIN_TAGGED_CMD 7 | ||
1502 | #define ASC_MAX_SCSI_RESET_WAIT 30 | ||
1503 | |||
1504 | struct asc_dvc_var; /* Forward Declaration. */ | ||
1505 | |||
1506 | typedef void (* ASC_ISR_CALLBACK)(struct asc_dvc_var *, ASC_QDONE_INFO *); | ||
1507 | typedef int (* ASC_EXE_CALLBACK)(struct asc_dvc_var *, ASC_SCSI_Q *); | ||
1508 | |||
1509 | typedef struct asc_dvc_var { | ||
1510 | PortAddr iop_base; | ||
1511 | ushort err_code; | ||
1512 | ushort dvc_cntl; | ||
1513 | ushort bug_fix_cntl; | ||
1514 | ushort bus_type; | ||
1515 | ASC_ISR_CALLBACK isr_callback; | ||
1516 | ASC_EXE_CALLBACK exe_callback; | ||
1517 | ASC_SCSI_BIT_ID_TYPE init_sdtr; | ||
1518 | ASC_SCSI_BIT_ID_TYPE sdtr_done; | ||
1519 | ASC_SCSI_BIT_ID_TYPE use_tagged_qng; | ||
1520 | ASC_SCSI_BIT_ID_TYPE unit_not_ready; | ||
1521 | ASC_SCSI_BIT_ID_TYPE queue_full_or_busy; | ||
1522 | ASC_SCSI_BIT_ID_TYPE start_motor; | ||
1523 | uchar scsi_reset_wait; | ||
1524 | uchar chip_no; | ||
1525 | char is_in_int; | ||
1526 | uchar max_total_qng; | ||
1527 | uchar cur_total_qng; | ||
1528 | uchar in_critical_cnt; | ||
1529 | uchar irq_no; | ||
1530 | uchar last_q_shortage; | ||
1531 | ushort init_state; | ||
1532 | uchar cur_dvc_qng[ASC_MAX_TID + 1]; | ||
1533 | uchar max_dvc_qng[ASC_MAX_TID + 1]; | ||
1534 | ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1]; | ||
1535 | ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1]; | ||
1536 | uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO]; | ||
1537 | ASC_DVC_CFG *cfg; | ||
1538 | ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always; | ||
1539 | char redo_scam; | ||
1540 | ushort res2; | ||
1541 | uchar dos_int13_table[ASC_MAX_TID + 1]; | ||
1542 | ASC_DCNT max_dma_count; | ||
1543 | ASC_SCSI_BIT_ID_TYPE no_scam; | ||
1544 | ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer; | ||
1545 | uchar max_sdtr_index; | ||
1546 | uchar host_init_sdtr_index; | ||
1547 | struct asc_board *drv_ptr; | ||
1548 | ASC_DCNT uc_break; | ||
1549 | } ASC_DVC_VAR; | ||
1550 | |||
1551 | typedef struct asc_dvc_inq_info { | ||
1552 | uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1]; | ||
1553 | } ASC_DVC_INQ_INFO; | ||
1554 | |||
1555 | typedef struct asc_cap_info { | ||
1556 | ASC_DCNT lba; | ||
1557 | ASC_DCNT blk_size; | ||
1558 | } ASC_CAP_INFO; | ||
1559 | |||
1560 | typedef struct asc_cap_info_array { | ||
1561 | ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1]; | ||
1562 | } ASC_CAP_INFO_ARRAY; | ||
1563 | |||
1564 | #define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001 | ||
1565 | #define ASC_MCNTL_NULL_TARGET (ushort)0x0002 | ||
1566 | #define ASC_CNTL_INITIATOR (ushort)0x0001 | ||
1567 | #define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002 | ||
1568 | #define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004 | ||
1569 | #define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008 | ||
1570 | #define ASC_CNTL_NO_SCAM (ushort)0x0010 | ||
1571 | #define ASC_CNTL_INT_MULTI_Q (ushort)0x0080 | ||
1572 | #define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040 | ||
1573 | #define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100 | ||
1574 | #define ASC_CNTL_RESET_SCSI (ushort)0x0200 | ||
1575 | #define ASC_CNTL_INIT_INQUIRY (ushort)0x0400 | ||
1576 | #define ASC_CNTL_INIT_VERBOSE (ushort)0x0800 | ||
1577 | #define ASC_CNTL_SCSI_PARITY (ushort)0x1000 | ||
1578 | #define ASC_CNTL_BURST_MODE (ushort)0x2000 | ||
1579 | #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000 | ||
1580 | #define ASC_EEP_DVC_CFG_BEG_VL 2 | ||
1581 | #define ASC_EEP_MAX_DVC_ADDR_VL 15 | ||
1582 | #define ASC_EEP_DVC_CFG_BEG 32 | ||
1583 | #define ASC_EEP_MAX_DVC_ADDR 45 | ||
1584 | #define ASC_EEP_DEFINED_WORDS 10 | ||
1585 | #define ASC_EEP_MAX_ADDR 63 | ||
1586 | #define ASC_EEP_RES_WORDS 0 | ||
1587 | #define ASC_EEP_MAX_RETRY 20 | ||
1588 | #define ASC_MAX_INIT_BUSY_RETRY 8 | ||
1589 | #define ASC_EEP_ISA_PNP_WSIZE 16 | ||
1590 | |||
1591 | /* | ||
1592 | * These macros keep the chip SCSI id and ISA DMA speed | ||
1593 | * bitfields in board order. C bitfields aren't portable | ||
1594 | * between big and little-endian platforms so they are | ||
1595 | * not used. | ||
1596 | */ | ||
1597 | |||
1598 | #define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f) | ||
1599 | #define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4) | ||
1600 | #define ASC_EEP_SET_CHIP_ID(cfg, sid) \ | ||
1601 | ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID)) | ||
1602 | #define ASC_EEP_SET_DMA_SPD(cfg, spd) \ | ||
1603 | ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4) | ||
1604 | |||
1605 | typedef struct asceep_config { | ||
1606 | ushort cfg_lsw; | ||
1607 | ushort cfg_msw; | ||
1608 | uchar init_sdtr; | ||
1609 | uchar disc_enable; | ||
1610 | uchar use_cmd_qng; | ||
1611 | uchar start_motor; | ||
1612 | uchar max_total_qng; | ||
1613 | uchar max_tag_qng; | ||
1614 | uchar bios_scan; | ||
1615 | uchar power_up_wait; | ||
1616 | uchar no_scam; | ||
1617 | uchar id_speed; /* low order 4 bits is chip scsi id */ | ||
1618 | /* high order 4 bits is isa dma speed */ | ||
1619 | uchar dos_int13_table[ASC_MAX_TID + 1]; | ||
1620 | uchar adapter_info[6]; | ||
1621 | ushort cntl; | ||
1622 | ushort chksum; | ||
1623 | } ASCEEP_CONFIG; | ||
1624 | |||
1625 | #define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800 | ||
1626 | #define ASC_PCI_CFG_LSW_BURST_MODE 0x0080 | ||
1627 | #define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020 | ||
1628 | |||
1629 | #define ASC_EEP_CMD_READ 0x80 | ||
1630 | #define ASC_EEP_CMD_WRITE 0x40 | ||
1631 | #define ASC_EEP_CMD_WRITE_ABLE 0x30 | ||
1632 | #define ASC_EEP_CMD_WRITE_DISABLE 0x00 | ||
1633 | #define ASC_OVERRUN_BSIZE 0x00000048UL | ||
1634 | #define ASC_CTRL_BREAK_ONCE 0x0001 | ||
1635 | #define ASC_CTRL_BREAK_STAY_IDLE 0x0002 | ||
1636 | #define ASCV_MSGOUT_BEG 0x0000 | ||
1637 | #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3) | ||
1638 | #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4) | ||
1639 | #define ASCV_BREAK_SAVED_CODE (ushort)0x0006 | ||
1640 | #define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8) | ||
1641 | #define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3) | ||
1642 | #define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4) | ||
1643 | #define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8) | ||
1644 | #define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8) | ||
1645 | #define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020 | ||
1646 | #define ASCV_BREAK_ADDR (ushort)0x0028 | ||
1647 | #define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A | ||
1648 | #define ASCV_BREAK_CONTROL (ushort)0x002C | ||
1649 | #define ASCV_BREAK_HIT_COUNT (ushort)0x002E | ||
1650 | |||
1651 | #define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030 | ||
1652 | #define ASCV_MCODE_CHKSUM_W (ushort)0x0032 | ||
1653 | #define ASCV_MCODE_SIZE_W (ushort)0x0034 | ||
1654 | #define ASCV_STOP_CODE_B (ushort)0x0036 | ||
1655 | #define ASCV_DVC_ERR_CODE_B (ushort)0x0037 | ||
1656 | #define ASCV_OVERRUN_PADDR_D (ushort)0x0038 | ||
1657 | #define ASCV_OVERRUN_BSIZE_D (ushort)0x003C | ||
1658 | #define ASCV_HALTCODE_W (ushort)0x0040 | ||
1659 | #define ASCV_CHKSUM_W (ushort)0x0042 | ||
1660 | #define ASCV_MC_DATE_W (ushort)0x0044 | ||
1661 | #define ASCV_MC_VER_W (ushort)0x0046 | ||
1662 | #define ASCV_NEXTRDY_B (ushort)0x0048 | ||
1663 | #define ASCV_DONENEXT_B (ushort)0x0049 | ||
1664 | #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A | ||
1665 | #define ASCV_SCSIBUSY_B (ushort)0x004B | ||
1666 | #define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C | ||
1667 | #define ASCV_CURCDB_B (ushort)0x004D | ||
1668 | #define ASCV_RCLUN_B (ushort)0x004E | ||
1669 | #define ASCV_BUSY_QHEAD_B (ushort)0x004F | ||
1670 | #define ASCV_DISC1_QHEAD_B (ushort)0x0050 | ||
1671 | #define ASCV_DISC_ENABLE_B (ushort)0x0052 | ||
1672 | #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053 | ||
1673 | #define ASCV_HOSTSCSI_ID_B (ushort)0x0055 | ||
1674 | #define ASCV_MCODE_CNTL_B (ushort)0x0056 | ||
1675 | #define ASCV_NULL_TARGET_B (ushort)0x0057 | ||
1676 | #define ASCV_FREE_Q_HEAD_W (ushort)0x0058 | ||
1677 | #define ASCV_DONE_Q_TAIL_W (ushort)0x005A | ||
1678 | #define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1) | ||
1679 | #define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1) | ||
1680 | #define ASCV_HOST_FLAG_B (ushort)0x005D | ||
1681 | #define ASCV_TOTAL_READY_Q_B (ushort)0x0064 | ||
1682 | #define ASCV_VER_SERIAL_B (ushort)0x0065 | ||
1683 | #define ASCV_HALTCODE_SAVED_W (ushort)0x0066 | ||
1684 | #define ASCV_WTM_FLAG_B (ushort)0x0068 | ||
1685 | #define ASCV_RISC_FLAG_B (ushort)0x006A | ||
1686 | #define ASCV_REQ_SG_LIST_QP (ushort)0x006B | ||
1687 | #define ASC_HOST_FLAG_IN_ISR 0x01 | ||
1688 | #define ASC_HOST_FLAG_ACK_INT 0x02 | ||
1689 | #define ASC_RISC_FLAG_GEN_INT 0x01 | ||
1690 | #define ASC_RISC_FLAG_REQ_SG_LIST 0x02 | ||
1691 | #define IOP_CTRL (0x0F) | ||
1692 | #define IOP_STATUS (0x0E) | ||
1693 | #define IOP_INT_ACK IOP_STATUS | ||
1694 | #define IOP_REG_IFC (0x0D) | ||
1695 | #define IOP_SYN_OFFSET (0x0B) | ||
1696 | #define IOP_EXTRA_CONTROL (0x0D) | ||
1697 | #define IOP_REG_PC (0x0C) | ||
1698 | #define IOP_RAM_ADDR (0x0A) | ||
1699 | #define IOP_RAM_DATA (0x08) | ||
1700 | #define IOP_EEP_DATA (0x06) | ||
1701 | #define IOP_EEP_CMD (0x07) | ||
1702 | #define IOP_VERSION (0x03) | ||
1703 | #define IOP_CONFIG_HIGH (0x04) | ||
1704 | #define IOP_CONFIG_LOW (0x02) | ||
1705 | #define IOP_SIG_BYTE (0x01) | ||
1706 | #define IOP_SIG_WORD (0x00) | ||
1707 | #define IOP_REG_DC1 (0x0E) | ||
1708 | #define IOP_REG_DC0 (0x0C) | ||
1709 | #define IOP_REG_SB (0x0B) | ||
1710 | #define IOP_REG_DA1 (0x0A) | ||
1711 | #define IOP_REG_DA0 (0x08) | ||
1712 | #define IOP_REG_SC (0x09) | ||
1713 | #define IOP_DMA_SPEED (0x07) | ||
1714 | #define IOP_REG_FLAG (0x07) | ||
1715 | #define IOP_FIFO_H (0x06) | ||
1716 | #define IOP_FIFO_L (0x04) | ||
1717 | #define IOP_REG_ID (0x05) | ||
1718 | #define IOP_REG_QP (0x03) | ||
1719 | #define IOP_REG_IH (0x02) | ||
1720 | #define IOP_REG_IX (0x01) | ||
1721 | #define IOP_REG_AX (0x00) | ||
1722 | #define IFC_REG_LOCK (0x00) | ||
1723 | #define IFC_REG_UNLOCK (0x09) | ||
1724 | #define IFC_WR_EN_FILTER (0x10) | ||
1725 | #define IFC_RD_NO_EEPROM (0x10) | ||
1726 | #define IFC_SLEW_RATE (0x20) | ||
1727 | #define IFC_ACT_NEG (0x40) | ||
1728 | #define IFC_INP_FILTER (0x80) | ||
1729 | #define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK) | ||
1730 | #define SC_SEL (uchar)(0x80) | ||
1731 | #define SC_BSY (uchar)(0x40) | ||
1732 | #define SC_ACK (uchar)(0x20) | ||
1733 | #define SC_REQ (uchar)(0x10) | ||
1734 | #define SC_ATN (uchar)(0x08) | ||
1735 | #define SC_IO (uchar)(0x04) | ||
1736 | #define SC_CD (uchar)(0x02) | ||
1737 | #define SC_MSG (uchar)(0x01) | ||
1738 | #define SEC_SCSI_CTL (uchar)(0x80) | ||
1739 | #define SEC_ACTIVE_NEGATE (uchar)(0x40) | ||
1740 | #define SEC_SLEW_RATE (uchar)(0x20) | ||
1741 | #define SEC_ENABLE_FILTER (uchar)(0x10) | ||
1742 | #define ASC_HALT_EXTMSG_IN (ushort)0x8000 | ||
1743 | #define ASC_HALT_CHK_CONDITION (ushort)0x8100 | ||
1744 | #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200 | ||
1745 | #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300 | ||
1746 | #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400 | ||
1747 | #define ASC_HALT_SDTR_REJECTED (ushort)0x4000 | ||
1748 | #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000 | ||
1749 | #define ASC_MAX_QNO 0xF8 | ||
1750 | #define ASC_DATA_SEC_BEG (ushort)0x0080 | ||
1751 | #define ASC_DATA_SEC_END (ushort)0x0080 | ||
1752 | #define ASC_CODE_SEC_BEG (ushort)0x0080 | ||
1753 | #define ASC_CODE_SEC_END (ushort)0x0080 | ||
1754 | #define ASC_QADR_BEG (0x4000) | ||
1755 | #define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64) | ||
1756 | #define ASC_QADR_END (ushort)0x7FFF | ||
1757 | #define ASC_QLAST_ADR (ushort)0x7FC0 | ||
1758 | #define ASC_QBLK_SIZE 0x40 | ||
1759 | #define ASC_BIOS_DATA_QBEG 0xF8 | ||
1760 | #define ASC_MIN_ACTIVE_QNO 0x01 | ||
1761 | #define ASC_QLINK_END 0xFF | ||
1762 | #define ASC_EEPROM_WORDS 0x10 | ||
1763 | #define ASC_MAX_MGS_LEN 0x10 | ||
1764 | #define ASC_BIOS_ADDR_DEF 0xDC00 | ||
1765 | #define ASC_BIOS_SIZE 0x3800 | ||
1766 | #define ASC_BIOS_RAM_OFF 0x3800 | ||
1767 | #define ASC_BIOS_RAM_SIZE 0x800 | ||
1768 | #define ASC_BIOS_MIN_ADDR 0xC000 | ||
1769 | #define ASC_BIOS_MAX_ADDR 0xEC00 | ||
1770 | #define ASC_BIOS_BANK_SIZE 0x0400 | ||
1771 | #define ASC_MCODE_START_ADDR 0x0080 | ||
1772 | #define ASC_CFG0_HOST_INT_ON 0x0020 | ||
1773 | #define ASC_CFG0_BIOS_ON 0x0040 | ||
1774 | #define ASC_CFG0_VERA_BURST_ON 0x0080 | ||
1775 | #define ASC_CFG0_SCSI_PARITY_ON 0x0800 | ||
1776 | #define ASC_CFG1_SCSI_TARGET_ON 0x0080 | ||
1777 | #define ASC_CFG1_LRAM_8BITS_ON 0x0800 | ||
1778 | #define ASC_CFG_MSW_CLR_MASK 0x3080 | ||
1779 | #define CSW_TEST1 (ASC_CS_TYPE)0x8000 | ||
1780 | #define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000 | ||
1781 | #define CSW_RESERVED1 (ASC_CS_TYPE)0x2000 | ||
1782 | #define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000 | ||
1783 | #define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800 | ||
1784 | #define CSW_TEST2 (ASC_CS_TYPE)0x0400 | ||
1785 | #define CSW_TEST3 (ASC_CS_TYPE)0x0200 | ||
1786 | #define CSW_RESERVED2 (ASC_CS_TYPE)0x0100 | ||
1787 | #define CSW_DMA_DONE (ASC_CS_TYPE)0x0080 | ||
1788 | #define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040 | ||
1789 | #define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020 | ||
1790 | #define CSW_HALTED (ASC_CS_TYPE)0x0010 | ||
1791 | #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008 | ||
1792 | #define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004 | ||
1793 | #define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002 | ||
1794 | #define CSW_INT_PENDING (ASC_CS_TYPE)0x0001 | ||
1795 | #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000 | ||
1796 | #define CIW_INT_ACK (ASC_CS_TYPE)0x0100 | ||
1797 | #define CIW_TEST1 (ASC_CS_TYPE)0x0200 | ||
1798 | #define CIW_TEST2 (ASC_CS_TYPE)0x0400 | ||
1799 | #define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800 | ||
1800 | #define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000 | ||
1801 | #define CC_CHIP_RESET (uchar)0x80 | ||
1802 | #define CC_SCSI_RESET (uchar)0x40 | ||
1803 | #define CC_HALT (uchar)0x20 | ||
1804 | #define CC_SINGLE_STEP (uchar)0x10 | ||
1805 | #define CC_DMA_ABLE (uchar)0x08 | ||
1806 | #define CC_TEST (uchar)0x04 | ||
1807 | #define CC_BANK_ONE (uchar)0x02 | ||
1808 | #define CC_DIAG (uchar)0x01 | ||
1809 | #define ASC_1000_ID0W 0x04C1 | ||
1810 | #define ASC_1000_ID0W_FIX 0x00C1 | ||
1811 | #define ASC_1000_ID1B 0x25 | ||
1812 | #define ASC_EISA_BIG_IOP_GAP (0x1C30-0x0C50) | ||
1813 | #define ASC_EISA_SMALL_IOP_GAP (0x0020) | ||
1814 | #define ASC_EISA_MIN_IOP_ADDR (0x0C30) | ||
1815 | #define ASC_EISA_MAX_IOP_ADDR (0xFC50) | ||
1816 | #define ASC_EISA_REV_IOP_MASK (0x0C83) | ||
1817 | #define ASC_EISA_PID_IOP_MASK (0x0C80) | ||
1818 | #define ASC_EISA_CFG_IOP_MASK (0x0C86) | ||
1819 | #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000) | ||
1820 | #define ASC_EISA_ID_740 0x01745004UL | ||
1821 | #define ASC_EISA_ID_750 0x01755004UL | ||
1822 | #define INS_HALTINT (ushort)0x6281 | ||
1823 | #define INS_HALT (ushort)0x6280 | ||
1824 | #define INS_SINT (ushort)0x6200 | ||
1825 | #define INS_RFLAG_WTM (ushort)0x7380 | ||
1826 | #define ASC_MC_SAVE_CODE_WSIZE 0x500 | ||
1827 | #define ASC_MC_SAVE_DATA_WSIZE 0x40 | ||
1828 | |||
1829 | typedef struct asc_mc_saved { | ||
1830 | ushort data[ASC_MC_SAVE_DATA_WSIZE]; | ||
1831 | ushort code[ASC_MC_SAVE_CODE_WSIZE]; | ||
1832 | } ASC_MC_SAVED; | ||
1833 | |||
1834 | #define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B) | ||
1835 | #define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val) | ||
1836 | #define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W) | ||
1837 | #define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W) | ||
1838 | #define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val) | ||
1839 | #define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val) | ||
1840 | #define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B) | ||
1841 | #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B) | ||
1842 | #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val) | ||
1843 | #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val) | ||
1844 | #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data)); | ||
1845 | #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id)); | ||
1846 | #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data); | ||
1847 | #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id)); | ||
1848 | #define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ]) | ||
1849 | #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE) | ||
1850 | #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD) | ||
1851 | #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION) | ||
1852 | #define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW) | ||
1853 | #define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH) | ||
1854 | #define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data) | ||
1855 | #define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data) | ||
1856 | #define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD) | ||
1857 | #define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data) | ||
1858 | #define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA) | ||
1859 | #define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data) | ||
1860 | #define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR)) | ||
1861 | #define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr) | ||
1862 | #define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA) | ||
1863 | #define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data) | ||
1864 | #define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC) | ||
1865 | #define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data) | ||
1866 | #define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS) | ||
1867 | #define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val) | ||
1868 | #define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL) | ||
1869 | #define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val) | ||
1870 | #define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET) | ||
1871 | #define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data) | ||
1872 | #define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data) | ||
1873 | #define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC) | ||
1874 | #define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH)) | ||
1875 | #define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID) | ||
1876 | #define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL) | ||
1877 | #define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data) | ||
1878 | #define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX) | ||
1879 | #define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data) | ||
1880 | #define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX) | ||
1881 | #define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data) | ||
1882 | #define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH) | ||
1883 | #define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data) | ||
1884 | #define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP) | ||
1885 | #define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data) | ||
1886 | #define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L) | ||
1887 | #define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data) | ||
1888 | #define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H) | ||
1889 | #define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data) | ||
1890 | #define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED) | ||
1891 | #define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data) | ||
1892 | #define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0) | ||
1893 | #define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data) | ||
1894 | #define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1) | ||
1895 | #define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data) | ||
1896 | #define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0) | ||
1897 | #define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data) | ||
1898 | #define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1) | ||
1899 | #define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data) | ||
1900 | #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID) | ||
1901 | #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data) | ||
1902 | |||
1903 | STATIC int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg); | ||
1904 | STATIC int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg); | ||
1905 | STATIC void AscWaitEEPRead(void); | ||
1906 | STATIC void AscWaitEEPWrite(void); | ||
1907 | STATIC ushort AscReadEEPWord(PortAddr, uchar); | ||
1908 | STATIC ushort AscWriteEEPWord(PortAddr, uchar, ushort); | ||
1909 | STATIC ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort); | ||
1910 | STATIC int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort); | ||
1911 | STATIC int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort); | ||
1912 | STATIC int AscStartChip(PortAddr); | ||
1913 | STATIC int AscStopChip(PortAddr); | ||
1914 | STATIC void AscSetChipIH(PortAddr, ushort); | ||
1915 | STATIC int AscIsChipHalted(PortAddr); | ||
1916 | STATIC void AscAckInterrupt(PortAddr); | ||
1917 | STATIC void AscDisableInterrupt(PortAddr); | ||
1918 | STATIC void AscEnableInterrupt(PortAddr); | ||
1919 | STATIC void AscSetBank(PortAddr, uchar); | ||
1920 | STATIC int AscResetChipAndScsiBus(ASC_DVC_VAR *); | ||
1921 | #ifdef CONFIG_ISA | ||
1922 | STATIC ushort AscGetIsaDmaChannel(PortAddr); | ||
1923 | STATIC ushort AscSetIsaDmaChannel(PortAddr, ushort); | ||
1924 | STATIC uchar AscSetIsaDmaSpeed(PortAddr, uchar); | ||
1925 | STATIC uchar AscGetIsaDmaSpeed(PortAddr); | ||
1926 | #endif /* CONFIG_ISA */ | ||
1927 | STATIC uchar AscReadLramByte(PortAddr, ushort); | ||
1928 | STATIC ushort AscReadLramWord(PortAddr, ushort); | ||
1929 | #if CC_VERY_LONG_SG_LIST | ||
1930 | STATIC ASC_DCNT AscReadLramDWord(PortAddr, ushort); | ||
1931 | #endif /* CC_VERY_LONG_SG_LIST */ | ||
1932 | STATIC void AscWriteLramWord(PortAddr, ushort, ushort); | ||
1933 | STATIC void AscWriteLramByte(PortAddr, ushort, uchar); | ||
1934 | STATIC ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int); | ||
1935 | STATIC void AscMemWordSetLram(PortAddr, ushort, ushort, int); | ||
1936 | STATIC void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int); | ||
1937 | STATIC void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int); | ||
1938 | STATIC void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int); | ||
1939 | STATIC ushort AscInitAscDvcVar(ASC_DVC_VAR *); | ||
1940 | STATIC ushort AscInitFromEEP(ASC_DVC_VAR *); | ||
1941 | STATIC ushort AscInitFromAscDvcVar(ASC_DVC_VAR *); | ||
1942 | STATIC ushort AscInitMicroCodeVar(ASC_DVC_VAR *); | ||
1943 | STATIC int AscTestExternalLram(ASC_DVC_VAR *); | ||
1944 | STATIC uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar); | ||
1945 | STATIC uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar); | ||
1946 | STATIC void AscSetChipSDTR(PortAddr, uchar, uchar); | ||
1947 | STATIC uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar); | ||
1948 | STATIC uchar AscAllocFreeQueue(PortAddr, uchar); | ||
1949 | STATIC uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar); | ||
1950 | STATIC int AscHostReqRiscHalt(PortAddr); | ||
1951 | STATIC int AscStopQueueExe(PortAddr); | ||
1952 | STATIC int AscSendScsiQueue(ASC_DVC_VAR *, | ||
1953 | ASC_SCSI_Q * scsiq, | ||
1954 | uchar n_q_required); | ||
1955 | STATIC int AscPutReadyQueue(ASC_DVC_VAR *, | ||
1956 | ASC_SCSI_Q *, uchar); | ||
1957 | STATIC int AscPutReadySgListQueue(ASC_DVC_VAR *, | ||
1958 | ASC_SCSI_Q *, uchar); | ||
1959 | STATIC int AscSetChipSynRegAtID(PortAddr, uchar, uchar); | ||
1960 | STATIC int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar); | ||
1961 | STATIC ushort AscInitLram(ASC_DVC_VAR *); | ||
1962 | STATIC ushort AscInitQLinkVar(ASC_DVC_VAR *); | ||
1963 | STATIC int AscSetLibErrorCode(ASC_DVC_VAR *, ushort); | ||
1964 | STATIC int AscIsrChipHalted(ASC_DVC_VAR *); | ||
1965 | STATIC uchar _AscCopyLramScsiDoneQ(PortAddr, ushort, | ||
1966 | ASC_QDONE_INFO *, ASC_DCNT); | ||
1967 | STATIC int AscIsrQDone(ASC_DVC_VAR *); | ||
1968 | STATIC int AscCompareString(uchar *, uchar *, int); | ||
1969 | #ifdef CONFIG_ISA | ||
1970 | STATIC ushort AscGetEisaChipCfg(PortAddr); | ||
1971 | STATIC ASC_DCNT AscGetEisaProductID(PortAddr); | ||
1972 | STATIC PortAddr AscSearchIOPortAddrEISA(PortAddr); | ||
1973 | STATIC PortAddr AscSearchIOPortAddr11(PortAddr); | ||
1974 | STATIC PortAddr AscSearchIOPortAddr(PortAddr, ushort); | ||
1975 | STATIC void AscSetISAPNPWaitForKey(void); | ||
1976 | #endif /* CONFIG_ISA */ | ||
1977 | STATIC uchar AscGetChipScsiCtrl(PortAddr); | ||
1978 | STATIC uchar AscSetChipScsiID(PortAddr, uchar); | ||
1979 | STATIC uchar AscGetChipVersion(PortAddr, ushort); | ||
1980 | STATIC ushort AscGetChipBusType(PortAddr); | ||
1981 | STATIC ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort); | ||
1982 | STATIC int AscFindSignature(PortAddr); | ||
1983 | STATIC void AscToggleIRQAct(PortAddr); | ||
1984 | STATIC uchar AscGetChipIRQ(PortAddr, ushort); | ||
1985 | STATIC uchar AscSetChipIRQ(PortAddr, uchar, ushort); | ||
1986 | STATIC ushort AscGetChipBiosAddress(PortAddr, ushort); | ||
1987 | STATIC inline ulong DvcEnterCritical(void); | ||
1988 | STATIC inline void DvcLeaveCritical(ulong); | ||
1989 | #ifdef CONFIG_PCI | ||
1990 | STATIC uchar DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort); | ||
1991 | STATIC void DvcWritePCIConfigByte(ASC_DVC_VAR *, | ||
1992 | ushort, uchar); | ||
1993 | #endif /* CONFIG_PCI */ | ||
1994 | STATIC ushort AscGetChipBiosAddress(PortAddr, ushort); | ||
1995 | STATIC void DvcSleepMilliSecond(ASC_DCNT); | ||
1996 | STATIC void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT); | ||
1997 | STATIC void DvcPutScsiQ(PortAddr, ushort, uchar *, int); | ||
1998 | STATIC void DvcGetQinfo(PortAddr, ushort, uchar *, int); | ||
1999 | STATIC ushort AscInitGetConfig(ASC_DVC_VAR *); | ||
2000 | STATIC ushort AscInitSetConfig(ASC_DVC_VAR *); | ||
2001 | STATIC ushort AscInitAsc1000Driver(ASC_DVC_VAR *); | ||
2002 | STATIC void AscAsyncFix(ASC_DVC_VAR *, uchar, | ||
2003 | ASC_SCSI_INQUIRY *); | ||
2004 | STATIC int AscTagQueuingSafe(ASC_SCSI_INQUIRY *); | ||
2005 | STATIC void AscInquiryHandling(ASC_DVC_VAR *, | ||
2006 | uchar, ASC_SCSI_INQUIRY *); | ||
2007 | STATIC int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *); | ||
2008 | STATIC int AscISR(ASC_DVC_VAR *); | ||
2009 | STATIC uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, | ||
2010 | uchar); | ||
2011 | STATIC int AscSgListToQueue(int); | ||
2012 | #ifdef CONFIG_ISA | ||
2013 | STATIC void AscEnableIsaDma(uchar); | ||
2014 | #endif /* CONFIG_ISA */ | ||
2015 | STATIC ASC_DCNT AscGetMaxDmaCount(ushort); | ||
2016 | |||
2017 | |||
2018 | /* | ||
2019 | * --- Adv Library Constants and Macros | ||
2020 | */ | ||
2021 | |||
2022 | #define ADV_LIB_VERSION_MAJOR 5 | ||
2023 | #define ADV_LIB_VERSION_MINOR 14 | ||
2024 | |||
2025 | /* | ||
2026 | * Define Adv Library required special types. | ||
2027 | */ | ||
2028 | |||
2029 | /* | ||
2030 | * Portable Data Types | ||
2031 | * | ||
2032 | * Any instance where a 32-bit long or pointer type is assumed | ||
2033 | * for precision or HW defined structures, the following define | ||
2034 | * types must be used. In Linux the char, short, and int types | ||
2035 | * are all consistent at 8, 16, and 32 bits respectively. Pointers | ||
2036 | * and long types are 64 bits on Alpha and UltraSPARC. | ||
2037 | */ | ||
2038 | #define ADV_PADDR __u32 /* Physical address data type. */ | ||
2039 | #define ADV_VADDR __u32 /* Virtual address data type. */ | ||
2040 | #define ADV_DCNT __u32 /* Unsigned Data count type. */ | ||
2041 | #define ADV_SDCNT __s32 /* Signed Data count type. */ | ||
2042 | |||
2043 | /* | ||
2044 | * These macros are used to convert a virtual address to a | ||
2045 | * 32-bit value. This currently can be used on Linux Alpha | ||
2046 | * which uses 64-bit virtual address but a 32-bit bus address. | ||
2047 | * This is likely to break in the future, but doing this now | ||
2048 | * will give us time to change the HW and FW to handle 64-bit | ||
2049 | * addresses. | ||
2050 | */ | ||
2051 | #define ADV_VADDR_TO_U32 virt_to_bus | ||
2052 | #define ADV_U32_TO_VADDR bus_to_virt | ||
2053 | |||
2054 | #define AdvPortAddr ulong /* Virtual memory address size */ | ||
2055 | |||
2056 | /* | ||
2057 | * Define Adv Library required memory access macros. | ||
2058 | */ | ||
2059 | #define ADV_MEM_READB(addr) readb(addr) | ||
2060 | #define ADV_MEM_READW(addr) readw(addr) | ||
2061 | #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr) | ||
2062 | #define ADV_MEM_WRITEW(addr, word) writew(word, addr) | ||
2063 | #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr) | ||
2064 | |||
2065 | #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15) | ||
2066 | |||
2067 | /* | ||
2068 | * For wide boards a CDB length maximum of 16 bytes | ||
2069 | * is supported. | ||
2070 | */ | ||
2071 | #define ADV_MAX_CDB_LEN 16 | ||
2072 | |||
2073 | /* | ||
2074 | * Define total number of simultaneous maximum element scatter-gather | ||
2075 | * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the | ||
2076 | * maximum number of outstanding commands per wide host adapter. Each | ||
2077 | * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather | ||
2078 | * elements. Allow each command to have at least one ADV_SG_BLOCK structure. | ||
2079 | * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK | ||
2080 | * structures or 255 scatter-gather elements. | ||
2081 | * | ||
2082 | */ | ||
2083 | #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG | ||
2084 | |||
2085 | /* | ||
2086 | * Define Adv Library required maximum number of scatter-gather | ||
2087 | * elements per request. | ||
2088 | */ | ||
2089 | #define ADV_MAX_SG_LIST 255 | ||
2090 | |||
2091 | /* Number of SG blocks needed. */ | ||
2092 | #define ADV_NUM_SG_BLOCK \ | ||
2093 | ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK) | ||
2094 | |||
2095 | /* Total contiguous memory needed for SG blocks. */ | ||
2096 | #define ADV_SG_TOTAL_MEM_SIZE \ | ||
2097 | (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK) | ||
2098 | |||
2099 | #define ADV_PAGE_SIZE PAGE_SIZE | ||
2100 | |||
2101 | #define ADV_NUM_PAGE_CROSSING \ | ||
2102 | ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE) | ||
2103 | |||
2104 | /* a_condor.h */ | ||
2105 | #define ADV_PCI_VENDOR_ID 0x10CD | ||
2106 | #define ADV_PCI_DEVICE_ID_REV_A 0x2300 | ||
2107 | #define ADV_PCI_DEVID_38C0800_REV1 0x2500 | ||
2108 | #define ADV_PCI_DEVID_38C1600_REV1 0x2700 | ||
2109 | |||
2110 | #define ADV_EEP_DVC_CFG_BEGIN (0x00) | ||
2111 | #define ADV_EEP_DVC_CFG_END (0x15) | ||
2112 | #define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */ | ||
2113 | #define ADV_EEP_MAX_WORD_ADDR (0x1E) | ||
2114 | |||
2115 | #define ADV_EEP_DELAY_MS 100 | ||
2116 | |||
2117 | #define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */ | ||
2118 | #define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */ | ||
2119 | /* | ||
2120 | * For the ASC3550 Bit 13 is Termination Polarity control bit. | ||
2121 | * For later ICs Bit 13 controls whether the CIS (Card Information | ||
2122 | * Service Section) is loaded from EEPROM. | ||
2123 | */ | ||
2124 | #define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */ | ||
2125 | #define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */ | ||
2126 | /* | ||
2127 | * ASC38C1600 Bit 11 | ||
2128 | * | ||
2129 | * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify | ||
2130 | * INT A in the PCI Configuration Space Int Pin field. If it is 1, then | ||
2131 | * Function 0 will specify INT B. | ||
2132 | * | ||
2133 | * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify | ||
2134 | * INT B in the PCI Configuration Space Int Pin field. If it is 1, then | ||
2135 | * Function 1 will specify INT A. | ||
2136 | */ | ||
2137 | #define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */ | ||
2138 | |||
2139 | typedef struct adveep_3550_config | ||
2140 | { | ||
2141 | /* Word Offset, Description */ | ||
2142 | |||
2143 | ushort cfg_lsw; /* 00 power up initialization */ | ||
2144 | /* bit 13 set - Term Polarity Control */ | ||
2145 | /* bit 14 set - BIOS Enable */ | ||
2146 | /* bit 15 set - Big Endian Mode */ | ||
2147 | ushort cfg_msw; /* 01 unused */ | ||
2148 | ushort disc_enable; /* 02 disconnect enable */ | ||
2149 | ushort wdtr_able; /* 03 Wide DTR able */ | ||
2150 | ushort sdtr_able; /* 04 Synchronous DTR able */ | ||
2151 | ushort start_motor; /* 05 send start up motor */ | ||
2152 | ushort tagqng_able; /* 06 tag queuing able */ | ||
2153 | ushort bios_scan; /* 07 BIOS device control */ | ||
2154 | ushort scam_tolerant; /* 08 no scam */ | ||
2155 | |||
2156 | uchar adapter_scsi_id; /* 09 Host Adapter ID */ | ||
2157 | uchar bios_boot_delay; /* power up wait */ | ||
2158 | |||
2159 | uchar scsi_reset_delay; /* 10 reset delay */ | ||
2160 | uchar bios_id_lun; /* first boot device scsi id & lun */ | ||
2161 | /* high nibble is lun */ | ||
2162 | /* low nibble is scsi id */ | ||
2163 | |||
2164 | uchar termination; /* 11 0 - automatic */ | ||
2165 | /* 1 - low off / high off */ | ||
2166 | /* 2 - low off / high on */ | ||
2167 | /* 3 - low on / high on */ | ||
2168 | /* There is no low on / high off */ | ||
2169 | |||
2170 | uchar reserved1; /* reserved byte (not used) */ | ||
2171 | |||
2172 | ushort bios_ctrl; /* 12 BIOS control bits */ | ||
2173 | /* bit 0 BIOS don't act as initiator. */ | ||
2174 | /* bit 1 BIOS > 1 GB support */ | ||
2175 | /* bit 2 BIOS > 2 Disk Support */ | ||
2176 | /* bit 3 BIOS don't support removables */ | ||
2177 | /* bit 4 BIOS support bootable CD */ | ||
2178 | /* bit 5 BIOS scan enabled */ | ||
2179 | /* bit 6 BIOS support multiple LUNs */ | ||
2180 | /* bit 7 BIOS display of message */ | ||
2181 | /* bit 8 SCAM disabled */ | ||
2182 | /* bit 9 Reset SCSI bus during init. */ | ||
2183 | /* bit 10 */ | ||
2184 | /* bit 11 No verbose initialization. */ | ||
2185 | /* bit 12 SCSI parity enabled */ | ||
2186 | /* bit 13 */ | ||
2187 | /* bit 14 */ | ||
2188 | /* bit 15 */ | ||
2189 | ushort ultra_able; /* 13 ULTRA speed able */ | ||
2190 | ushort reserved2; /* 14 reserved */ | ||
2191 | uchar max_host_qng; /* 15 maximum host queuing */ | ||
2192 | uchar max_dvc_qng; /* maximum per device queuing */ | ||
2193 | ushort dvc_cntl; /* 16 control bit for driver */ | ||
2194 | ushort bug_fix; /* 17 control bit for bug fix */ | ||
2195 | ushort serial_number_word1; /* 18 Board serial number word 1 */ | ||
2196 | ushort serial_number_word2; /* 19 Board serial number word 2 */ | ||
2197 | ushort serial_number_word3; /* 20 Board serial number word 3 */ | ||
2198 | ushort check_sum; /* 21 EEP check sum */ | ||
2199 | uchar oem_name[16]; /* 22 OEM name */ | ||
2200 | ushort dvc_err_code; /* 30 last device driver error code */ | ||
2201 | ushort adv_err_code; /* 31 last uc and Adv Lib error code */ | ||
2202 | ushort adv_err_addr; /* 32 last uc error address */ | ||
2203 | ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */ | ||
2204 | ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */ | ||
2205 | ushort saved_adv_err_addr; /* 35 saved last uc error address */ | ||
2206 | ushort num_of_err; /* 36 number of error */ | ||
2207 | } ADVEEP_3550_CONFIG; | ||
2208 | |||
2209 | typedef struct adveep_38C0800_config | ||
2210 | { | ||
2211 | /* Word Offset, Description */ | ||
2212 | |||
2213 | ushort cfg_lsw; /* 00 power up initialization */ | ||
2214 | /* bit 13 set - Load CIS */ | ||
2215 | /* bit 14 set - BIOS Enable */ | ||
2216 | /* bit 15 set - Big Endian Mode */ | ||
2217 | ushort cfg_msw; /* 01 unused */ | ||
2218 | ushort disc_enable; /* 02 disconnect enable */ | ||
2219 | ushort wdtr_able; /* 03 Wide DTR able */ | ||
2220 | ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */ | ||
2221 | ushort start_motor; /* 05 send start up motor */ | ||
2222 | ushort tagqng_able; /* 06 tag queuing able */ | ||
2223 | ushort bios_scan; /* 07 BIOS device control */ | ||
2224 | ushort scam_tolerant; /* 08 no scam */ | ||
2225 | |||
2226 | uchar adapter_scsi_id; /* 09 Host Adapter ID */ | ||
2227 | uchar bios_boot_delay; /* power up wait */ | ||
2228 | |||
2229 | uchar scsi_reset_delay; /* 10 reset delay */ | ||
2230 | uchar bios_id_lun; /* first boot device scsi id & lun */ | ||
2231 | /* high nibble is lun */ | ||
2232 | /* low nibble is scsi id */ | ||
2233 | |||
2234 | uchar termination_se; /* 11 0 - automatic */ | ||
2235 | /* 1 - low off / high off */ | ||
2236 | /* 2 - low off / high on */ | ||
2237 | /* 3 - low on / high on */ | ||
2238 | /* There is no low on / high off */ | ||
2239 | |||
2240 | uchar termination_lvd; /* 11 0 - automatic */ | ||
2241 | /* 1 - low off / high off */ | ||
2242 | /* 2 - low off / high on */ | ||
2243 | /* 3 - low on / high on */ | ||
2244 | /* There is no low on / high off */ | ||
2245 | |||
2246 | ushort bios_ctrl; /* 12 BIOS control bits */ | ||
2247 | /* bit 0 BIOS don't act as initiator. */ | ||
2248 | /* bit 1 BIOS > 1 GB support */ | ||
2249 | /* bit 2 BIOS > 2 Disk Support */ | ||
2250 | /* bit 3 BIOS don't support removables */ | ||
2251 | /* bit 4 BIOS support bootable CD */ | ||
2252 | /* bit 5 BIOS scan enabled */ | ||
2253 | /* bit 6 BIOS support multiple LUNs */ | ||
2254 | /* bit 7 BIOS display of message */ | ||
2255 | /* bit 8 SCAM disabled */ | ||
2256 | /* bit 9 Reset SCSI bus during init. */ | ||
2257 | /* bit 10 */ | ||
2258 | /* bit 11 No verbose initialization. */ | ||
2259 | /* bit 12 SCSI parity enabled */ | ||
2260 | /* bit 13 */ | ||
2261 | /* bit 14 */ | ||
2262 | /* bit 15 */ | ||
2263 | ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */ | ||
2264 | ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */ | ||
2265 | uchar max_host_qng; /* 15 maximum host queueing */ | ||
2266 | uchar max_dvc_qng; /* maximum per device queuing */ | ||
2267 | ushort dvc_cntl; /* 16 control bit for driver */ | ||
2268 | ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */ | ||
2269 | ushort serial_number_word1; /* 18 Board serial number word 1 */ | ||
2270 | ushort serial_number_word2; /* 19 Board serial number word 2 */ | ||
2271 | ushort serial_number_word3; /* 20 Board serial number word 3 */ | ||
2272 | ushort check_sum; /* 21 EEP check sum */ | ||
2273 | uchar oem_name[16]; /* 22 OEM name */ | ||
2274 | ushort dvc_err_code; /* 30 last device driver error code */ | ||
2275 | ushort adv_err_code; /* 31 last uc and Adv Lib error code */ | ||
2276 | ushort adv_err_addr; /* 32 last uc error address */ | ||
2277 | ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */ | ||
2278 | ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */ | ||
2279 | ushort saved_adv_err_addr; /* 35 saved last uc error address */ | ||
2280 | ushort reserved36; /* 36 reserved */ | ||
2281 | ushort reserved37; /* 37 reserved */ | ||
2282 | ushort reserved38; /* 38 reserved */ | ||
2283 | ushort reserved39; /* 39 reserved */ | ||
2284 | ushort reserved40; /* 40 reserved */ | ||
2285 | ushort reserved41; /* 41 reserved */ | ||
2286 | ushort reserved42; /* 42 reserved */ | ||
2287 | ushort reserved43; /* 43 reserved */ | ||
2288 | ushort reserved44; /* 44 reserved */ | ||
2289 | ushort reserved45; /* 45 reserved */ | ||
2290 | ushort reserved46; /* 46 reserved */ | ||
2291 | ushort reserved47; /* 47 reserved */ | ||
2292 | ushort reserved48; /* 48 reserved */ | ||
2293 | ushort reserved49; /* 49 reserved */ | ||
2294 | ushort reserved50; /* 50 reserved */ | ||
2295 | ushort reserved51; /* 51 reserved */ | ||
2296 | ushort reserved52; /* 52 reserved */ | ||
2297 | ushort reserved53; /* 53 reserved */ | ||
2298 | ushort reserved54; /* 54 reserved */ | ||
2299 | ushort reserved55; /* 55 reserved */ | ||
2300 | ushort cisptr_lsw; /* 56 CIS PTR LSW */ | ||
2301 | ushort cisprt_msw; /* 57 CIS PTR MSW */ | ||
2302 | ushort subsysvid; /* 58 SubSystem Vendor ID */ | ||
2303 | ushort subsysid; /* 59 SubSystem ID */ | ||
2304 | ushort reserved60; /* 60 reserved */ | ||
2305 | ushort reserved61; /* 61 reserved */ | ||
2306 | ushort reserved62; /* 62 reserved */ | ||
2307 | ushort reserved63; /* 63 reserved */ | ||
2308 | } ADVEEP_38C0800_CONFIG; | ||
2309 | |||
2310 | typedef struct adveep_38C1600_config | ||
2311 | { | ||
2312 | /* Word Offset, Description */ | ||
2313 | |||
2314 | ushort cfg_lsw; /* 00 power up initialization */ | ||
2315 | /* bit 11 set - Func. 0 INTB, Func. 1 INTA */ | ||
2316 | /* clear - Func. 0 INTA, Func. 1 INTB */ | ||
2317 | /* bit 13 set - Load CIS */ | ||
2318 | /* bit 14 set - BIOS Enable */ | ||
2319 | /* bit 15 set - Big Endian Mode */ | ||
2320 | ushort cfg_msw; /* 01 unused */ | ||
2321 | ushort disc_enable; /* 02 disconnect enable */ | ||
2322 | ushort wdtr_able; /* 03 Wide DTR able */ | ||
2323 | ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */ | ||
2324 | ushort start_motor; /* 05 send start up motor */ | ||
2325 | ushort tagqng_able; /* 06 tag queuing able */ | ||
2326 | ushort bios_scan; /* 07 BIOS device control */ | ||
2327 | ushort scam_tolerant; /* 08 no scam */ | ||
2328 | |||
2329 | uchar adapter_scsi_id; /* 09 Host Adapter ID */ | ||
2330 | uchar bios_boot_delay; /* power up wait */ | ||
2331 | |||
2332 | uchar scsi_reset_delay; /* 10 reset delay */ | ||
2333 | uchar bios_id_lun; /* first boot device scsi id & lun */ | ||
2334 | /* high nibble is lun */ | ||
2335 | /* low nibble is scsi id */ | ||
2336 | |||
2337 | uchar termination_se; /* 11 0 - automatic */ | ||
2338 | /* 1 - low off / high off */ | ||
2339 | /* 2 - low off / high on */ | ||
2340 | /* 3 - low on / high on */ | ||
2341 | /* There is no low on / high off */ | ||
2342 | |||
2343 | uchar termination_lvd; /* 11 0 - automatic */ | ||
2344 | /* 1 - low off / high off */ | ||
2345 | /* 2 - low off / high on */ | ||
2346 | /* 3 - low on / high on */ | ||
2347 | /* There is no low on / high off */ | ||
2348 | |||
2349 | ushort bios_ctrl; /* 12 BIOS control bits */ | ||
2350 | /* bit 0 BIOS don't act as initiator. */ | ||
2351 | /* bit 1 BIOS > 1 GB support */ | ||
2352 | /* bit 2 BIOS > 2 Disk Support */ | ||
2353 | /* bit 3 BIOS don't support removables */ | ||
2354 | /* bit 4 BIOS support bootable CD */ | ||
2355 | /* bit 5 BIOS scan enabled */ | ||
2356 | /* bit 6 BIOS support multiple LUNs */ | ||
2357 | /* bit 7 BIOS display of message */ | ||
2358 | /* bit 8 SCAM disabled */ | ||
2359 | /* bit 9 Reset SCSI bus during init. */ | ||
2360 | /* bit 10 Basic Integrity Checking disabled */ | ||
2361 | /* bit 11 No verbose initialization. */ | ||
2362 | /* bit 12 SCSI parity enabled */ | ||
2363 | /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */ | ||
2364 | /* bit 14 */ | ||
2365 | /* bit 15 */ | ||
2366 | ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */ | ||
2367 | ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */ | ||
2368 | uchar max_host_qng; /* 15 maximum host queueing */ | ||
2369 | uchar max_dvc_qng; /* maximum per device queuing */ | ||
2370 | ushort dvc_cntl; /* 16 control bit for driver */ | ||
2371 | ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */ | ||
2372 | ushort serial_number_word1; /* 18 Board serial number word 1 */ | ||
2373 | ushort serial_number_word2; /* 19 Board serial number word 2 */ | ||
2374 | ushort serial_number_word3; /* 20 Board serial number word 3 */ | ||
2375 | ushort check_sum; /* 21 EEP check sum */ | ||
2376 | uchar oem_name[16]; /* 22 OEM name */ | ||
2377 | ushort dvc_err_code; /* 30 last device driver error code */ | ||
2378 | ushort adv_err_code; /* 31 last uc and Adv Lib error code */ | ||
2379 | ushort adv_err_addr; /* 32 last uc error address */ | ||
2380 | ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */ | ||
2381 | ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */ | ||
2382 | ushort saved_adv_err_addr; /* 35 saved last uc error address */ | ||
2383 | ushort reserved36; /* 36 reserved */ | ||
2384 | ushort reserved37; /* 37 reserved */ | ||
2385 | ushort reserved38; /* 38 reserved */ | ||
2386 | ushort reserved39; /* 39 reserved */ | ||
2387 | ushort reserved40; /* 40 reserved */ | ||
2388 | ushort reserved41; /* 41 reserved */ | ||
2389 | ushort reserved42; /* 42 reserved */ | ||
2390 | ushort reserved43; /* 43 reserved */ | ||
2391 | ushort reserved44; /* 44 reserved */ | ||
2392 | ushort reserved45; /* 45 reserved */ | ||
2393 | ushort reserved46; /* 46 reserved */ | ||
2394 | ushort reserved47; /* 47 reserved */ | ||
2395 | ushort reserved48; /* 48 reserved */ | ||
2396 | ushort reserved49; /* 49 reserved */ | ||
2397 | ushort reserved50; /* 50 reserved */ | ||
2398 | ushort reserved51; /* 51 reserved */ | ||
2399 | ushort reserved52; /* 52 reserved */ | ||
2400 | ushort reserved53; /* 53 reserved */ | ||
2401 | ushort reserved54; /* 54 reserved */ | ||
2402 | ushort reserved55; /* 55 reserved */ | ||
2403 | ushort cisptr_lsw; /* 56 CIS PTR LSW */ | ||
2404 | ushort cisprt_msw; /* 57 CIS PTR MSW */ | ||
2405 | ushort subsysvid; /* 58 SubSystem Vendor ID */ | ||
2406 | ushort subsysid; /* 59 SubSystem ID */ | ||
2407 | ushort reserved60; /* 60 reserved */ | ||
2408 | ushort reserved61; /* 61 reserved */ | ||
2409 | ushort reserved62; /* 62 reserved */ | ||
2410 | ushort reserved63; /* 63 reserved */ | ||
2411 | } ADVEEP_38C1600_CONFIG; | ||
2412 | |||
2413 | /* | ||
2414 | * EEPROM Commands | ||
2415 | */ | ||
2416 | #define ASC_EEP_CMD_DONE 0x0200 | ||
2417 | #define ASC_EEP_CMD_DONE_ERR 0x0001 | ||
2418 | |||
2419 | /* cfg_word */ | ||
2420 | #define EEP_CFG_WORD_BIG_ENDIAN 0x8000 | ||
2421 | |||
2422 | /* bios_ctrl */ | ||
2423 | #define BIOS_CTRL_BIOS 0x0001 | ||
2424 | #define BIOS_CTRL_EXTENDED_XLAT 0x0002 | ||
2425 | #define BIOS_CTRL_GT_2_DISK 0x0004 | ||
2426 | #define BIOS_CTRL_BIOS_REMOVABLE 0x0008 | ||
2427 | #define BIOS_CTRL_BOOTABLE_CD 0x0010 | ||
2428 | #define BIOS_CTRL_MULTIPLE_LUN 0x0040 | ||
2429 | #define BIOS_CTRL_DISPLAY_MSG 0x0080 | ||
2430 | #define BIOS_CTRL_NO_SCAM 0x0100 | ||
2431 | #define BIOS_CTRL_RESET_SCSI_BUS 0x0200 | ||
2432 | #define BIOS_CTRL_INIT_VERBOSE 0x0800 | ||
2433 | #define BIOS_CTRL_SCSI_PARITY 0x1000 | ||
2434 | #define BIOS_CTRL_AIPP_DIS 0x2000 | ||
2435 | |||
2436 | #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */ | ||
2437 | #define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */ | ||
2438 | |||
2439 | #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */ | ||
2440 | #define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */ | ||
2441 | |||
2442 | /* | ||
2443 | * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is | ||
2444 | * a special 16K Adv Library and Microcode version. After the issue is | ||
2445 | * resolved, should restore 32K support. | ||
2446 | * | ||
2447 | * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory * | ||
2448 | */ | ||
2449 | #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */ | ||
2450 | #define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */ | ||
2451 | #define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */ | ||
2452 | |||
2453 | /* | ||
2454 | * Byte I/O register address from base of 'iop_base'. | ||
2455 | */ | ||
2456 | #define IOPB_INTR_STATUS_REG 0x00 | ||
2457 | #define IOPB_CHIP_ID_1 0x01 | ||
2458 | #define IOPB_INTR_ENABLES 0x02 | ||
2459 | #define IOPB_CHIP_TYPE_REV 0x03 | ||
2460 | #define IOPB_RES_ADDR_4 0x04 | ||
2461 | #define IOPB_RES_ADDR_5 0x05 | ||
2462 | #define IOPB_RAM_DATA 0x06 | ||
2463 | #define IOPB_RES_ADDR_7 0x07 | ||
2464 | #define IOPB_FLAG_REG 0x08 | ||
2465 | #define IOPB_RES_ADDR_9 0x09 | ||
2466 | #define IOPB_RISC_CSR 0x0A | ||
2467 | #define IOPB_RES_ADDR_B 0x0B | ||
2468 | #define IOPB_RES_ADDR_C 0x0C | ||
2469 | #define IOPB_RES_ADDR_D 0x0D | ||
2470 | #define IOPB_SOFT_OVER_WR 0x0E | ||
2471 | #define IOPB_RES_ADDR_F 0x0F | ||
2472 | #define IOPB_MEM_CFG 0x10 | ||
2473 | #define IOPB_RES_ADDR_11 0x11 | ||
2474 | #define IOPB_GPIO_DATA 0x12 | ||
2475 | #define IOPB_RES_ADDR_13 0x13 | ||
2476 | #define IOPB_FLASH_PAGE 0x14 | ||
2477 | #define IOPB_RES_ADDR_15 0x15 | ||
2478 | #define IOPB_GPIO_CNTL 0x16 | ||
2479 | #define IOPB_RES_ADDR_17 0x17 | ||
2480 | #define IOPB_FLASH_DATA 0x18 | ||
2481 | #define IOPB_RES_ADDR_19 0x19 | ||
2482 | #define IOPB_RES_ADDR_1A 0x1A | ||
2483 | #define IOPB_RES_ADDR_1B 0x1B | ||
2484 | #define IOPB_RES_ADDR_1C 0x1C | ||
2485 | #define IOPB_RES_ADDR_1D 0x1D | ||
2486 | #define IOPB_RES_ADDR_1E 0x1E | ||
2487 | #define IOPB_RES_ADDR_1F 0x1F | ||
2488 | #define IOPB_DMA_CFG0 0x20 | ||
2489 | #define IOPB_DMA_CFG1 0x21 | ||
2490 | #define IOPB_TICKLE 0x22 | ||
2491 | #define IOPB_DMA_REG_WR 0x23 | ||
2492 | #define IOPB_SDMA_STATUS 0x24 | ||
2493 | #define IOPB_SCSI_BYTE_CNT 0x25 | ||
2494 | #define IOPB_HOST_BYTE_CNT 0x26 | ||
2495 | #define IOPB_BYTE_LEFT_TO_XFER 0x27 | ||
2496 | #define IOPB_BYTE_TO_XFER_0 0x28 | ||
2497 | #define IOPB_BYTE_TO_XFER_1 0x29 | ||
2498 | #define IOPB_BYTE_TO_XFER_2 0x2A | ||
2499 | #define IOPB_BYTE_TO_XFER_3 0x2B | ||
2500 | #define IOPB_ACC_GRP 0x2C | ||
2501 | #define IOPB_RES_ADDR_2D 0x2D | ||
2502 | #define IOPB_DEV_ID 0x2E | ||
2503 | #define IOPB_RES_ADDR_2F 0x2F | ||
2504 | #define IOPB_SCSI_DATA 0x30 | ||
2505 | #define IOPB_RES_ADDR_31 0x31 | ||
2506 | #define IOPB_RES_ADDR_32 0x32 | ||
2507 | #define IOPB_SCSI_DATA_HSHK 0x33 | ||
2508 | #define IOPB_SCSI_CTRL 0x34 | ||
2509 | #define IOPB_RES_ADDR_35 0x35 | ||
2510 | #define IOPB_RES_ADDR_36 0x36 | ||
2511 | #define IOPB_RES_ADDR_37 0x37 | ||
2512 | #define IOPB_RAM_BIST 0x38 | ||
2513 | #define IOPB_PLL_TEST 0x39 | ||
2514 | #define IOPB_PCI_INT_CFG 0x3A | ||
2515 | #define IOPB_RES_ADDR_3B 0x3B | ||
2516 | #define IOPB_RFIFO_CNT 0x3C | ||
2517 | #define IOPB_RES_ADDR_3D 0x3D | ||
2518 | #define IOPB_RES_ADDR_3E 0x3E | ||
2519 | #define IOPB_RES_ADDR_3F 0x3F | ||
2520 | |||
2521 | /* | ||
2522 | * Word I/O register address from base of 'iop_base'. | ||
2523 | */ | ||
2524 | #define IOPW_CHIP_ID_0 0x00 /* CID0 */ | ||
2525 | #define IOPW_CTRL_REG 0x02 /* CC */ | ||
2526 | #define IOPW_RAM_ADDR 0x04 /* LA */ | ||
2527 | #define IOPW_RAM_DATA 0x06 /* LD */ | ||
2528 | #define IOPW_RES_ADDR_08 0x08 | ||
2529 | #define IOPW_RISC_CSR 0x0A /* CSR */ | ||
2530 | #define IOPW_SCSI_CFG0 0x0C /* CFG0 */ | ||
2531 | #define IOPW_SCSI_CFG1 0x0E /* CFG1 */ | ||
2532 | #define IOPW_RES_ADDR_10 0x10 | ||
2533 | #define IOPW_SEL_MASK 0x12 /* SM */ | ||
2534 | #define IOPW_RES_ADDR_14 0x14 | ||
2535 | #define IOPW_FLASH_ADDR 0x16 /* FA */ | ||
2536 | #define IOPW_RES_ADDR_18 0x18 | ||
2537 | #define IOPW_EE_CMD 0x1A /* EC */ | ||
2538 | #define IOPW_EE_DATA 0x1C /* ED */ | ||
2539 | #define IOPW_SFIFO_CNT 0x1E /* SFC */ | ||
2540 | #define IOPW_RES_ADDR_20 0x20 | ||
2541 | #define IOPW_Q_BASE 0x22 /* QB */ | ||
2542 | #define IOPW_QP 0x24 /* QP */ | ||
2543 | #define IOPW_IX 0x26 /* IX */ | ||
2544 | #define IOPW_SP 0x28 /* SP */ | ||
2545 | #define IOPW_PC 0x2A /* PC */ | ||
2546 | #define IOPW_RES_ADDR_2C 0x2C | ||
2547 | #define IOPW_RES_ADDR_2E 0x2E | ||
2548 | #define IOPW_SCSI_DATA 0x30 /* SD */ | ||
2549 | #define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */ | ||
2550 | #define IOPW_SCSI_CTRL 0x34 /* SC */ | ||
2551 | #define IOPW_HSHK_CFG 0x36 /* HCFG */ | ||
2552 | #define IOPW_SXFR_STATUS 0x36 /* SXS */ | ||
2553 | #define IOPW_SXFR_CNTL 0x38 /* SXL */ | ||
2554 | #define IOPW_SXFR_CNTH 0x3A /* SXH */ | ||
2555 | #define IOPW_RES_ADDR_3C 0x3C | ||
2556 | #define IOPW_RFIFO_DATA 0x3E /* RFD */ | ||
2557 | |||
2558 | /* | ||
2559 | * Doubleword I/O register address from base of 'iop_base'. | ||
2560 | */ | ||
2561 | #define IOPDW_RES_ADDR_0 0x00 | ||
2562 | #define IOPDW_RAM_DATA 0x04 | ||
2563 | #define IOPDW_RES_ADDR_8 0x08 | ||
2564 | #define IOPDW_RES_ADDR_C 0x0C | ||
2565 | #define IOPDW_RES_ADDR_10 0x10 | ||
2566 | #define IOPDW_COMMA 0x14 | ||
2567 | #define IOPDW_COMMB 0x18 | ||
2568 | #define IOPDW_RES_ADDR_1C 0x1C | ||
2569 | #define IOPDW_SDMA_ADDR0 0x20 | ||
2570 | #define IOPDW_SDMA_ADDR1 0x24 | ||
2571 | #define IOPDW_SDMA_COUNT 0x28 | ||
2572 | #define IOPDW_SDMA_ERROR 0x2C | ||
2573 | #define IOPDW_RDMA_ADDR0 0x30 | ||
2574 | #define IOPDW_RDMA_ADDR1 0x34 | ||
2575 | #define IOPDW_RDMA_COUNT 0x38 | ||
2576 | #define IOPDW_RDMA_ERROR 0x3C | ||
2577 | |||
2578 | #define ADV_CHIP_ID_BYTE 0x25 | ||
2579 | #define ADV_CHIP_ID_WORD 0x04C1 | ||
2580 | |||
2581 | #define ADV_SC_SCSI_BUS_RESET 0x2000 | ||
2582 | |||
2583 | #define ADV_INTR_ENABLE_HOST_INTR 0x01 | ||
2584 | #define ADV_INTR_ENABLE_SEL_INTR 0x02 | ||
2585 | #define ADV_INTR_ENABLE_DPR_INTR 0x04 | ||
2586 | #define ADV_INTR_ENABLE_RTA_INTR 0x08 | ||
2587 | #define ADV_INTR_ENABLE_RMA_INTR 0x10 | ||
2588 | #define ADV_INTR_ENABLE_RST_INTR 0x20 | ||
2589 | #define ADV_INTR_ENABLE_DPE_INTR 0x40 | ||
2590 | #define ADV_INTR_ENABLE_GLOBAL_INTR 0x80 | ||
2591 | |||
2592 | #define ADV_INTR_STATUS_INTRA 0x01 | ||
2593 | #define ADV_INTR_STATUS_INTRB 0x02 | ||
2594 | #define ADV_INTR_STATUS_INTRC 0x04 | ||
2595 | |||
2596 | #define ADV_RISC_CSR_STOP (0x0000) | ||
2597 | #define ADV_RISC_TEST_COND (0x2000) | ||
2598 | #define ADV_RISC_CSR_RUN (0x4000) | ||
2599 | #define ADV_RISC_CSR_SINGLE_STEP (0x8000) | ||
2600 | |||
2601 | #define ADV_CTRL_REG_HOST_INTR 0x0100 | ||
2602 | #define ADV_CTRL_REG_SEL_INTR 0x0200 | ||
2603 | #define ADV_CTRL_REG_DPR_INTR 0x0400 | ||
2604 | #define ADV_CTRL_REG_RTA_INTR 0x0800 | ||
2605 | #define ADV_CTRL_REG_RMA_INTR 0x1000 | ||
2606 | #define ADV_CTRL_REG_RES_BIT14 0x2000 | ||
2607 | #define ADV_CTRL_REG_DPE_INTR 0x4000 | ||
2608 | #define ADV_CTRL_REG_POWER_DONE 0x8000 | ||
2609 | #define ADV_CTRL_REG_ANY_INTR 0xFF00 | ||
2610 | |||
2611 | #define ADV_CTRL_REG_CMD_RESET 0x00C6 | ||
2612 | #define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5 | ||
2613 | #define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4 | ||
2614 | #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3 | ||
2615 | #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2 | ||
2616 | |||
2617 | #define ADV_TICKLE_NOP 0x00 | ||
2618 | #define ADV_TICKLE_A 0x01 | ||
2619 | #define ADV_TICKLE_B 0x02 | ||
2620 | #define ADV_TICKLE_C 0x03 | ||
2621 | |||
2622 | #define ADV_SCSI_CTRL_RSTOUT 0x2000 | ||
2623 | |||
2624 | #define AdvIsIntPending(port) \ | ||
2625 | (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR) | ||
2626 | |||
2627 | /* | ||
2628 | * SCSI_CFG0 Register bit definitions | ||
2629 | */ | ||
2630 | #define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */ | ||
2631 | #define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */ | ||
2632 | #define EVEN_PARITY 0x1000 /* Select Even Parity */ | ||
2633 | #define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */ | ||
2634 | #define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */ | ||
2635 | #define PRIM_MODE 0x0100 /* Primitive SCSI mode */ | ||
2636 | #define SCAM_EN 0x0080 /* Enable SCAM selection */ | ||
2637 | #define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */ | ||
2638 | #define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */ | ||
2639 | #define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */ | ||
2640 | #define OUR_ID 0x000F /* SCSI ID */ | ||
2641 | |||
2642 | /* | ||
2643 | * SCSI_CFG1 Register bit definitions | ||
2644 | */ | ||
2645 | #define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */ | ||
2646 | #define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */ | ||
2647 | #define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */ | ||
2648 | #define FILTER_SEL 0x0C00 /* Filter Period Selection */ | ||
2649 | #define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */ | ||
2650 | #define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */ | ||
2651 | #define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */ | ||
2652 | #define ACTIVE_DBL 0x0200 /* Disable Active Negation */ | ||
2653 | #define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */ | ||
2654 | #define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */ | ||
2655 | #define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */ | ||
2656 | #define TERM_CTL 0x0030 /* External SCSI Termination Bits */ | ||
2657 | #define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */ | ||
2658 | #define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */ | ||
2659 | #define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */ | ||
2660 | |||
2661 | /* | ||
2662 | * Addendum for ASC-38C0800 Chip | ||
2663 | * | ||
2664 | * The ASC-38C1600 Chip uses the same definitions except that the | ||
2665 | * bus mode override bits [12:10] have been moved to byte register | ||
2666 | * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in | ||
2667 | * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV) | ||
2668 | * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only. | ||
2669 | * Also each ASC-38C1600 function or channel uses only cable bits [5:4] | ||
2670 | * and [1:0]. Bits [14], [7:6], [3:2] are unused. | ||
2671 | */ | ||
2672 | #define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */ | ||
2673 | #define HVD_LVD_SE 0x1C00 /* Device Detect Bits */ | ||
2674 | #define HVD 0x1000 /* HVD Device Detect */ | ||
2675 | #define LVD 0x0800 /* LVD Device Detect */ | ||
2676 | #define SE 0x0400 /* SE Device Detect */ | ||
2677 | #define TERM_LVD 0x00C0 /* LVD Termination Bits */ | ||
2678 | #define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */ | ||
2679 | #define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */ | ||
2680 | #define TERM_SE 0x0030 /* SE Termination Bits */ | ||
2681 | #define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */ | ||
2682 | #define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */ | ||
2683 | #define C_DET_LVD 0x000C /* LVD Cable Detect Bits */ | ||
2684 | #define C_DET3 0x0008 /* Cable Detect for LVD External Wide */ | ||
2685 | #define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */ | ||
2686 | #define C_DET_SE 0x0003 /* SE Cable Detect Bits */ | ||
2687 | #define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */ | ||
2688 | #define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */ | ||
2689 | |||
2690 | |||
2691 | #define CABLE_ILLEGAL_A 0x7 | ||
2692 | /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */ | ||
2693 | |||
2694 | #define CABLE_ILLEGAL_B 0xB | ||
2695 | /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */ | ||
2696 | |||
2697 | /* | ||
2698 | * MEM_CFG Register bit definitions | ||
2699 | */ | ||
2700 | #define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */ | ||
2701 | #define FAST_EE_CLK 0x20 /* Diagnostic Bit */ | ||
2702 | #define RAM_SZ 0x1C /* Specify size of RAM to RISC */ | ||
2703 | #define RAM_SZ_2KB 0x00 /* 2 KB */ | ||
2704 | #define RAM_SZ_4KB 0x04 /* 4 KB */ | ||
2705 | #define RAM_SZ_8KB 0x08 /* 8 KB */ | ||
2706 | #define RAM_SZ_16KB 0x0C /* 16 KB */ | ||
2707 | #define RAM_SZ_32KB 0x10 /* 32 KB */ | ||
2708 | #define RAM_SZ_64KB 0x14 /* 64 KB */ | ||
2709 | |||
2710 | /* | ||
2711 | * DMA_CFG0 Register bit definitions | ||
2712 | * | ||
2713 | * This register is only accessible to the host. | ||
2714 | */ | ||
2715 | #define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */ | ||
2716 | #define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */ | ||
2717 | #define FIFO_THRESH_16B 0x00 /* 16 bytes */ | ||
2718 | #define FIFO_THRESH_32B 0x20 /* 32 bytes */ | ||
2719 | #define FIFO_THRESH_48B 0x30 /* 48 bytes */ | ||
2720 | #define FIFO_THRESH_64B 0x40 /* 64 bytes */ | ||
2721 | #define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */ | ||
2722 | #define FIFO_THRESH_96B 0x60 /* 96 bytes */ | ||
2723 | #define FIFO_THRESH_112B 0x70 /* 112 bytes */ | ||
2724 | #define START_CTL 0x0C /* DMA start conditions */ | ||
2725 | #define START_CTL_TH 0x00 /* Wait threshold level (default) */ | ||
2726 | #define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */ | ||
2727 | #define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */ | ||
2728 | #define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */ | ||
2729 | #define READ_CMD 0x03 /* Memory Read Method */ | ||
2730 | #define READ_CMD_MR 0x00 /* Memory Read */ | ||
2731 | #define READ_CMD_MRL 0x02 /* Memory Read Long */ | ||
2732 | #define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */ | ||
2733 | |||
2734 | /* | ||
2735 | * ASC-38C0800 RAM BIST Register bit definitions | ||
2736 | */ | ||
2737 | #define RAM_TEST_MODE 0x80 | ||
2738 | #define PRE_TEST_MODE 0x40 | ||
2739 | #define NORMAL_MODE 0x00 | ||
2740 | #define RAM_TEST_DONE 0x10 | ||
2741 | #define RAM_TEST_STATUS 0x0F | ||
2742 | #define RAM_TEST_HOST_ERROR 0x08 | ||
2743 | #define RAM_TEST_INTRAM_ERROR 0x04 | ||
2744 | #define RAM_TEST_RISC_ERROR 0x02 | ||
2745 | #define RAM_TEST_SCSI_ERROR 0x01 | ||
2746 | #define RAM_TEST_SUCCESS 0x00 | ||
2747 | #define PRE_TEST_VALUE 0x05 | ||
2748 | #define NORMAL_VALUE 0x00 | ||
2749 | |||
2750 | /* | ||
2751 | * ASC38C1600 Definitions | ||
2752 | * | ||
2753 | * IOPB_PCI_INT_CFG Bit Field Definitions | ||
2754 | */ | ||
2755 | |||
2756 | #define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */ | ||
2757 | |||
2758 | /* | ||
2759 | * Bit 1 can be set to change the interrupt for the Function to operate in | ||
2760 | * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in | ||
2761 | * Open Drain mode. Both functions of the ASC38C1600 must be set to the same | ||
2762 | * mode, otherwise the operating mode is undefined. | ||
2763 | */ | ||
2764 | #define TOTEMPOLE 0x02 | ||
2765 | |||
2766 | /* | ||
2767 | * Bit 0 can be used to change the Int Pin for the Function. The value is | ||
2768 | * 0 by default for both Functions with Function 0 using INT A and Function | ||
2769 | * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set, | ||
2770 | * INT A is used. | ||
2771 | * | ||
2772 | * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin | ||
2773 | * value specified in the PCI Configuration Space. | ||
2774 | */ | ||
2775 | #define INTAB 0x01 | ||
2776 | |||
2777 | /* a_advlib.h */ | ||
2778 | |||
2779 | /* | ||
2780 | * Adv Library Status Definitions | ||
2781 | */ | ||
2782 | #define ADV_TRUE 1 | ||
2783 | #define ADV_FALSE 0 | ||
2784 | #define ADV_NOERROR 1 | ||
2785 | #define ADV_SUCCESS 1 | ||
2786 | #define ADV_BUSY 0 | ||
2787 | #define ADV_ERROR (-1) | ||
2788 | |||
2789 | |||
2790 | /* | ||
2791 | * ADV_DVC_VAR 'warn_code' values | ||
2792 | */ | ||
2793 | #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */ | ||
2794 | #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */ | ||
2795 | #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */ | ||
2796 | #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */ | ||
2797 | #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */ | ||
2798 | |||
2799 | #define ADV_MAX_TID 15 /* max. target identifier */ | ||
2800 | #define ADV_MAX_LUN 7 /* max. logical unit number */ | ||
2801 | |||
2802 | /* | ||
2803 | * Error code values are set in ADV_DVC_VAR 'err_code'. | ||
2804 | */ | ||
2805 | #define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */ | ||
2806 | #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */ | ||
2807 | #define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */ | ||
2808 | #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */ | ||
2809 | #define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */ | ||
2810 | #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */ | ||
2811 | #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */ | ||
2812 | #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */ | ||
2813 | #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */ | ||
2814 | #define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */ | ||
2815 | #define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */ | ||
2816 | #define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */ | ||
2817 | #define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */ | ||
2818 | #define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */ | ||
2819 | |||
2820 | /* | ||
2821 | * Fixed locations of microcode operating variables. | ||
2822 | */ | ||
2823 | #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */ | ||
2824 | #define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */ | ||
2825 | #define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */ | ||
2826 | #define ASC_MC_VERSION_DATE 0x0038 /* microcode version */ | ||
2827 | #define ASC_MC_VERSION_NUM 0x003A /* microcode number */ | ||
2828 | #define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */ | ||
2829 | #define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */ | ||
2830 | #define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */ | ||
2831 | #define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */ | ||
2832 | #define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */ | ||
2833 | #define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */ | ||
2834 | #define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */ | ||
2835 | #define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */ | ||
2836 | #define ASC_MC_CHIP_TYPE 0x009A | ||
2837 | #define ASC_MC_INTRB_CODE 0x009B | ||
2838 | #define ASC_MC_WDTR_ABLE 0x009C | ||
2839 | #define ASC_MC_SDTR_ABLE 0x009E | ||
2840 | #define ASC_MC_TAGQNG_ABLE 0x00A0 | ||
2841 | #define ASC_MC_DISC_ENABLE 0x00A2 | ||
2842 | #define ASC_MC_IDLE_CMD_STATUS 0x00A4 | ||
2843 | #define ASC_MC_IDLE_CMD 0x00A6 | ||
2844 | #define ASC_MC_IDLE_CMD_PARAMETER 0x00A8 | ||
2845 | #define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC | ||
2846 | #define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE | ||
2847 | #define ASC_MC_DEFAULT_MEM_CFG 0x00B0 | ||
2848 | #define ASC_MC_DEFAULT_SEL_MASK 0x00B2 | ||
2849 | #define ASC_MC_SDTR_DONE 0x00B6 | ||
2850 | #define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0 | ||
2851 | #define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0 | ||
2852 | #define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100 | ||
2853 | #define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */ | ||
2854 | #define ASC_MC_WDTR_DONE 0x0124 | ||
2855 | #define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */ | ||
2856 | #define ASC_MC_ICQ 0x0160 | ||
2857 | #define ASC_MC_IRQ 0x0164 | ||
2858 | #define ASC_MC_PPR_ABLE 0x017A | ||
2859 | |||
2860 | /* | ||
2861 | * BIOS LRAM variable absolute offsets. | ||
2862 | */ | ||
2863 | #define BIOS_CODESEG 0x54 | ||
2864 | #define BIOS_CODELEN 0x56 | ||
2865 | #define BIOS_SIGNATURE 0x58 | ||
2866 | #define BIOS_VERSION 0x5A | ||
2867 | |||
2868 | /* | ||
2869 | * Microcode Control Flags | ||
2870 | * | ||
2871 | * Flags set by the Adv Library in RISC variable 'control_flag' (0x122) | ||
2872 | * and handled by the microcode. | ||
2873 | */ | ||
2874 | #define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */ | ||
2875 | #define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */ | ||
2876 | |||
2877 | /* | ||
2878 | * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format | ||
2879 | */ | ||
2880 | #define HSHK_CFG_WIDE_XFR 0x8000 | ||
2881 | #define HSHK_CFG_RATE 0x0F00 | ||
2882 | #define HSHK_CFG_OFFSET 0x001F | ||
2883 | |||
2884 | #define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */ | ||
2885 | #define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */ | ||
2886 | #define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */ | ||
2887 | #define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */ | ||
2888 | |||
2889 | #define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */ | ||
2890 | #define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */ | ||
2891 | #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */ | ||
2892 | #define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */ | ||
2893 | #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */ | ||
2894 | |||
2895 | #define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */ | ||
2896 | #define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */ | ||
2897 | #define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */ | ||
2898 | #define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */ | ||
2899 | #define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */ | ||
2900 | /* | ||
2901 | * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or | ||
2902 | * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used. | ||
2903 | */ | ||
2904 | #define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */ | ||
2905 | #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */ | ||
2906 | |||
2907 | /* | ||
2908 | * All fields here are accessed by the board microcode and need to be | ||
2909 | * little-endian. | ||
2910 | */ | ||
2911 | typedef struct adv_carr_t | ||
2912 | { | ||
2913 | ADV_VADDR carr_va; /* Carrier Virtual Address */ | ||
2914 | ADV_PADDR carr_pa; /* Carrier Physical Address */ | ||
2915 | ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */ | ||
2916 | /* | ||
2917 | * next_vpa [31:4] Carrier Virtual or Physical Next Pointer | ||
2918 | * | ||
2919 | * next_vpa [3:1] Reserved Bits | ||
2920 | * next_vpa [0] Done Flag set in Response Queue. | ||
2921 | */ | ||
2922 | ADV_VADDR next_vpa; | ||
2923 | } ADV_CARR_T; | ||
2924 | |||
2925 | /* | ||
2926 | * Mask used to eliminate low 4 bits of carrier 'next_vpa' field. | ||
2927 | */ | ||
2928 | #define ASC_NEXT_VPA_MASK 0xFFFFFFF0 | ||
2929 | |||
2930 | #define ASC_RQ_DONE 0x00000001 | ||
2931 | #define ASC_RQ_GOOD 0x00000002 | ||
2932 | #define ASC_CQ_STOPPER 0x00000000 | ||
2933 | |||
2934 | #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK) | ||
2935 | |||
2936 | #define ADV_CARRIER_NUM_PAGE_CROSSING \ | ||
2937 | (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \ | ||
2938 | (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE) | ||
2939 | |||
2940 | #define ADV_CARRIER_BUFSIZE \ | ||
2941 | ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T)) | ||
2942 | |||
2943 | /* | ||
2944 | * ASC_SCSI_REQ_Q 'a_flag' definitions | ||
2945 | * | ||
2946 | * The Adv Library should limit use to the lower nibble (4 bits) of | ||
2947 | * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag. | ||
2948 | */ | ||
2949 | #define ADV_POLL_REQUEST 0x01 /* poll for request completion */ | ||
2950 | #define ADV_SCSIQ_DONE 0x02 /* request done */ | ||
2951 | #define ADV_DONT_RETRY 0x08 /* don't do retry */ | ||
2952 | |||
2953 | #define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */ | ||
2954 | #define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */ | ||
2955 | #define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */ | ||
2956 | |||
2957 | /* | ||
2958 | * Adapter temporary configuration structure | ||
2959 | * | ||
2960 | * This structure can be discarded after initialization. Don't add | ||
2961 | * fields here needed after initialization. | ||
2962 | * | ||
2963 | * Field naming convention: | ||
2964 | * | ||
2965 | * *_enable indicates the field enables or disables a feature. The | ||
2966 | * value of the field is never reset. | ||
2967 | */ | ||
2968 | typedef struct adv_dvc_cfg { | ||
2969 | ushort disc_enable; /* enable disconnection */ | ||
2970 | uchar chip_version; /* chip version */ | ||
2971 | uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */ | ||
2972 | ushort lib_version; /* Adv Library version number */ | ||
2973 | ushort control_flag; /* Microcode Control Flag */ | ||
2974 | ushort mcode_date; /* Microcode date */ | ||
2975 | ushort mcode_version; /* Microcode version */ | ||
2976 | ushort pci_slot_info; /* high byte device/function number */ | ||
2977 | /* bits 7-3 device num., bits 2-0 function num. */ | ||
2978 | /* low byte bus num. */ | ||
2979 | ushort serial1; /* EEPROM serial number word 1 */ | ||
2980 | ushort serial2; /* EEPROM serial number word 2 */ | ||
2981 | ushort serial3; /* EEPROM serial number word 3 */ | ||
2982 | struct device *dev; /* pointer to the pci dev structure for this board */ | ||
2983 | } ADV_DVC_CFG; | ||
2984 | |||
2985 | struct adv_dvc_var; | ||
2986 | struct adv_scsi_req_q; | ||
2987 | |||
2988 | typedef void (* ADV_ISR_CALLBACK) | ||
2989 | (struct adv_dvc_var *, struct adv_scsi_req_q *); | ||
2990 | |||
2991 | typedef void (* ADV_ASYNC_CALLBACK) | ||
2992 | (struct adv_dvc_var *, uchar); | ||
2993 | |||
2994 | /* | ||
2995 | * Adapter operation variable structure. | ||
2996 | * | ||
2997 | * One structure is required per host adapter. | ||
2998 | * | ||
2999 | * Field naming convention: | ||
3000 | * | ||
3001 | * *_able indicates both whether a feature should be enabled or disabled | ||
3002 | * and whether a device isi capable of the feature. At initialization | ||
3003 | * this field may be set, but later if a device is found to be incapable | ||
3004 | * of the feature, the field is cleared. | ||
3005 | */ | ||
3006 | typedef struct adv_dvc_var { | ||
3007 | AdvPortAddr iop_base; /* I/O port address */ | ||
3008 | ushort err_code; /* fatal error code */ | ||
3009 | ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */ | ||
3010 | ADV_ISR_CALLBACK isr_callback; | ||
3011 | ADV_ASYNC_CALLBACK async_callback; | ||
3012 | ushort wdtr_able; /* try WDTR for a device */ | ||
3013 | ushort sdtr_able; /* try SDTR for a device */ | ||
3014 | ushort ultra_able; /* try SDTR Ultra speed for a device */ | ||
3015 | ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */ | ||
3016 | ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */ | ||
3017 | ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */ | ||
3018 | ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */ | ||
3019 | ushort tagqng_able; /* try tagged queuing with a device */ | ||
3020 | ushort ppr_able; /* PPR message capable per TID bitmask. */ | ||
3021 | uchar max_dvc_qng; /* maximum number of tagged commands per device */ | ||
3022 | ushort start_motor; /* start motor command allowed */ | ||
3023 | uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */ | ||
3024 | uchar chip_no; /* should be assigned by caller */ | ||
3025 | uchar max_host_qng; /* maximum number of Q'ed command allowed */ | ||
3026 | uchar irq_no; /* IRQ number */ | ||
3027 | ushort no_scam; /* scam_tolerant of EEPROM */ | ||
3028 | struct asc_board *drv_ptr; /* driver pointer to private structure */ | ||
3029 | uchar chip_scsi_id; /* chip SCSI target ID */ | ||
3030 | uchar chip_type; | ||
3031 | uchar bist_err_code; | ||
3032 | ADV_CARR_T *carrier_buf; | ||
3033 | ADV_CARR_T *carr_freelist; /* Carrier free list. */ | ||
3034 | ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */ | ||
3035 | ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */ | ||
3036 | ushort carr_pending_cnt; /* Count of pending carriers. */ | ||
3037 | /* | ||
3038 | * Note: The following fields will not be used after initialization. The | ||
3039 | * driver may discard the buffer after initialization is done. | ||
3040 | */ | ||
3041 | ADV_DVC_CFG *cfg; /* temporary configuration structure */ | ||
3042 | } ADV_DVC_VAR; | ||
3043 | |||
3044 | #define NO_OF_SG_PER_BLOCK 15 | ||
3045 | |||
3046 | typedef struct asc_sg_block { | ||
3047 | uchar reserved1; | ||
3048 | uchar reserved2; | ||
3049 | uchar reserved3; | ||
3050 | uchar sg_cnt; /* Valid entries in block. */ | ||
3051 | ADV_PADDR sg_ptr; /* Pointer to next sg block. */ | ||
3052 | struct { | ||
3053 | ADV_PADDR sg_addr; /* SG element address. */ | ||
3054 | ADV_DCNT sg_count; /* SG element count. */ | ||
3055 | } sg_list[NO_OF_SG_PER_BLOCK]; | ||
3056 | } ADV_SG_BLOCK; | ||
3057 | |||
3058 | /* | ||
3059 | * ADV_SCSI_REQ_Q - microcode request structure | ||
3060 | * | ||
3061 | * All fields in this structure up to byte 60 are used by the microcode. | ||
3062 | * The microcode makes assumptions about the size and ordering of fields | ||
3063 | * in this structure. Do not change the structure definition here without | ||
3064 | * coordinating the change with the microcode. | ||
3065 | * | ||
3066 | * All fields accessed by microcode must be maintained in little_endian | ||
3067 | * order. | ||
3068 | */ | ||
3069 | typedef struct adv_scsi_req_q { | ||
3070 | uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */ | ||
3071 | uchar target_cmd; | ||
3072 | uchar target_id; /* Device target identifier. */ | ||
3073 | uchar target_lun; /* Device target logical unit number. */ | ||
3074 | ADV_PADDR data_addr; /* Data buffer physical address. */ | ||
3075 | ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */ | ||
3076 | ADV_PADDR sense_addr; | ||
3077 | ADV_PADDR carr_pa; | ||
3078 | uchar mflag; | ||
3079 | uchar sense_len; | ||
3080 | uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */ | ||
3081 | uchar scsi_cntl; | ||
3082 | uchar done_status; /* Completion status. */ | ||
3083 | uchar scsi_status; /* SCSI status byte. */ | ||
3084 | uchar host_status; /* Ucode host status. */ | ||
3085 | uchar sg_working_ix; | ||
3086 | uchar cdb[12]; /* SCSI CDB bytes 0-11. */ | ||
3087 | ADV_PADDR sg_real_addr; /* SG list physical address. */ | ||
3088 | ADV_PADDR scsiq_rptr; | ||
3089 | uchar cdb16[4]; /* SCSI CDB bytes 12-15. */ | ||
3090 | ADV_VADDR scsiq_ptr; | ||
3091 | ADV_VADDR carr_va; | ||
3092 | /* | ||
3093 | * End of microcode structure - 60 bytes. The rest of the structure | ||
3094 | * is used by the Adv Library and ignored by the microcode. | ||
3095 | */ | ||
3096 | ADV_VADDR srb_ptr; | ||
3097 | ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */ | ||
3098 | char *vdata_addr; /* Data buffer virtual address. */ | ||
3099 | uchar a_flag; | ||
3100 | uchar pad[2]; /* Pad out to a word boundary. */ | ||
3101 | } ADV_SCSI_REQ_Q; | ||
3102 | |||
3103 | /* | ||
3104 | * Microcode idle loop commands | ||
3105 | */ | ||
3106 | #define IDLE_CMD_COMPLETED 0 | ||
3107 | #define IDLE_CMD_STOP_CHIP 0x0001 | ||
3108 | #define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002 | ||
3109 | #define IDLE_CMD_SEND_INT 0x0004 | ||
3110 | #define IDLE_CMD_ABORT 0x0008 | ||
3111 | #define IDLE_CMD_DEVICE_RESET 0x0010 | ||
3112 | #define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */ | ||
3113 | #define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */ | ||
3114 | #define IDLE_CMD_SCSIREQ 0x0080 | ||
3115 | |||
3116 | #define IDLE_CMD_STATUS_SUCCESS 0x0001 | ||
3117 | #define IDLE_CMD_STATUS_FAILURE 0x0002 | ||
3118 | |||
3119 | /* | ||
3120 | * AdvSendIdleCmd() flag definitions. | ||
3121 | */ | ||
3122 | #define ADV_NOWAIT 0x01 | ||
3123 | |||
3124 | /* | ||
3125 | * Wait loop time out values. | ||
3126 | */ | ||
3127 | #define SCSI_WAIT_10_SEC 10UL /* 10 seconds */ | ||
3128 | #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */ | ||
3129 | #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */ | ||
3130 | #define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */ | ||
3131 | #define SCSI_MAX_RETRY 10 /* retry count */ | ||
3132 | |||
3133 | #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */ | ||
3134 | #define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */ | ||
3135 | #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */ | ||
3136 | #define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */ | ||
3137 | |||
3138 | |||
3139 | #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */ | ||
3140 | |||
3141 | /* | ||
3142 | * Device drivers must define the following functions. | ||
3143 | */ | ||
3144 | STATIC inline ulong DvcEnterCritical(void); | ||
3145 | STATIC inline void DvcLeaveCritical(ulong); | ||
3146 | STATIC void DvcSleepMilliSecond(ADV_DCNT); | ||
3147 | STATIC uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort); | ||
3148 | STATIC void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar); | ||
3149 | STATIC ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *, | ||
3150 | uchar *, ASC_SDCNT *, int); | ||
3151 | STATIC void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort); | ||
3152 | |||
3153 | /* | ||
3154 | * Adv Library functions available to drivers. | ||
3155 | */ | ||
3156 | STATIC int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *); | ||
3157 | STATIC int AdvISR(ADV_DVC_VAR *); | ||
3158 | STATIC int AdvInitGetConfig(ADV_DVC_VAR *); | ||
3159 | STATIC int AdvInitAsc3550Driver(ADV_DVC_VAR *); | ||
3160 | STATIC int AdvInitAsc38C0800Driver(ADV_DVC_VAR *); | ||
3161 | STATIC int AdvInitAsc38C1600Driver(ADV_DVC_VAR *); | ||
3162 | STATIC int AdvResetChipAndSB(ADV_DVC_VAR *); | ||
3163 | STATIC int AdvResetSB(ADV_DVC_VAR *asc_dvc); | ||
3164 | |||
3165 | /* | ||
3166 | * Internal Adv Library functions. | ||
3167 | */ | ||
3168 | STATIC int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT); | ||
3169 | STATIC void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *); | ||
3170 | STATIC int AdvInitFrom3550EEP(ADV_DVC_VAR *); | ||
3171 | STATIC int AdvInitFrom38C0800EEP(ADV_DVC_VAR *); | ||
3172 | STATIC int AdvInitFrom38C1600EEP(ADV_DVC_VAR *); | ||
3173 | STATIC ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *); | ||
3174 | STATIC void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *); | ||
3175 | STATIC ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *); | ||
3176 | STATIC void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *); | ||
3177 | STATIC ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *); | ||
3178 | STATIC void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *); | ||
3179 | STATIC void AdvWaitEEPCmd(AdvPortAddr); | ||
3180 | STATIC ushort AdvReadEEPWord(AdvPortAddr, int); | ||
3181 | |||
3182 | /* | ||
3183 | * PCI Bus Definitions | ||
3184 | */ | ||
3185 | #define AscPCICmdRegBits_BusMastering 0x0007 | ||
3186 | #define AscPCICmdRegBits_ParErrRespCtrl 0x0040 | ||
3187 | |||
3188 | /* Read byte from a register. */ | ||
3189 | #define AdvReadByteRegister(iop_base, reg_off) \ | ||
3190 | (ADV_MEM_READB((iop_base) + (reg_off))) | ||
3191 | |||
3192 | /* Write byte to a register. */ | ||
3193 | #define AdvWriteByteRegister(iop_base, reg_off, byte) \ | ||
3194 | (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte))) | ||
3195 | |||
3196 | /* Read word (2 bytes) from a register. */ | ||
3197 | #define AdvReadWordRegister(iop_base, reg_off) \ | ||
3198 | (ADV_MEM_READW((iop_base) + (reg_off))) | ||
3199 | |||
3200 | /* Write word (2 bytes) to a register. */ | ||
3201 | #define AdvWriteWordRegister(iop_base, reg_off, word) \ | ||
3202 | (ADV_MEM_WRITEW((iop_base) + (reg_off), (word))) | ||
3203 | |||
3204 | /* Write dword (4 bytes) to a register. */ | ||
3205 | #define AdvWriteDWordRegister(iop_base, reg_off, dword) \ | ||
3206 | (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword))) | ||
3207 | |||
3208 | /* Read byte from LRAM. */ | ||
3209 | #define AdvReadByteLram(iop_base, addr, byte) \ | ||
3210 | do { \ | ||
3211 | ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \ | ||
3212 | (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \ | ||
3213 | } while (0) | ||
3214 | |||
3215 | /* Write byte to LRAM. */ | ||
3216 | #define AdvWriteByteLram(iop_base, addr, byte) \ | ||
3217 | (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \ | ||
3218 | ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte))) | ||
3219 | |||
3220 | /* Read word (2 bytes) from LRAM. */ | ||
3221 | #define AdvReadWordLram(iop_base, addr, word) \ | ||
3222 | do { \ | ||
3223 | ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \ | ||
3224 | (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \ | ||
3225 | } while (0) | ||
3226 | |||
3227 | /* Write word (2 bytes) to LRAM. */ | ||
3228 | #define AdvWriteWordLram(iop_base, addr, word) \ | ||
3229 | (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \ | ||
3230 | ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word))) | ||
3231 | |||
3232 | /* Write little-endian double word (4 bytes) to LRAM */ | ||
3233 | /* Because of unspecified C language ordering don't use auto-increment. */ | ||
3234 | #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \ | ||
3235 | ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \ | ||
3236 | ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \ | ||
3237 | cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \ | ||
3238 | (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \ | ||
3239 | ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \ | ||
3240 | cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF))))) | ||
3241 | |||
3242 | /* Read word (2 bytes) from LRAM assuming that the address is already set. */ | ||
3243 | #define AdvReadWordAutoIncLram(iop_base) \ | ||
3244 | (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)) | ||
3245 | |||
3246 | /* Write word (2 bytes) to LRAM assuming that the address is already set. */ | ||
3247 | #define AdvWriteWordAutoIncLram(iop_base, word) \ | ||
3248 | (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word))) | ||
3249 | |||
3250 | |||
3251 | /* | ||
3252 | * Define macro to check for Condor signature. | ||
3253 | * | ||
3254 | * Evaluate to ADV_TRUE if a Condor chip is found the specified port | ||
3255 | * address 'iop_base'. Otherwise evalue to ADV_FALSE. | ||
3256 | */ | ||
3257 | #define AdvFindSignature(iop_base) \ | ||
3258 | (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \ | ||
3259 | ADV_CHIP_ID_BYTE) && \ | ||
3260 | (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \ | ||
3261 | ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE) | ||
3262 | |||
3263 | /* | ||
3264 | * Define macro to Return the version number of the chip at 'iop_base'. | ||
3265 | * | ||
3266 | * The second parameter 'bus_type' is currently unused. | ||
3267 | */ | ||
3268 | #define AdvGetChipVersion(iop_base, bus_type) \ | ||
3269 | AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV) | ||
3270 | |||
3271 | /* | ||
3272 | * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must | ||
3273 | * match the ASC_SCSI_REQ_Q 'srb_ptr' field. | ||
3274 | * | ||
3275 | * If the request has not yet been sent to the device it will simply be | ||
3276 | * aborted from RISC memory. If the request is disconnected it will be | ||
3277 | * aborted on reselection by sending an Abort Message to the target ID. | ||
3278 | * | ||
3279 | * Return value: | ||
3280 | * ADV_TRUE(1) - Queue was successfully aborted. | ||
3281 | * ADV_FALSE(0) - Queue was not found on the active queue list. | ||
3282 | */ | ||
3283 | #define AdvAbortQueue(asc_dvc, scsiq) \ | ||
3284 | AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \ | ||
3285 | (ADV_DCNT) (scsiq)) | ||
3286 | |||
3287 | /* | ||
3288 | * Send a Bus Device Reset Message to the specified target ID. | ||
3289 | * | ||
3290 | * All outstanding commands will be purged if sending the | ||
3291 | * Bus Device Reset Message is successful. | ||
3292 | * | ||
3293 | * Return Value: | ||
3294 | * ADV_TRUE(1) - All requests on the target are purged. | ||
3295 | * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests | ||
3296 | * are not purged. | ||
3297 | */ | ||
3298 | #define AdvResetDevice(asc_dvc, target_id) \ | ||
3299 | AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \ | ||
3300 | (ADV_DCNT) (target_id)) | ||
3301 | |||
3302 | /* | ||
3303 | * SCSI Wide Type definition. | ||
3304 | */ | ||
3305 | #define ADV_SCSI_BIT_ID_TYPE ushort | ||
3306 | |||
3307 | /* | ||
3308 | * AdvInitScsiTarget() 'cntl_flag' options. | ||
3309 | */ | ||
3310 | #define ADV_SCAN_LUN 0x01 | ||
3311 | #define ADV_CAPINFO_NOLUN 0x02 | ||
3312 | |||
3313 | /* | ||
3314 | * Convert target id to target id bit mask. | ||
3315 | */ | ||
3316 | #define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID)) | ||
3317 | |||
3318 | /* | ||
3319 | * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values. | ||
3320 | */ | ||
3321 | |||
3322 | #define QD_NO_STATUS 0x00 /* Request not completed yet. */ | ||
3323 | #define QD_NO_ERROR 0x01 | ||
3324 | #define QD_ABORTED_BY_HOST 0x02 | ||
3325 | #define QD_WITH_ERROR 0x04 | ||
3326 | |||
3327 | #define QHSTA_NO_ERROR 0x00 | ||
3328 | #define QHSTA_M_SEL_TIMEOUT 0x11 | ||
3329 | #define QHSTA_M_DATA_OVER_RUN 0x12 | ||
3330 | #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13 | ||
3331 | #define QHSTA_M_QUEUE_ABORTED 0x15 | ||
3332 | #define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */ | ||
3333 | #define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */ | ||
3334 | #define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */ | ||
3335 | #define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */ | ||
3336 | #define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */ | ||
3337 | #define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */ | ||
3338 | #define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */ | ||
3339 | /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */ | ||
3340 | #define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */ | ||
3341 | #define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */ | ||
3342 | #define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */ | ||
3343 | #define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */ | ||
3344 | #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */ | ||
3345 | #define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */ | ||
3346 | #define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */ | ||
3347 | #define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */ | ||
3348 | #define QHSTA_M_WTM_TIMEOUT 0x41 | ||
3349 | #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42 | ||
3350 | #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43 | ||
3351 | #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44 | ||
3352 | #define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */ | ||
3353 | #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */ | ||
3354 | #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */ | ||
3355 | |||
3356 | |||
3357 | /* | ||
3358 | * Default EEPROM Configuration structure defined in a_init.c. | ||
3359 | */ | ||
3360 | static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config; | ||
3361 | static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config; | ||
3362 | static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config; | ||
3363 | |||
3364 | /* | ||
3365 | * DvcGetPhyAddr() flag arguments | ||
3366 | */ | ||
3367 | #define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */ | ||
3368 | #define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */ | ||
3369 | #define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */ | ||
3370 | #define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */ | ||
3371 | #define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */ | ||
3372 | #define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */ | ||
3373 | |||
3374 | /* Return the address that is aligned at the next doubleword >= to 'addr'. */ | ||
3375 | #define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7) | ||
3376 | #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF) | ||
3377 | #define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F) | ||
3378 | |||
3379 | /* | ||
3380 | * Total contiguous memory needed for driver SG blocks. | ||
3381 | * | ||
3382 | * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum | ||
3383 | * number of scatter-gather elements the driver supports in a | ||
3384 | * single request. | ||
3385 | */ | ||
3386 | |||
3387 | #define ADV_SG_LIST_MAX_BYTE_SIZE \ | ||
3388 | (sizeof(ADV_SG_BLOCK) * \ | ||
3389 | ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)) | ||
3390 | |||
3391 | /* | ||
3392 | * Inquiry data structure and bitfield macros | ||
3393 | * | ||
3394 | * Using bitfields to access the subchar data isn't portable across | ||
3395 | * endianness, so instead mask and shift. Only quantities of more | ||
3396 | * than 1 bit are shifted, since the others are just tested for true | ||
3397 | * or false. | ||
3398 | */ | ||
3399 | |||
3400 | #define ADV_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f) | ||
3401 | #define ADV_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5) | ||
3402 | #define ADV_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f) | ||
3403 | #define ADV_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80) | ||
3404 | #define ADV_INQ_ANSI_VER(inq) ((inq)->ver & 0x07) | ||
3405 | #define ADV_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3) | ||
3406 | #define ADV_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6) | ||
3407 | #define ADV_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f) | ||
3408 | #define ADV_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40) | ||
3409 | #define ADV_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80) | ||
3410 | #define ADV_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01) | ||
3411 | #define ADV_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02) | ||
3412 | #define ADV_INQ_LINK_CMD(inq) ((inq)->flags & 0x08) | ||
3413 | #define ADV_INQ_SYNC(inq) ((inq)->flags & 0x10) | ||
3414 | #define ADV_INQ_WIDE16(inq) ((inq)->flags & 0x20) | ||
3415 | #define ADV_INQ_WIDE32(inq) ((inq)->flags & 0x40) | ||
3416 | #define ADV_INQ_REL_ADDR(inq) ((inq)->flags & 0x80) | ||
3417 | #define ADV_INQ_INFO_UNIT(inq) ((inq)->info & 0x01) | ||
3418 | #define ADV_INQ_QUICK_ARB(inq) ((inq)->info & 0x02) | ||
3419 | #define ADV_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2) | ||
3420 | |||
3421 | typedef struct { | ||
3422 | uchar periph; /* peripheral device type [0:4] */ | ||
3423 | /* peripheral qualifier [5:7] */ | ||
3424 | uchar devtype; /* device type modifier (for SCSI I) [0:6] */ | ||
3425 | /* RMB - removable medium bit [7] */ | ||
3426 | uchar ver; /* ANSI approved version [0:2] */ | ||
3427 | /* ECMA version [3:5] */ | ||
3428 | /* ISO version [6:7] */ | ||
3429 | uchar byte3; /* response data format [0:3] */ | ||
3430 | /* 0 SCSI 1 */ | ||
3431 | /* 1 CCS */ | ||
3432 | /* 2 SCSI-2 */ | ||
3433 | /* 3-F reserved */ | ||
3434 | /* reserved [4:5] */ | ||
3435 | /* terminate I/O process bit (see 5.6.22) [6] */ | ||
3436 | /* asynch. event notification (processor) [7] */ | ||
3437 | uchar add_len; /* additional length */ | ||
3438 | uchar res1; /* reserved */ | ||
3439 | uchar res2; /* reserved */ | ||
3440 | uchar flags; /* soft reset implemented [0] */ | ||
3441 | /* command queuing [1] */ | ||
3442 | /* reserved [2] */ | ||
3443 | /* linked command for this logical unit [3] */ | ||
3444 | /* synchronous data transfer [4] */ | ||
3445 | /* wide bus 16 bit data transfer [5] */ | ||
3446 | /* wide bus 32 bit data transfer [6] */ | ||
3447 | /* relative addressing mode [7] */ | ||
3448 | uchar vendor_id[8]; /* vendor identification */ | ||
3449 | uchar product_id[16]; /* product identification */ | ||
3450 | uchar product_rev_level[4]; /* product revision level */ | ||
3451 | uchar vendor_specific[20]; /* vendor specific */ | ||
3452 | uchar info; /* information unit supported [0] */ | ||
3453 | /* quick arbitrate supported [1] */ | ||
3454 | /* clocking field [2:3] */ | ||
3455 | /* reserved [4:7] */ | ||
3456 | uchar res3; /* reserved */ | ||
3457 | } ADV_SCSI_INQUIRY; /* 58 bytes */ | ||
3458 | |||
3459 | |||
3460 | /* | ||
3461 | * --- Driver Constants and Macros | ||
3462 | */ | ||
3463 | |||
3464 | #define ASC_NUM_BOARD_SUPPORTED 16 | ||
3465 | #define ASC_NUM_IOPORT_PROBE 4 | ||
3466 | #define ASC_NUM_BUS 4 | ||
3467 | |||
3468 | /* Reference Scsi_Host hostdata */ | ||
3469 | #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata)) | ||
3470 | |||
3471 | /* asc_board_t flags */ | ||
3472 | #define ASC_HOST_IN_RESET 0x01 | ||
3473 | #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */ | ||
3474 | #define ASC_SELECT_QUEUE_DEPTHS 0x08 | ||
3475 | |||
3476 | #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0) | ||
3477 | #define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD) | ||
3478 | |||
3479 | #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */ | ||
3480 | |||
3481 | #define ASC_INFO_SIZE 128 /* advansys_info() line size */ | ||
3482 | |||
3483 | #ifdef CONFIG_PROC_FS | ||
3484 | /* /proc/scsi/advansys/[0...] related definitions */ | ||
3485 | #define ASC_PRTBUF_SIZE 2048 | ||
3486 | #define ASC_PRTLINE_SIZE 160 | ||
3487 | |||
3488 | #define ASC_PRT_NEXT() \ | ||
3489 | if (cp) { \ | ||
3490 | totlen += len; \ | ||
3491 | leftlen -= len; \ | ||
3492 | if (leftlen == 0) { \ | ||
3493 | return totlen; \ | ||
3494 | } \ | ||
3495 | cp += len; \ | ||
3496 | } | ||
3497 | #endif /* CONFIG_PROC_FS */ | ||
3498 | |||
3499 | /* Asc Library return codes */ | ||
3500 | #define ASC_TRUE 1 | ||
3501 | #define ASC_FALSE 0 | ||
3502 | #define ASC_NOERROR 1 | ||
3503 | #define ASC_BUSY 0 | ||
3504 | #define ASC_ERROR (-1) | ||
3505 | |||
3506 | /* struct scsi_cmnd function return codes */ | ||
3507 | #define STATUS_BYTE(byte) (byte) | ||
3508 | #define MSG_BYTE(byte) ((byte) << 8) | ||
3509 | #define HOST_BYTE(byte) ((byte) << 16) | ||
3510 | #define DRIVER_BYTE(byte) ((byte) << 24) | ||
3511 | |||
3512 | /* | ||
3513 | * The following definitions and macros are OS independent interfaces to | ||
3514 | * the queue functions: | ||
3515 | * REQ - SCSI request structure | ||
3516 | * REQP - pointer to SCSI request structure | ||
3517 | * REQPTID(reqp) - reqp's target id | ||
3518 | * REQPNEXT(reqp) - reqp's next pointer | ||
3519 | * REQPNEXTP(reqp) - pointer to reqp's next pointer | ||
3520 | * REQPTIME(reqp) - reqp's time stamp value | ||
3521 | * REQTIMESTAMP() - system time stamp value | ||
3522 | */ | ||
3523 | typedef struct scsi_cmnd REQ, *REQP; | ||
3524 | #define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble)) | ||
3525 | #define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble)) | ||
3526 | #define REQPTID(reqp) ((reqp)->device->id) | ||
3527 | #define REQPTIME(reqp) ((reqp)->SCp.this_residual) | ||
3528 | #define REQTIMESTAMP() (jiffies) | ||
3529 | |||
3530 | #define REQTIMESTAT(function, ascq, reqp, tid) \ | ||
3531 | { \ | ||
3532 | /* | ||
3533 | * If the request time stamp is less than the system time stamp, then \ | ||
3534 | * maybe the system time stamp wrapped. Set the request time to zero.\ | ||
3535 | */ \ | ||
3536 | if (REQPTIME(reqp) <= REQTIMESTAMP()) { \ | ||
3537 | REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \ | ||
3538 | } else { \ | ||
3539 | /* Indicate an error occurred with the assertion. */ \ | ||
3540 | ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \ | ||
3541 | REQPTIME(reqp) = 0; \ | ||
3542 | } \ | ||
3543 | /* Handle first minimum time case without external initialization. */ \ | ||
3544 | if (((ascq)->q_tot_cnt[tid] == 1) || \ | ||
3545 | (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \ | ||
3546 | (ascq)->q_min_tim[tid] = REQPTIME(reqp); \ | ||
3547 | ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \ | ||
3548 | (function), (tid), (ascq)->q_min_tim[tid]); \ | ||
3549 | } \ | ||
3550 | if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \ | ||
3551 | (ascq)->q_max_tim[tid] = REQPTIME(reqp); \ | ||
3552 | ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \ | ||
3553 | (function), tid, (ascq)->q_max_tim[tid]); \ | ||
3554 | } \ | ||
3555 | (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \ | ||
3556 | /* Reset the time stamp field. */ \ | ||
3557 | REQPTIME(reqp) = 0; \ | ||
3558 | } | ||
3559 | |||
3560 | /* asc_enqueue() flags */ | ||
3561 | #define ASC_FRONT 1 | ||
3562 | #define ASC_BACK 2 | ||
3563 | |||
3564 | /* asc_dequeue_list() argument */ | ||
3565 | #define ASC_TID_ALL (-1) | ||
3566 | |||
3567 | /* Return non-zero, if the queue is empty. */ | ||
3568 | #define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0) | ||
3569 | |||
3570 | #define PCI_MAX_SLOT 0x1F | ||
3571 | #define PCI_MAX_BUS 0xFF | ||
3572 | #define PCI_IOADDRESS_MASK 0xFFFE | ||
3573 | #define ASC_PCI_VENDORID 0x10CD | ||
3574 | #define ASC_PCI_DEVICE_ID_CNT 6 /* PCI Device ID count. */ | ||
3575 | #define ASC_PCI_DEVICE_ID_1100 0x1100 | ||
3576 | #define ASC_PCI_DEVICE_ID_1200 0x1200 | ||
3577 | #define ASC_PCI_DEVICE_ID_1300 0x1300 | ||
3578 | #define ASC_PCI_DEVICE_ID_2300 0x2300 /* ASC-3550 */ | ||
3579 | #define ASC_PCI_DEVICE_ID_2500 0x2500 /* ASC-38C0800 */ | ||
3580 | #define ASC_PCI_DEVICE_ID_2700 0x2700 /* ASC-38C1600 */ | ||
3581 | |||
3582 | #ifndef ADVANSYS_STATS | ||
3583 | #define ASC_STATS(shp, counter) | ||
3584 | #define ASC_STATS_ADD(shp, counter, count) | ||
3585 | #else /* ADVANSYS_STATS */ | ||
3586 | #define ASC_STATS(shp, counter) \ | ||
3587 | (ASC_BOARDP(shp)->asc_stats.counter++) | ||
3588 | |||
3589 | #define ASC_STATS_ADD(shp, counter, count) \ | ||
3590 | (ASC_BOARDP(shp)->asc_stats.counter += (count)) | ||
3591 | #endif /* ADVANSYS_STATS */ | ||
3592 | |||
3593 | #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit)) | ||
3594 | |||
3595 | /* If the result wraps when calculating tenths, return 0. */ | ||
3596 | #define ASC_TENTHS(num, den) \ | ||
3597 | (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \ | ||
3598 | 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den))))) | ||
3599 | |||
3600 | /* | ||
3601 | * Display a message to the console. | ||
3602 | */ | ||
3603 | #define ASC_PRINT(s) \ | ||
3604 | { \ | ||
3605 | printk("advansys: "); \ | ||
3606 | printk(s); \ | ||
3607 | } | ||
3608 | |||
3609 | #define ASC_PRINT1(s, a1) \ | ||
3610 | { \ | ||
3611 | printk("advansys: "); \ | ||
3612 | printk((s), (a1)); \ | ||
3613 | } | ||
3614 | |||
3615 | #define ASC_PRINT2(s, a1, a2) \ | ||
3616 | { \ | ||
3617 | printk("advansys: "); \ | ||
3618 | printk((s), (a1), (a2)); \ | ||
3619 | } | ||
3620 | |||
3621 | #define ASC_PRINT3(s, a1, a2, a3) \ | ||
3622 | { \ | ||
3623 | printk("advansys: "); \ | ||
3624 | printk((s), (a1), (a2), (a3)); \ | ||
3625 | } | ||
3626 | |||
3627 | #define ASC_PRINT4(s, a1, a2, a3, a4) \ | ||
3628 | { \ | ||
3629 | printk("advansys: "); \ | ||
3630 | printk((s), (a1), (a2), (a3), (a4)); \ | ||
3631 | } | ||
3632 | |||
3633 | |||
3634 | #ifndef ADVANSYS_DEBUG | ||
3635 | |||
3636 | #define ASC_DBG(lvl, s) | ||
3637 | #define ASC_DBG1(lvl, s, a1) | ||
3638 | #define ASC_DBG2(lvl, s, a1, a2) | ||
3639 | #define ASC_DBG3(lvl, s, a1, a2, a3) | ||
3640 | #define ASC_DBG4(lvl, s, a1, a2, a3, a4) | ||
3641 | #define ASC_DBG_PRT_SCSI_HOST(lvl, s) | ||
3642 | #define ASC_DBG_PRT_SCSI_CMND(lvl, s) | ||
3643 | #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) | ||
3644 | #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) | ||
3645 | #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) | ||
3646 | #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) | ||
3647 | #define ASC_DBG_PRT_HEX(lvl, name, start, length) | ||
3648 | #define ASC_DBG_PRT_CDB(lvl, cdb, len) | ||
3649 | #define ASC_DBG_PRT_SENSE(lvl, sense, len) | ||
3650 | #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) | ||
3651 | |||
3652 | #else /* ADVANSYS_DEBUG */ | ||
3653 | |||
3654 | /* | ||
3655 | * Debugging Message Levels: | ||
3656 | * 0: Errors Only | ||
3657 | * 1: High-Level Tracing | ||
3658 | * 2-N: Verbose Tracing | ||
3659 | */ | ||
3660 | |||
3661 | #define ASC_DBG(lvl, s) \ | ||
3662 | { \ | ||
3663 | if (asc_dbglvl >= (lvl)) { \ | ||
3664 | printk(s); \ | ||
3665 | } \ | ||
3666 | } | ||
3667 | |||
3668 | #define ASC_DBG1(lvl, s, a1) \ | ||
3669 | { \ | ||
3670 | if (asc_dbglvl >= (lvl)) { \ | ||
3671 | printk((s), (a1)); \ | ||
3672 | } \ | ||
3673 | } | ||
3674 | |||
3675 | #define ASC_DBG2(lvl, s, a1, a2) \ | ||
3676 | { \ | ||
3677 | if (asc_dbglvl >= (lvl)) { \ | ||
3678 | printk((s), (a1), (a2)); \ | ||
3679 | } \ | ||
3680 | } | ||
3681 | |||
3682 | #define ASC_DBG3(lvl, s, a1, a2, a3) \ | ||
3683 | { \ | ||
3684 | if (asc_dbglvl >= (lvl)) { \ | ||
3685 | printk((s), (a1), (a2), (a3)); \ | ||
3686 | } \ | ||
3687 | } | ||
3688 | |||
3689 | #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \ | ||
3690 | { \ | ||
3691 | if (asc_dbglvl >= (lvl)) { \ | ||
3692 | printk((s), (a1), (a2), (a3), (a4)); \ | ||
3693 | } \ | ||
3694 | } | ||
3695 | |||
3696 | #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \ | ||
3697 | { \ | ||
3698 | if (asc_dbglvl >= (lvl)) { \ | ||
3699 | asc_prt_scsi_host(s); \ | ||
3700 | } \ | ||
3701 | } | ||
3702 | |||
3703 | #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \ | ||
3704 | { \ | ||
3705 | if (asc_dbglvl >= (lvl)) { \ | ||
3706 | asc_prt_scsi_cmnd(s); \ | ||
3707 | } \ | ||
3708 | } | ||
3709 | |||
3710 | #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \ | ||
3711 | { \ | ||
3712 | if (asc_dbglvl >= (lvl)) { \ | ||
3713 | asc_prt_asc_scsi_q(scsiqp); \ | ||
3714 | } \ | ||
3715 | } | ||
3716 | |||
3717 | #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \ | ||
3718 | { \ | ||
3719 | if (asc_dbglvl >= (lvl)) { \ | ||
3720 | asc_prt_asc_qdone_info(qdone); \ | ||
3721 | } \ | ||
3722 | } | ||
3723 | |||
3724 | #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \ | ||
3725 | { \ | ||
3726 | if (asc_dbglvl >= (lvl)) { \ | ||
3727 | asc_prt_adv_scsi_req_q(scsiqp); \ | ||
3728 | } \ | ||
3729 | } | ||
3730 | |||
3731 | #define ASC_DBG_PRT_HEX(lvl, name, start, length) \ | ||
3732 | { \ | ||
3733 | if (asc_dbglvl >= (lvl)) { \ | ||
3734 | asc_prt_hex((name), (start), (length)); \ | ||
3735 | } \ | ||
3736 | } | ||
3737 | |||
3738 | #define ASC_DBG_PRT_CDB(lvl, cdb, len) \ | ||
3739 | ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len)); | ||
3740 | |||
3741 | #define ASC_DBG_PRT_SENSE(lvl, sense, len) \ | ||
3742 | ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len)); | ||
3743 | |||
3744 | #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \ | ||
3745 | ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len)); | ||
3746 | #endif /* ADVANSYS_DEBUG */ | ||
3747 | |||
3748 | #ifndef ADVANSYS_ASSERT | ||
3749 | #define ASC_ASSERT(a) | ||
3750 | #else /* ADVANSYS_ASSERT */ | ||
3751 | |||
3752 | #define ASC_ASSERT(a) \ | ||
3753 | { \ | ||
3754 | if (!(a)) { \ | ||
3755 | printk("ASC_ASSERT() Failure: file %s, line %d\n", \ | ||
3756 | __FILE__, __LINE__); \ | ||
3757 | } \ | ||
3758 | } | ||
3759 | |||
3760 | #endif /* ADVANSYS_ASSERT */ | ||
3761 | |||
3762 | |||
3763 | /* | ||
3764 | * --- Driver Structures | ||
3765 | */ | ||
3766 | |||
3767 | #ifdef ADVANSYS_STATS | ||
3768 | |||
3769 | /* Per board statistics structure */ | ||
3770 | struct asc_stats { | ||
3771 | /* Driver Entrypoint Statistics */ | ||
3772 | ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */ | ||
3773 | ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */ | ||
3774 | ADV_DCNT biosparam; /* # calls to advansys_biosparam() */ | ||
3775 | ADV_DCNT interrupt; /* # advansys_interrupt() calls */ | ||
3776 | ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */ | ||
3777 | ADV_DCNT done; /* # calls to request's scsi_done function */ | ||
3778 | ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */ | ||
3779 | ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */ | ||
3780 | ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */ | ||
3781 | /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */ | ||
3782 | ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */ | ||
3783 | ADV_DCNT exe_busy; /* # ASC_BUSY returns. */ | ||
3784 | ADV_DCNT exe_error; /* # ASC_ERROR returns. */ | ||
3785 | ADV_DCNT exe_unknown; /* # unknown returns. */ | ||
3786 | /* Data Transfer Statistics */ | ||
3787 | ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */ | ||
3788 | ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */ | ||
3789 | ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */ | ||
3790 | ADV_DCNT sg_elem; /* # scatter-gather elements */ | ||
3791 | ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */ | ||
3792 | }; | ||
3793 | #endif /* ADVANSYS_STATS */ | ||
3794 | |||
3795 | /* | ||
3796 | * Request queuing structure | ||
3797 | */ | ||
3798 | typedef struct asc_queue { | ||
3799 | ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */ | ||
3800 | REQP q_first[ADV_MAX_TID+1]; /* first queued request */ | ||
3801 | REQP q_last[ADV_MAX_TID+1]; /* last queued request */ | ||
3802 | #ifdef ADVANSYS_STATS | ||
3803 | short q_cur_cnt[ADV_MAX_TID+1]; /* current queue count */ | ||
3804 | short q_max_cnt[ADV_MAX_TID+1]; /* maximum queue count */ | ||
3805 | ADV_DCNT q_tot_cnt[ADV_MAX_TID+1]; /* total enqueue count */ | ||
3806 | ADV_DCNT q_tot_tim[ADV_MAX_TID+1]; /* total time queued */ | ||
3807 | ushort q_max_tim[ADV_MAX_TID+1]; /* maximum time queued */ | ||
3808 | ushort q_min_tim[ADV_MAX_TID+1]; /* minimum time queued */ | ||
3809 | #endif /* ADVANSYS_STATS */ | ||
3810 | } asc_queue_t; | ||
3811 | |||
3812 | /* | ||
3813 | * Adv Library Request Structures | ||
3814 | * | ||
3815 | * The following two structures are used to process Wide Board requests. | ||
3816 | * | ||
3817 | * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library | ||
3818 | * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the | ||
3819 | * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the | ||
3820 | * Mid-Level SCSI request structure. | ||
3821 | * | ||
3822 | * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each | ||
3823 | * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux | ||
3824 | * up to 255 scatter-gather elements may be used per request or | ||
3825 | * ADV_SCSI_REQ_Q. | ||
3826 | * | ||
3827 | * Both structures must be 32 byte aligned. | ||
3828 | */ | ||
3829 | typedef struct adv_sgblk { | ||
3830 | ADV_SG_BLOCK sg_block; /* Sgblock structure. */ | ||
3831 | uchar align[32]; /* Sgblock structure padding. */ | ||
3832 | struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */ | ||
3833 | } adv_sgblk_t; | ||
3834 | |||
3835 | typedef struct adv_req { | ||
3836 | ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */ | ||
3837 | uchar align[32]; /* Request structure padding. */ | ||
3838 | struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */ | ||
3839 | adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */ | ||
3840 | struct adv_req *next_reqp; /* Next Request Structure. */ | ||
3841 | } adv_req_t; | ||
3842 | |||
3843 | /* | ||
3844 | * Structure allocated for each board. | ||
3845 | * | ||
3846 | * This structure is allocated by scsi_register() at the end | ||
3847 | * of the 'Scsi_Host' structure starting at the 'hostdata' | ||
3848 | * field. It is guaranteed to be allocated from DMA-able memory. | ||
3849 | */ | ||
3850 | typedef struct asc_board { | ||
3851 | int id; /* Board Id */ | ||
3852 | uint flags; /* Board flags */ | ||
3853 | union { | ||
3854 | ASC_DVC_VAR asc_dvc_var; /* Narrow board */ | ||
3855 | ADV_DVC_VAR adv_dvc_var; /* Wide board */ | ||
3856 | } dvc_var; | ||
3857 | union { | ||
3858 | ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */ | ||
3859 | ADV_DVC_CFG adv_dvc_cfg; /* Wide board */ | ||
3860 | } dvc_cfg; | ||
3861 | ushort asc_n_io_port; /* Number I/O ports. */ | ||
3862 | asc_queue_t active; /* Active command queue */ | ||
3863 | asc_queue_t waiting; /* Waiting command queue */ | ||
3864 | asc_queue_t done; /* Done command queue */ | ||
3865 | ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */ | ||
3866 | struct scsi_device *device[ADV_MAX_TID+1]; /* Mid-Level Scsi Device */ | ||
3867 | ushort reqcnt[ADV_MAX_TID+1]; /* Starvation request count */ | ||
3868 | ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */ | ||
3869 | ushort queue_full_cnt[ADV_MAX_TID+1]; /* Queue full count */ | ||
3870 | union { | ||
3871 | ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */ | ||
3872 | ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */ | ||
3873 | ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */ | ||
3874 | ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */ | ||
3875 | } eep_config; | ||
3876 | ulong last_reset; /* Saved last reset time */ | ||
3877 | spinlock_t lock; /* Board spinlock */ | ||
3878 | #ifdef CONFIG_PROC_FS | ||
3879 | /* /proc/scsi/advansys/[0...] */ | ||
3880 | char *prtbuf; /* /proc print buffer */ | ||
3881 | #endif /* CONFIG_PROC_FS */ | ||
3882 | #ifdef ADVANSYS_STATS | ||
3883 | struct asc_stats asc_stats; /* Board statistics */ | ||
3884 | #endif /* ADVANSYS_STATS */ | ||
3885 | /* | ||
3886 | * The following fields are used only for Narrow Boards. | ||
3887 | */ | ||
3888 | /* The following three structures must be in DMA-able memory. */ | ||
3889 | ASC_SCSI_REQ_Q scsireqq; | ||
3890 | ASC_CAP_INFO cap_info; | ||
3891 | ASC_SCSI_INQUIRY inquiry; | ||
3892 | uchar sdtr_data[ASC_MAX_TID+1]; /* SDTR information */ | ||
3893 | /* | ||
3894 | * The following fields are used only for Wide Boards. | ||
3895 | */ | ||
3896 | void *ioremap_addr; /* I/O Memory remap address. */ | ||
3897 | ushort ioport; /* I/O Port address. */ | ||
3898 | ADV_CARR_T *orig_carrp; /* ADV_CARR_T memory block. */ | ||
3899 | adv_req_t *orig_reqp; /* adv_req_t memory block. */ | ||
3900 | adv_req_t *adv_reqp; /* Request structures. */ | ||
3901 | adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */ | ||
3902 | ushort bios_signature; /* BIOS Signature. */ | ||
3903 | ushort bios_version; /* BIOS Version. */ | ||
3904 | ushort bios_codeseg; /* BIOS Code Segment. */ | ||
3905 | ushort bios_codelen; /* BIOS Code Segment Length. */ | ||
3906 | } asc_board_t; | ||
3907 | |||
3908 | /* | ||
3909 | * PCI configuration structures | ||
3910 | */ | ||
3911 | typedef struct _PCI_DATA_ | ||
3912 | { | ||
3913 | uchar type; | ||
3914 | uchar bus; | ||
3915 | uchar slot; | ||
3916 | uchar func; | ||
3917 | uchar offset; | ||
3918 | } PCI_DATA; | ||
3919 | |||
3920 | typedef struct _PCI_DEVICE_ | ||
3921 | { | ||
3922 | ushort vendorID; | ||
3923 | ushort deviceID; | ||
3924 | ushort slotNumber; | ||
3925 | ushort slotFound; | ||
3926 | uchar busNumber; | ||
3927 | uchar maxBusNumber; | ||
3928 | uchar devFunc; | ||
3929 | ushort startSlot; | ||
3930 | ushort endSlot; | ||
3931 | uchar bridge; | ||
3932 | uchar type; | ||
3933 | } PCI_DEVICE; | ||
3934 | |||
3935 | typedef struct _PCI_CONFIG_SPACE_ | ||
3936 | { | ||
3937 | ushort vendorID; | ||
3938 | ushort deviceID; | ||
3939 | ushort command; | ||
3940 | ushort status; | ||
3941 | uchar revision; | ||
3942 | uchar classCode[3]; | ||
3943 | uchar cacheSize; | ||
3944 | uchar latencyTimer; | ||
3945 | uchar headerType; | ||
3946 | uchar bist; | ||
3947 | ADV_PADDR baseAddress[6]; | ||
3948 | ushort reserved[4]; | ||
3949 | ADV_PADDR optionRomAddr; | ||
3950 | ushort reserved2[4]; | ||
3951 | uchar irqLine; | ||
3952 | uchar irqPin; | ||
3953 | uchar minGnt; | ||
3954 | uchar maxLatency; | ||
3955 | } PCI_CONFIG_SPACE; | ||
3956 | |||
3957 | |||
3958 | /* | ||
3959 | * --- Driver Data | ||
3960 | */ | ||
3961 | |||
3962 | /* Note: All driver global data should be initialized. */ | ||
3963 | |||
3964 | /* Number of boards detected in system. */ | ||
3965 | STATIC int asc_board_count = 0; | ||
3966 | STATIC struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 }; | ||
3967 | |||
3968 | /* Overrun buffer used by all narrow boards. */ | ||
3969 | STATIC uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 }; | ||
3970 | |||
3971 | /* | ||
3972 | * Global structures required to issue a command. | ||
3973 | */ | ||
3974 | STATIC ASC_SCSI_Q asc_scsi_q = { { 0 } }; | ||
3975 | STATIC ASC_SG_HEAD asc_sg_head = { 0 }; | ||
3976 | |||
3977 | /* List of supported bus types. */ | ||
3978 | STATIC ushort asc_bus[ASC_NUM_BUS] __initdata = { | ||
3979 | ASC_IS_ISA, | ||
3980 | ASC_IS_VL, | ||
3981 | ASC_IS_EISA, | ||
3982 | ASC_IS_PCI, | ||
3983 | }; | ||
3984 | |||
3985 | /* | ||
3986 | * Used with the LILO 'advansys' option to eliminate or | ||
3987 | * limit I/O port probing at boot time, cf. advansys_setup(). | ||
3988 | */ | ||
3989 | STATIC int asc_iopflag = ASC_FALSE; | ||
3990 | STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 }; | ||
3991 | |||
3992 | #ifdef ADVANSYS_DEBUG | ||
3993 | STATIC char * | ||
3994 | asc_bus_name[ASC_NUM_BUS] = { | ||
3995 | "ASC_IS_ISA", | ||
3996 | "ASC_IS_VL", | ||
3997 | "ASC_IS_EISA", | ||
3998 | "ASC_IS_PCI", | ||
3999 | }; | ||
4000 | |||
4001 | STATIC int asc_dbglvl = 3; | ||
4002 | #endif /* ADVANSYS_DEBUG */ | ||
4003 | |||
4004 | /* Declaration for Asc Library internal data referenced by driver. */ | ||
4005 | STATIC PortAddr _asc_def_iop_base[]; | ||
4006 | |||
4007 | |||
4008 | /* | ||
4009 | * --- Driver Function Prototypes | ||
4010 | * | ||
4011 | * advansys.h contains function prototypes for functions global to Linux. | ||
4012 | */ | ||
4013 | |||
4014 | STATIC irqreturn_t advansys_interrupt(int, void *, struct pt_regs *); | ||
4015 | STATIC int advansys_slave_configure(struct scsi_device *); | ||
4016 | STATIC void asc_scsi_done_list(struct scsi_cmnd *); | ||
4017 | STATIC int asc_execute_scsi_cmnd(struct scsi_cmnd *); | ||
4018 | STATIC int asc_build_req(asc_board_t *, struct scsi_cmnd *); | ||
4019 | STATIC int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **); | ||
4020 | STATIC int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int); | ||
4021 | STATIC void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *); | ||
4022 | STATIC void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *); | ||
4023 | STATIC void adv_async_callback(ADV_DVC_VAR *, uchar); | ||
4024 | STATIC void asc_enqueue(asc_queue_t *, REQP, int); | ||
4025 | STATIC REQP asc_dequeue(asc_queue_t *, int); | ||
4026 | STATIC REQP asc_dequeue_list(asc_queue_t *, REQP *, int); | ||
4027 | STATIC int asc_rmqueue(asc_queue_t *, REQP); | ||
4028 | STATIC void asc_execute_queue(asc_queue_t *); | ||
4029 | #ifdef CONFIG_PROC_FS | ||
4030 | STATIC int asc_proc_copy(off_t, off_t, char *, int , char *, int); | ||
4031 | STATIC int asc_prt_board_devices(struct Scsi_Host *, char *, int); | ||
4032 | STATIC int asc_prt_adv_bios(struct Scsi_Host *, char *, int); | ||
4033 | STATIC int asc_get_eeprom_string(ushort *serialnum, uchar *cp); | ||
4034 | STATIC int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int); | ||
4035 | STATIC int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int); | ||
4036 | STATIC int asc_prt_driver_conf(struct Scsi_Host *, char *, int); | ||
4037 | STATIC int asc_prt_asc_board_info(struct Scsi_Host *, char *, int); | ||
4038 | STATIC int asc_prt_adv_board_info(struct Scsi_Host *, char *, int); | ||
4039 | STATIC int asc_prt_line(char *, int, char *fmt, ...); | ||
4040 | #endif /* CONFIG_PROC_FS */ | ||
4041 | |||
4042 | /* Declaration for Asc Library internal functions referenced by driver. */ | ||
4043 | STATIC int AscFindSignature(PortAddr); | ||
4044 | STATIC ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort); | ||
4045 | |||
4046 | /* Statistics function prototypes. */ | ||
4047 | #ifdef ADVANSYS_STATS | ||
4048 | #ifdef CONFIG_PROC_FS | ||
4049 | STATIC int asc_prt_board_stats(struct Scsi_Host *, char *, int); | ||
4050 | STATIC int asc_prt_target_stats(struct Scsi_Host *, int, char *, int); | ||
4051 | #endif /* CONFIG_PROC_FS */ | ||
4052 | #endif /* ADVANSYS_STATS */ | ||
4053 | |||
4054 | /* Debug function prototypes. */ | ||
4055 | #ifdef ADVANSYS_DEBUG | ||
4056 | STATIC void asc_prt_scsi_host(struct Scsi_Host *); | ||
4057 | STATIC void asc_prt_scsi_cmnd(struct scsi_cmnd *); | ||
4058 | STATIC void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *); | ||
4059 | STATIC void asc_prt_asc_dvc_var(ASC_DVC_VAR *); | ||
4060 | STATIC void asc_prt_asc_scsi_q(ASC_SCSI_Q *); | ||
4061 | STATIC void asc_prt_asc_qdone_info(ASC_QDONE_INFO *); | ||
4062 | STATIC void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *); | ||
4063 | STATIC void asc_prt_adv_dvc_var(ADV_DVC_VAR *); | ||
4064 | STATIC void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *); | ||
4065 | STATIC void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *); | ||
4066 | STATIC void asc_prt_hex(char *f, uchar *, int); | ||
4067 | #endif /* ADVANSYS_DEBUG */ | ||
4068 | |||
4069 | |||
4070 | /* | ||
4071 | * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions | ||
4072 | */ | ||
4073 | |||
4074 | #ifdef CONFIG_PROC_FS | ||
4075 | /* | ||
4076 | * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)] | ||
4077 | * | ||
4078 | * *buffer: I/O buffer | ||
4079 | * **start: if inout == FALSE pointer into buffer where user read should start | ||
4080 | * offset: current offset into a /proc/scsi/advansys/[0...] file | ||
4081 | * length: length of buffer | ||
4082 | * hostno: Scsi_Host host_no | ||
4083 | * inout: TRUE - user is writing; FALSE - user is reading | ||
4084 | * | ||
4085 | * Return the number of bytes read from or written to a | ||
4086 | * /proc/scsi/advansys/[0...] file. | ||
4087 | * | ||
4088 | * Note: This function uses the per board buffer 'prtbuf' which is | ||
4089 | * allocated when the board is initialized in advansys_detect(). The | ||
4090 | * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is | ||
4091 | * used to write to the buffer. The way asc_proc_copy() is written | ||
4092 | * if 'prtbuf' is too small it will not be overwritten. Instead the | ||
4093 | * user just won't get all the available statistics. | ||
4094 | */ | ||
4095 | int | ||
4096 | advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | ||
4097 | off_t offset, int length, int inout) | ||
4098 | { | ||
4099 | struct Scsi_Host *shp; | ||
4100 | asc_board_t *boardp; | ||
4101 | int i; | ||
4102 | char *cp; | ||
4103 | int cplen; | ||
4104 | int cnt; | ||
4105 | int totcnt; | ||
4106 | int leftlen; | ||
4107 | char *curbuf; | ||
4108 | off_t advoffset; | ||
4109 | #ifdef ADVANSYS_STATS | ||
4110 | int tgt_id; | ||
4111 | #endif /* ADVANSYS_STATS */ | ||
4112 | |||
4113 | ASC_DBG(1, "advansys_proc_info: begin\n"); | ||
4114 | |||
4115 | /* | ||
4116 | * User write not supported. | ||
4117 | */ | ||
4118 | if (inout == TRUE) { | ||
4119 | return(-ENOSYS); | ||
4120 | } | ||
4121 | |||
4122 | /* | ||
4123 | * User read of /proc/scsi/advansys/[0...] file. | ||
4124 | */ | ||
4125 | |||
4126 | /* Find the specified board. */ | ||
4127 | for (i = 0; i < asc_board_count; i++) { | ||
4128 | if (asc_host[i]->host_no == shost->host_no) { | ||
4129 | break; | ||
4130 | } | ||
4131 | } | ||
4132 | if (i == asc_board_count) { | ||
4133 | return(-ENOENT); | ||
4134 | } | ||
4135 | |||
4136 | shp = asc_host[i]; | ||
4137 | boardp = ASC_BOARDP(shp); | ||
4138 | |||
4139 | /* Copy read data starting at the beginning of the buffer. */ | ||
4140 | *start = buffer; | ||
4141 | curbuf = buffer; | ||
4142 | advoffset = 0; | ||
4143 | totcnt = 0; | ||
4144 | leftlen = length; | ||
4145 | |||
4146 | /* | ||
4147 | * Get board configuration information. | ||
4148 | * | ||
4149 | * advansys_info() returns the board string from its own static buffer. | ||
4150 | */ | ||
4151 | cp = (char *) advansys_info(shp); | ||
4152 | strcat(cp, "\n"); | ||
4153 | cplen = strlen(cp); | ||
4154 | /* Copy board information. */ | ||
4155 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4156 | totcnt += cnt; | ||
4157 | leftlen -= cnt; | ||
4158 | if (leftlen == 0) { | ||
4159 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4160 | return totcnt; | ||
4161 | } | ||
4162 | advoffset += cplen; | ||
4163 | curbuf += cnt; | ||
4164 | |||
4165 | /* | ||
4166 | * Display Wide Board BIOS Information. | ||
4167 | */ | ||
4168 | if (ASC_WIDE_BOARD(boardp)) { | ||
4169 | cp = boardp->prtbuf; | ||
4170 | cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE); | ||
4171 | ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); | ||
4172 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4173 | totcnt += cnt; | ||
4174 | leftlen -= cnt; | ||
4175 | if (leftlen == 0) { | ||
4176 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4177 | return totcnt; | ||
4178 | } | ||
4179 | advoffset += cplen; | ||
4180 | curbuf += cnt; | ||
4181 | } | ||
4182 | |||
4183 | /* | ||
4184 | * Display driver information for each device attached to the board. | ||
4185 | */ | ||
4186 | cp = boardp->prtbuf; | ||
4187 | cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE); | ||
4188 | ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); | ||
4189 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4190 | totcnt += cnt; | ||
4191 | leftlen -= cnt; | ||
4192 | if (leftlen == 0) { | ||
4193 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4194 | return totcnt; | ||
4195 | } | ||
4196 | advoffset += cplen; | ||
4197 | curbuf += cnt; | ||
4198 | |||
4199 | /* | ||
4200 | * Display EEPROM configuration for the board. | ||
4201 | */ | ||
4202 | cp = boardp->prtbuf; | ||
4203 | if (ASC_NARROW_BOARD(boardp)) { | ||
4204 | cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE); | ||
4205 | } else { | ||
4206 | cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE); | ||
4207 | } | ||
4208 | ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); | ||
4209 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4210 | totcnt += cnt; | ||
4211 | leftlen -= cnt; | ||
4212 | if (leftlen == 0) { | ||
4213 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4214 | return totcnt; | ||
4215 | } | ||
4216 | advoffset += cplen; | ||
4217 | curbuf += cnt; | ||
4218 | |||
4219 | /* | ||
4220 | * Display driver configuration and information for the board. | ||
4221 | */ | ||
4222 | cp = boardp->prtbuf; | ||
4223 | cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE); | ||
4224 | ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); | ||
4225 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4226 | totcnt += cnt; | ||
4227 | leftlen -= cnt; | ||
4228 | if (leftlen == 0) { | ||
4229 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4230 | return totcnt; | ||
4231 | } | ||
4232 | advoffset += cplen; | ||
4233 | curbuf += cnt; | ||
4234 | |||
4235 | #ifdef ADVANSYS_STATS | ||
4236 | /* | ||
4237 | * Display driver statistics for the board. | ||
4238 | */ | ||
4239 | cp = boardp->prtbuf; | ||
4240 | cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE); | ||
4241 | ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE); | ||
4242 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4243 | totcnt += cnt; | ||
4244 | leftlen -= cnt; | ||
4245 | if (leftlen == 0) { | ||
4246 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4247 | return totcnt; | ||
4248 | } | ||
4249 | advoffset += cplen; | ||
4250 | curbuf += cnt; | ||
4251 | |||
4252 | /* | ||
4253 | * Display driver statistics for each target. | ||
4254 | */ | ||
4255 | for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) { | ||
4256 | cp = boardp->prtbuf; | ||
4257 | cplen = asc_prt_target_stats(shp, tgt_id, cp, ASC_PRTBUF_SIZE); | ||
4258 | ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE); | ||
4259 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4260 | totcnt += cnt; | ||
4261 | leftlen -= cnt; | ||
4262 | if (leftlen == 0) { | ||
4263 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4264 | return totcnt; | ||
4265 | } | ||
4266 | advoffset += cplen; | ||
4267 | curbuf += cnt; | ||
4268 | } | ||
4269 | #endif /* ADVANSYS_STATS */ | ||
4270 | |||
4271 | /* | ||
4272 | * Display Asc Library dynamic configuration information | ||
4273 | * for the board. | ||
4274 | */ | ||
4275 | cp = boardp->prtbuf; | ||
4276 | if (ASC_NARROW_BOARD(boardp)) { | ||
4277 | cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE); | ||
4278 | } else { | ||
4279 | cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE); | ||
4280 | } | ||
4281 | ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); | ||
4282 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4283 | totcnt += cnt; | ||
4284 | leftlen -= cnt; | ||
4285 | if (leftlen == 0) { | ||
4286 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4287 | return totcnt; | ||
4288 | } | ||
4289 | advoffset += cplen; | ||
4290 | curbuf += cnt; | ||
4291 | |||
4292 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4293 | |||
4294 | return totcnt; | ||
4295 | } | ||
4296 | #endif /* CONFIG_PROC_FS */ | ||
4297 | |||
4298 | /* | ||
4299 | * advansys_detect() | ||
4300 | * | ||
4301 | * Detect function for AdvanSys adapters. | ||
4302 | * | ||
4303 | * Argument is a pointer to the host driver's scsi_hosts entry. | ||
4304 | * | ||
4305 | * Return number of adapters found. | ||
4306 | * | ||
4307 | * Note: Because this function is called during system initialization | ||
4308 | * it must not call SCSI mid-level functions including scsi_malloc() | ||
4309 | * and scsi_free(). | ||
4310 | */ | ||
4311 | int __init | ||
4312 | advansys_detect(struct scsi_host_template *tpnt) | ||
4313 | { | ||
4314 | static int detect_called = ASC_FALSE; | ||
4315 | int iop; | ||
4316 | int bus; | ||
4317 | struct Scsi_Host *shp = NULL; | ||
4318 | asc_board_t *boardp = NULL; | ||
4319 | ASC_DVC_VAR *asc_dvc_varp = NULL; | ||
4320 | ADV_DVC_VAR *adv_dvc_varp = NULL; | ||
4321 | adv_sgblk_t *sgp = NULL; | ||
4322 | int ioport = 0; | ||
4323 | int share_irq = FALSE; | ||
4324 | int iolen = 0; | ||
4325 | struct device *dev = NULL; | ||
4326 | #ifdef CONFIG_PCI | ||
4327 | int pci_init_search = 0; | ||
4328 | struct pci_dev *pci_devicep[ASC_NUM_BOARD_SUPPORTED]; | ||
4329 | int pci_card_cnt_max = 0; | ||
4330 | int pci_card_cnt = 0; | ||
4331 | struct pci_dev *pci_devp = NULL; | ||
4332 | int pci_device_id_cnt = 0; | ||
4333 | unsigned int pci_device_id[ASC_PCI_DEVICE_ID_CNT] = { | ||
4334 | ASC_PCI_DEVICE_ID_1100, | ||
4335 | ASC_PCI_DEVICE_ID_1200, | ||
4336 | ASC_PCI_DEVICE_ID_1300, | ||
4337 | ASC_PCI_DEVICE_ID_2300, | ||
4338 | ASC_PCI_DEVICE_ID_2500, | ||
4339 | ASC_PCI_DEVICE_ID_2700 | ||
4340 | }; | ||
4341 | ADV_PADDR pci_memory_address; | ||
4342 | #endif /* CONFIG_PCI */ | ||
4343 | int warn_code, err_code; | ||
4344 | int ret; | ||
4345 | |||
4346 | if (detect_called == ASC_FALSE) { | ||
4347 | detect_called = ASC_TRUE; | ||
4348 | } else { | ||
4349 | printk("AdvanSys SCSI: advansys_detect() multiple calls ignored\n"); | ||
4350 | return 0; | ||
4351 | } | ||
4352 | |||
4353 | ASC_DBG(1, "advansys_detect: begin\n"); | ||
4354 | |||
4355 | asc_board_count = 0; | ||
4356 | |||
4357 | /* | ||
4358 | * If I/O port probing has been modified, then verify and | ||
4359 | * clean-up the 'asc_ioport' list. | ||
4360 | */ | ||
4361 | if (asc_iopflag == ASC_TRUE) { | ||
4362 | for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) { | ||
4363 | ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n", | ||
4364 | ioport, asc_ioport[ioport]); | ||
4365 | if (asc_ioport[ioport] != 0) { | ||
4366 | for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) { | ||
4367 | if (_asc_def_iop_base[iop] == asc_ioport[ioport]) { | ||
4368 | break; | ||
4369 | } | ||
4370 | } | ||
4371 | if (iop == ASC_IOADR_TABLE_MAX_IX) { | ||
4372 | printk( | ||
4373 | "AdvanSys SCSI: specified I/O Port 0x%X is invalid\n", | ||
4374 | asc_ioport[ioport]); | ||
4375 | asc_ioport[ioport] = 0; | ||
4376 | } | ||
4377 | } | ||
4378 | } | ||
4379 | ioport = 0; | ||
4380 | } | ||
4381 | |||
4382 | for (bus = 0; bus < ASC_NUM_BUS; bus++) { | ||
4383 | |||
4384 | ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n", | ||
4385 | bus, asc_bus_name[bus]); | ||
4386 | iop = 0; | ||
4387 | |||
4388 | while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) { | ||
4389 | |||
4390 | ASC_DBG1(2, "advansys_detect: asc_board_count %d\n", | ||
4391 | asc_board_count); | ||
4392 | |||
4393 | switch (asc_bus[bus]) { | ||
4394 | case ASC_IS_ISA: | ||
4395 | case ASC_IS_VL: | ||
4396 | #ifdef CONFIG_ISA | ||
4397 | if (asc_iopflag == ASC_FALSE) { | ||
4398 | iop = AscSearchIOPortAddr(iop, asc_bus[bus]); | ||
4399 | } else { | ||
4400 | /* | ||
4401 | * ISA and VL I/O port scanning has either been | ||
4402 | * eliminated or limited to selected ports on | ||
4403 | * the LILO command line, /etc/lilo.conf, or | ||
4404 | * by setting variables when the module was loaded. | ||
4405 | */ | ||
4406 | ASC_DBG(1, "advansys_detect: I/O port scanning modified\n"); | ||
4407 | ioport_try_again: | ||
4408 | iop = 0; | ||
4409 | for (; ioport < ASC_NUM_IOPORT_PROBE; ioport++) { | ||
4410 | if ((iop = asc_ioport[ioport]) != 0) { | ||
4411 | break; | ||
4412 | } | ||
4413 | } | ||
4414 | if (iop) { | ||
4415 | ASC_DBG1(1, | ||
4416 | "advansys_detect: probing I/O port 0x%x...\n", | ||
4417 | iop); | ||
4418 | if (check_region(iop, ASC_IOADR_GAP) != 0) { | ||
4419 | printk( | ||
4420 | "AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop); | ||
4421 | /* Don't try this I/O port twice. */ | ||
4422 | asc_ioport[ioport] = 0; | ||
4423 | goto ioport_try_again; | ||
4424 | } else if (AscFindSignature(iop) == ASC_FALSE) { | ||
4425 | printk( | ||
4426 | "AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop); | ||
4427 | /* Don't try this I/O port twice. */ | ||
4428 | asc_ioport[ioport] = 0; | ||
4429 | goto ioport_try_again; | ||
4430 | } else { | ||
4431 | /* | ||
4432 | * If this isn't an ISA board, then it must be | ||
4433 | * a VL board. If currently looking an ISA | ||
4434 | * board is being looked for then try for | ||
4435 | * another ISA board in 'asc_ioport'. | ||
4436 | */ | ||
4437 | if (asc_bus[bus] == ASC_IS_ISA && | ||
4438 | (AscGetChipVersion(iop, ASC_IS_ISA) & | ||
4439 | ASC_CHIP_VER_ISA_BIT) == 0) { | ||
4440 | /* | ||
4441 | * Don't clear 'asc_ioport[ioport]'. Try | ||
4442 | * this board again for VL. Increment | ||
4443 | * 'ioport' past this board. | ||
4444 | */ | ||
4445 | ioport++; | ||
4446 | goto ioport_try_again; | ||
4447 | } | ||
4448 | } | ||
4449 | /* | ||
4450 | * This board appears good, don't try the I/O port | ||
4451 | * again by clearing its value. Increment 'ioport' | ||
4452 | * for the next iteration. | ||
4453 | */ | ||
4454 | asc_ioport[ioport++] = 0; | ||
4455 | } | ||
4456 | } | ||
4457 | #endif /* CONFIG_ISA */ | ||
4458 | break; | ||
4459 | |||
4460 | case ASC_IS_EISA: | ||
4461 | #ifdef CONFIG_ISA | ||
4462 | iop = AscSearchIOPortAddr(iop, asc_bus[bus]); | ||
4463 | #endif /* CONFIG_ISA */ | ||
4464 | break; | ||
4465 | |||
4466 | case ASC_IS_PCI: | ||
4467 | #ifdef CONFIG_PCI | ||
4468 | if (pci_init_search == 0) { | ||
4469 | int i, j; | ||
4470 | |||
4471 | pci_init_search = 1; | ||
4472 | |||
4473 | /* Find all PCI cards. */ | ||
4474 | while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) { | ||
4475 | if ((pci_devp = pci_find_device(ASC_PCI_VENDORID, | ||
4476 | pci_device_id[pci_device_id_cnt], pci_devp)) == | ||
4477 | NULL) { | ||
4478 | pci_device_id_cnt++; | ||
4479 | } else { | ||
4480 | if (pci_enable_device(pci_devp) == 0) { | ||
4481 | pci_devicep[pci_card_cnt_max++] = pci_devp; | ||
4482 | } | ||
4483 | } | ||
4484 | } | ||
4485 | |||
4486 | /* | ||
4487 | * Sort PCI cards in ascending order by PCI Bus, Slot, | ||
4488 | * and Device Number. | ||
4489 | */ | ||
4490 | for (i = 0; i < pci_card_cnt_max - 1; i++) | ||
4491 | { | ||
4492 | for (j = i + 1; j < pci_card_cnt_max; j++) { | ||
4493 | if ((pci_devicep[j]->bus->number < | ||
4494 | pci_devicep[i]->bus->number) || | ||
4495 | ((pci_devicep[j]->bus->number == | ||
4496 | pci_devicep[i]->bus->number) && | ||
4497 | (pci_devicep[j]->devfn < | ||
4498 | pci_devicep[i]->devfn))) { | ||
4499 | pci_devp = pci_devicep[i]; | ||
4500 | pci_devicep[i] = pci_devicep[j]; | ||
4501 | pci_devicep[j] = pci_devp; | ||
4502 | } | ||
4503 | } | ||
4504 | } | ||
4505 | |||
4506 | pci_card_cnt = 0; | ||
4507 | } else { | ||
4508 | pci_card_cnt++; | ||
4509 | } | ||
4510 | |||
4511 | if (pci_card_cnt == pci_card_cnt_max) { | ||
4512 | iop = 0; | ||
4513 | } else { | ||
4514 | pci_devp = pci_devicep[pci_card_cnt]; | ||
4515 | |||
4516 | ASC_DBG2(2, | ||
4517 | "advansys_detect: devfn %d, bus number %d\n", | ||
4518 | pci_devp->devfn, pci_devp->bus->number); | ||
4519 | iop = pci_resource_start(pci_devp, 0); | ||
4520 | ASC_DBG2(1, | ||
4521 | "advansys_detect: vendorID %X, deviceID %X\n", | ||
4522 | pci_devp->vendor, pci_devp->device); | ||
4523 | ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n", | ||
4524 | iop, pci_devp->irq); | ||
4525 | } | ||
4526 | if(pci_devp) | ||
4527 | dev = &pci_devp->dev; | ||
4528 | |||
4529 | #endif /* CONFIG_PCI */ | ||
4530 | break; | ||
4531 | |||
4532 | default: | ||
4533 | ASC_PRINT1("advansys_detect: unknown bus type: %d\n", | ||
4534 | asc_bus[bus]); | ||
4535 | break; | ||
4536 | } | ||
4537 | ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop); | ||
4538 | |||
4539 | /* | ||
4540 | * Adapter not found, try next bus type. | ||
4541 | */ | ||
4542 | if (iop == 0) { | ||
4543 | break; | ||
4544 | } | ||
4545 | |||
4546 | /* | ||
4547 | * Adapter found. | ||
4548 | * | ||
4549 | * Register the adapter, get its configuration, and | ||
4550 | * initialize it. | ||
4551 | */ | ||
4552 | ASC_DBG(2, "advansys_detect: scsi_register()\n"); | ||
4553 | shp = scsi_register(tpnt, sizeof(asc_board_t)); | ||
4554 | |||
4555 | if (shp == NULL) { | ||
4556 | continue; | ||
4557 | } | ||
4558 | |||
4559 | scsi_set_device(shp, dev); | ||
4560 | |||
4561 | /* Save a pointer to the Scsi_Host of each board found. */ | ||
4562 | asc_host[asc_board_count++] = shp; | ||
4563 | |||
4564 | /* Initialize private per board data */ | ||
4565 | boardp = ASC_BOARDP(shp); | ||
4566 | memset(boardp, 0, sizeof(asc_board_t)); | ||
4567 | boardp->id = asc_board_count - 1; | ||
4568 | |||
4569 | /* Initialize spinlock. */ | ||
4570 | spin_lock_init(&boardp->lock); | ||
4571 | |||
4572 | /* | ||
4573 | * Handle both narrow and wide boards. | ||
4574 | * | ||
4575 | * If a Wide board was detected, set the board structure | ||
4576 | * wide board flag. Set-up the board structure based on | ||
4577 | * the board type. | ||
4578 | */ | ||
4579 | #ifdef CONFIG_PCI | ||
4580 | if (asc_bus[bus] == ASC_IS_PCI && | ||
4581 | (pci_devp->device == ASC_PCI_DEVICE_ID_2300 || | ||
4582 | pci_devp->device == ASC_PCI_DEVICE_ID_2500 || | ||
4583 | pci_devp->device == ASC_PCI_DEVICE_ID_2700)) | ||
4584 | { | ||
4585 | boardp->flags |= ASC_IS_WIDE_BOARD; | ||
4586 | } | ||
4587 | #endif /* CONFIG_PCI */ | ||
4588 | |||
4589 | if (ASC_NARROW_BOARD(boardp)) { | ||
4590 | ASC_DBG(1, "advansys_detect: narrow board\n"); | ||
4591 | asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; | ||
4592 | asc_dvc_varp->bus_type = asc_bus[bus]; | ||
4593 | asc_dvc_varp->drv_ptr = boardp; | ||
4594 | asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg; | ||
4595 | asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0]; | ||
4596 | asc_dvc_varp->iop_base = iop; | ||
4597 | asc_dvc_varp->isr_callback = asc_isr_callback; | ||
4598 | } else { | ||
4599 | ASC_DBG(1, "advansys_detect: wide board\n"); | ||
4600 | adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; | ||
4601 | adv_dvc_varp->drv_ptr = boardp; | ||
4602 | adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg; | ||
4603 | adv_dvc_varp->isr_callback = adv_isr_callback; | ||
4604 | adv_dvc_varp->async_callback = adv_async_callback; | ||
4605 | #ifdef CONFIG_PCI | ||
4606 | if (pci_devp->device == ASC_PCI_DEVICE_ID_2300) | ||
4607 | { | ||
4608 | ASC_DBG(1, "advansys_detect: ASC-3550\n"); | ||
4609 | adv_dvc_varp->chip_type = ADV_CHIP_ASC3550; | ||
4610 | } else if (pci_devp->device == ASC_PCI_DEVICE_ID_2500) | ||
4611 | { | ||
4612 | ASC_DBG(1, "advansys_detect: ASC-38C0800\n"); | ||
4613 | adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800; | ||
4614 | } else | ||
4615 | { | ||
4616 | ASC_DBG(1, "advansys_detect: ASC-38C1600\n"); | ||
4617 | adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600; | ||
4618 | } | ||
4619 | #endif /* CONFIG_PCI */ | ||
4620 | |||
4621 | /* | ||
4622 | * Map the board's registers into virtual memory for | ||
4623 | * PCI slave access. Only memory accesses are used to | ||
4624 | * access the board's registers. | ||
4625 | * | ||
4626 | * Note: The PCI register base address is not always | ||
4627 | * page aligned, but the address passed to ioremap() | ||
4628 | * must be page aligned. It is guaranteed that the | ||
4629 | * PCI register base address will not cross a page | ||
4630 | * boundary. | ||
4631 | */ | ||
4632 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) | ||
4633 | { | ||
4634 | iolen = ADV_3550_IOLEN; | ||
4635 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) | ||
4636 | { | ||
4637 | iolen = ADV_38C0800_IOLEN; | ||
4638 | } else | ||
4639 | { | ||
4640 | iolen = ADV_38C1600_IOLEN; | ||
4641 | } | ||
4642 | #ifdef CONFIG_PCI | ||
4643 | pci_memory_address = pci_resource_start(pci_devp, 1); | ||
4644 | ASC_DBG1(1, "advansys_detect: pci_memory_address: 0x%lx\n", | ||
4645 | (ulong) pci_memory_address); | ||
4646 | if ((boardp->ioremap_addr = | ||
4647 | ioremap(pci_memory_address & PAGE_MASK, | ||
4648 | PAGE_SIZE)) == 0) { | ||
4649 | ASC_PRINT3( | ||
4650 | "advansys_detect: board %d: ioremap(%x, %d) returned NULL\n", | ||
4651 | boardp->id, pci_memory_address, iolen); | ||
4652 | scsi_unregister(shp); | ||
4653 | asc_board_count--; | ||
4654 | continue; | ||
4655 | } | ||
4656 | ASC_DBG1(1, "advansys_detect: ioremap_addr: 0x%lx\n", | ||
4657 | (ulong) boardp->ioremap_addr); | ||
4658 | adv_dvc_varp->iop_base = (AdvPortAddr) | ||
4659 | (boardp->ioremap_addr + | ||
4660 | (pci_memory_address - (pci_memory_address & PAGE_MASK))); | ||
4661 | ASC_DBG1(1, "advansys_detect: iop_base: 0x%lx\n", | ||
4662 | adv_dvc_varp->iop_base); | ||
4663 | #endif /* CONFIG_PCI */ | ||
4664 | |||
4665 | /* | ||
4666 | * Even though it isn't used to access wide boards, other | ||
4667 | * than for the debug line below, save I/O Port address so | ||
4668 | * that it can be reported. | ||
4669 | */ | ||
4670 | boardp->ioport = iop; | ||
4671 | |||
4672 | ASC_DBG2(1, | ||
4673 | "advansys_detect: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n", | ||
4674 | (ushort) inp(iop + 1), (ushort) inpw(iop)); | ||
4675 | } | ||
4676 | |||
4677 | #ifdef CONFIG_PROC_FS | ||
4678 | /* | ||
4679 | * Allocate buffer for printing information from | ||
4680 | * /proc/scsi/advansys/[0...]. | ||
4681 | */ | ||
4682 | if ((boardp->prtbuf = | ||
4683 | kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) { | ||
4684 | ASC_PRINT3( | ||
4685 | "advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n", | ||
4686 | boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC); | ||
4687 | scsi_unregister(shp); | ||
4688 | asc_board_count--; | ||
4689 | continue; | ||
4690 | } | ||
4691 | #endif /* CONFIG_PROC_FS */ | ||
4692 | |||
4693 | if (ASC_NARROW_BOARD(boardp)) { | ||
4694 | asc_dvc_varp->cfg->dev = dev; | ||
4695 | /* | ||
4696 | * Set the board bus type and PCI IRQ before | ||
4697 | * calling AscInitGetConfig(). | ||
4698 | */ | ||
4699 | switch (asc_dvc_varp->bus_type) { | ||
4700 | #ifdef CONFIG_ISA | ||
4701 | case ASC_IS_ISA: | ||
4702 | shp->unchecked_isa_dma = TRUE; | ||
4703 | share_irq = FALSE; | ||
4704 | break; | ||
4705 | case ASC_IS_VL: | ||
4706 | shp->unchecked_isa_dma = FALSE; | ||
4707 | share_irq = FALSE; | ||
4708 | break; | ||
4709 | case ASC_IS_EISA: | ||
4710 | shp->unchecked_isa_dma = FALSE; | ||
4711 | share_irq = TRUE; | ||
4712 | break; | ||
4713 | #endif /* CONFIG_ISA */ | ||
4714 | #ifdef CONFIG_PCI | ||
4715 | case ASC_IS_PCI: | ||
4716 | shp->irq = asc_dvc_varp->irq_no = pci_devp->irq; | ||
4717 | asc_dvc_varp->cfg->pci_slot_info = | ||
4718 | ASC_PCI_MKID(pci_devp->bus->number, | ||
4719 | PCI_SLOT(pci_devp->devfn), | ||
4720 | PCI_FUNC(pci_devp->devfn)); | ||
4721 | shp->unchecked_isa_dma = FALSE; | ||
4722 | share_irq = TRUE; | ||
4723 | break; | ||
4724 | #endif /* CONFIG_PCI */ | ||
4725 | default: | ||
4726 | ASC_PRINT2( | ||
4727 | "advansys_detect: board %d: unknown adapter type: %d\n", | ||
4728 | boardp->id, asc_dvc_varp->bus_type); | ||
4729 | shp->unchecked_isa_dma = TRUE; | ||
4730 | share_irq = FALSE; | ||
4731 | break; | ||
4732 | } | ||
4733 | } else { | ||
4734 | adv_dvc_varp->cfg->dev = dev; | ||
4735 | /* | ||
4736 | * For Wide boards set PCI information before calling | ||
4737 | * AdvInitGetConfig(). | ||
4738 | */ | ||
4739 | #ifdef CONFIG_PCI | ||
4740 | shp->irq = adv_dvc_varp->irq_no = pci_devp->irq; | ||
4741 | adv_dvc_varp->cfg->pci_slot_info = | ||
4742 | ASC_PCI_MKID(pci_devp->bus->number, | ||
4743 | PCI_SLOT(pci_devp->devfn), | ||
4744 | PCI_FUNC(pci_devp->devfn)); | ||
4745 | shp->unchecked_isa_dma = FALSE; | ||
4746 | share_irq = TRUE; | ||
4747 | #endif /* CONFIG_PCI */ | ||
4748 | } | ||
4749 | |||
4750 | /* | ||
4751 | * Read the board configuration. | ||
4752 | */ | ||
4753 | if (ASC_NARROW_BOARD(boardp)) { | ||
4754 | /* | ||
4755 | * NOTE: AscInitGetConfig() may change the board's | ||
4756 | * bus_type value. The asc_bus[bus] value should no | ||
4757 | * longer be used. If the bus_type field must be | ||
4758 | * referenced only use the bit-wise AND operator "&". | ||
4759 | */ | ||
4760 | ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n"); | ||
4761 | switch(ret = AscInitGetConfig(asc_dvc_varp)) { | ||
4762 | case 0: /* No error */ | ||
4763 | break; | ||
4764 | case ASC_WARN_IO_PORT_ROTATE: | ||
4765 | ASC_PRINT1( | ||
4766 | "AscInitGetConfig: board %d: I/O port address modified\n", | ||
4767 | boardp->id); | ||
4768 | break; | ||
4769 | case ASC_WARN_AUTO_CONFIG: | ||
4770 | ASC_PRINT1( | ||
4771 | "AscInitGetConfig: board %d: I/O port increment switch enabled\n", | ||
4772 | boardp->id); | ||
4773 | break; | ||
4774 | case ASC_WARN_EEPROM_CHKSUM: | ||
4775 | ASC_PRINT1( | ||
4776 | "AscInitGetConfig: board %d: EEPROM checksum error\n", | ||
4777 | boardp->id); | ||
4778 | break; | ||
4779 | case ASC_WARN_IRQ_MODIFIED: | ||
4780 | ASC_PRINT1( | ||
4781 | "AscInitGetConfig: board %d: IRQ modified\n", | ||
4782 | boardp->id); | ||
4783 | break; | ||
4784 | case ASC_WARN_CMD_QNG_CONFLICT: | ||
4785 | ASC_PRINT1( | ||
4786 | "AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n", | ||
4787 | boardp->id); | ||
4788 | break; | ||
4789 | default: | ||
4790 | ASC_PRINT2( | ||
4791 | "AscInitGetConfig: board %d: unknown warning: 0x%x\n", | ||
4792 | boardp->id, ret); | ||
4793 | break; | ||
4794 | } | ||
4795 | if ((err_code = asc_dvc_varp->err_code) != 0) { | ||
4796 | ASC_PRINT3( | ||
4797 | "AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n", | ||
4798 | boardp->id, asc_dvc_varp->init_state, | ||
4799 | asc_dvc_varp->err_code); | ||
4800 | } | ||
4801 | } else { | ||
4802 | ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n"); | ||
4803 | if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) { | ||
4804 | ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n", | ||
4805 | boardp->id, ret); | ||
4806 | } | ||
4807 | if ((err_code = adv_dvc_varp->err_code) != 0) { | ||
4808 | ASC_PRINT2( | ||
4809 | "AdvInitGetConfig: board %d error: err_code 0x%x\n", | ||
4810 | boardp->id, adv_dvc_varp->err_code); | ||
4811 | } | ||
4812 | } | ||
4813 | |||
4814 | if (err_code != 0) { | ||
4815 | #ifdef CONFIG_PROC_FS | ||
4816 | kfree(boardp->prtbuf); | ||
4817 | #endif /* CONFIG_PROC_FS */ | ||
4818 | scsi_unregister(shp); | ||
4819 | asc_board_count--; | ||
4820 | continue; | ||
4821 | } | ||
4822 | |||
4823 | /* | ||
4824 | * Save the EEPROM configuration so that it can be displayed | ||
4825 | * from /proc/scsi/advansys/[0...]. | ||
4826 | */ | ||
4827 | if (ASC_NARROW_BOARD(boardp)) { | ||
4828 | |||
4829 | ASCEEP_CONFIG *ep; | ||
4830 | |||
4831 | /* | ||
4832 | * Set the adapter's target id bit in the 'init_tidmask' field. | ||
4833 | */ | ||
4834 | boardp->init_tidmask |= | ||
4835 | ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id); | ||
4836 | |||
4837 | /* | ||
4838 | * Save EEPROM settings for the board. | ||
4839 | */ | ||
4840 | ep = &boardp->eep_config.asc_eep; | ||
4841 | |||
4842 | ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable; | ||
4843 | ep->disc_enable = asc_dvc_varp->cfg->disc_enable; | ||
4844 | ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled; | ||
4845 | ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed); | ||
4846 | ep->start_motor = asc_dvc_varp->start_motor; | ||
4847 | ep->cntl = asc_dvc_varp->dvc_cntl; | ||
4848 | ep->no_scam = asc_dvc_varp->no_scam; | ||
4849 | ep->max_total_qng = asc_dvc_varp->max_total_qng; | ||
4850 | ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id); | ||
4851 | /* 'max_tag_qng' is set to the same value for every device. */ | ||
4852 | ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0]; | ||
4853 | ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0]; | ||
4854 | ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1]; | ||
4855 | ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2]; | ||
4856 | ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3]; | ||
4857 | ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4]; | ||
4858 | ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5]; | ||
4859 | |||
4860 | /* | ||
4861 | * Modify board configuration. | ||
4862 | */ | ||
4863 | ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n"); | ||
4864 | switch (ret = AscInitSetConfig(asc_dvc_varp)) { | ||
4865 | case 0: /* No error. */ | ||
4866 | break; | ||
4867 | case ASC_WARN_IO_PORT_ROTATE: | ||
4868 | ASC_PRINT1( | ||
4869 | "AscInitSetConfig: board %d: I/O port address modified\n", | ||
4870 | boardp->id); | ||
4871 | break; | ||
4872 | case ASC_WARN_AUTO_CONFIG: | ||
4873 | ASC_PRINT1( | ||
4874 | "AscInitSetConfig: board %d: I/O port increment switch enabled\n", | ||
4875 | boardp->id); | ||
4876 | break; | ||
4877 | case ASC_WARN_EEPROM_CHKSUM: | ||
4878 | ASC_PRINT1( | ||
4879 | "AscInitSetConfig: board %d: EEPROM checksum error\n", | ||
4880 | boardp->id); | ||
4881 | break; | ||
4882 | case ASC_WARN_IRQ_MODIFIED: | ||
4883 | ASC_PRINT1( | ||
4884 | "AscInitSetConfig: board %d: IRQ modified\n", | ||
4885 | boardp->id); | ||
4886 | break; | ||
4887 | case ASC_WARN_CMD_QNG_CONFLICT: | ||
4888 | ASC_PRINT1( | ||
4889 | "AscInitSetConfig: board %d: tag queuing w/o disconnects\n", | ||
4890 | boardp->id); | ||
4891 | break; | ||
4892 | default: | ||
4893 | ASC_PRINT2( | ||
4894 | "AscInitSetConfig: board %d: unknown warning: 0x%x\n", | ||
4895 | boardp->id, ret); | ||
4896 | break; | ||
4897 | } | ||
4898 | if (asc_dvc_varp->err_code != 0) { | ||
4899 | ASC_PRINT3( | ||
4900 | "AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n", | ||
4901 | boardp->id, asc_dvc_varp->init_state, | ||
4902 | asc_dvc_varp->err_code); | ||
4903 | #ifdef CONFIG_PROC_FS | ||
4904 | kfree(boardp->prtbuf); | ||
4905 | #endif /* CONFIG_PROC_FS */ | ||
4906 | scsi_unregister(shp); | ||
4907 | asc_board_count--; | ||
4908 | continue; | ||
4909 | } | ||
4910 | |||
4911 | /* | ||
4912 | * Finish initializing the 'Scsi_Host' structure. | ||
4913 | */ | ||
4914 | /* AscInitSetConfig() will set the IRQ for non-PCI boards. */ | ||
4915 | if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) { | ||
4916 | shp->irq = asc_dvc_varp->irq_no; | ||
4917 | } | ||
4918 | } else { | ||
4919 | ADVEEP_3550_CONFIG *ep_3550; | ||
4920 | ADVEEP_38C0800_CONFIG *ep_38C0800; | ||
4921 | ADVEEP_38C1600_CONFIG *ep_38C1600; | ||
4922 | |||
4923 | /* | ||
4924 | * Save Wide EEP Configuration Information. | ||
4925 | */ | ||
4926 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) | ||
4927 | { | ||
4928 | ep_3550 = &boardp->eep_config.adv_3550_eep; | ||
4929 | |||
4930 | ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id; | ||
4931 | ep_3550->max_host_qng = adv_dvc_varp->max_host_qng; | ||
4932 | ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng; | ||
4933 | ep_3550->termination = adv_dvc_varp->cfg->termination; | ||
4934 | ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable; | ||
4935 | ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl; | ||
4936 | ep_3550->wdtr_able = adv_dvc_varp->wdtr_able; | ||
4937 | ep_3550->sdtr_able = adv_dvc_varp->sdtr_able; | ||
4938 | ep_3550->ultra_able = adv_dvc_varp->ultra_able; | ||
4939 | ep_3550->tagqng_able = adv_dvc_varp->tagqng_able; | ||
4940 | ep_3550->start_motor = adv_dvc_varp->start_motor; | ||
4941 | ep_3550->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait; | ||
4942 | ep_3550->serial_number_word1 = | ||
4943 | adv_dvc_varp->cfg->serial1; | ||
4944 | ep_3550->serial_number_word2 = | ||
4945 | adv_dvc_varp->cfg->serial2; | ||
4946 | ep_3550->serial_number_word3 = | ||
4947 | adv_dvc_varp->cfg->serial3; | ||
4948 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) | ||
4949 | { | ||
4950 | ep_38C0800 = &boardp->eep_config.adv_38C0800_eep; | ||
4951 | |||
4952 | ep_38C0800->adapter_scsi_id = adv_dvc_varp->chip_scsi_id; | ||
4953 | ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng; | ||
4954 | ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng; | ||
4955 | ep_38C0800->termination_lvd = | ||
4956 | adv_dvc_varp->cfg->termination; | ||
4957 | ep_38C0800->disc_enable = adv_dvc_varp->cfg->disc_enable; | ||
4958 | ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl; | ||
4959 | ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able; | ||
4960 | ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able; | ||
4961 | ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1; | ||
4962 | ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2; | ||
4963 | ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3; | ||
4964 | ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4; | ||
4965 | ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able; | ||
4966 | ep_38C0800->start_motor = adv_dvc_varp->start_motor; | ||
4967 | ep_38C0800->scsi_reset_delay = | ||
4968 | adv_dvc_varp->scsi_reset_wait; | ||
4969 | ep_38C0800->serial_number_word1 = | ||
4970 | adv_dvc_varp->cfg->serial1; | ||
4971 | ep_38C0800->serial_number_word2 = | ||
4972 | adv_dvc_varp->cfg->serial2; | ||
4973 | ep_38C0800->serial_number_word3 = | ||
4974 | adv_dvc_varp->cfg->serial3; | ||
4975 | } else | ||
4976 | { | ||
4977 | ep_38C1600 = &boardp->eep_config.adv_38C1600_eep; | ||
4978 | |||
4979 | ep_38C1600->adapter_scsi_id = adv_dvc_varp->chip_scsi_id; | ||
4980 | ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng; | ||
4981 | ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng; | ||
4982 | ep_38C1600->termination_lvd = | ||
4983 | adv_dvc_varp->cfg->termination; | ||
4984 | ep_38C1600->disc_enable = adv_dvc_varp->cfg->disc_enable; | ||
4985 | ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl; | ||
4986 | ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able; | ||
4987 | ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able; | ||
4988 | ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1; | ||
4989 | ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2; | ||
4990 | ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3; | ||
4991 | ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4; | ||
4992 | ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able; | ||
4993 | ep_38C1600->start_motor = adv_dvc_varp->start_motor; | ||
4994 | ep_38C1600->scsi_reset_delay = | ||
4995 | adv_dvc_varp->scsi_reset_wait; | ||
4996 | ep_38C1600->serial_number_word1 = | ||
4997 | adv_dvc_varp->cfg->serial1; | ||
4998 | ep_38C1600->serial_number_word2 = | ||
4999 | adv_dvc_varp->cfg->serial2; | ||
5000 | ep_38C1600->serial_number_word3 = | ||
5001 | adv_dvc_varp->cfg->serial3; | ||
5002 | } | ||
5003 | |||
5004 | /* | ||
5005 | * Set the adapter's target id bit in the 'init_tidmask' field. | ||
5006 | */ | ||
5007 | boardp->init_tidmask |= | ||
5008 | ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id); | ||
5009 | |||
5010 | /* | ||
5011 | * Finish initializing the 'Scsi_Host' structure. | ||
5012 | */ | ||
5013 | shp->irq = adv_dvc_varp->irq_no; | ||
5014 | } | ||
5015 | |||
5016 | /* | ||
5017 | * Channels are numbered beginning with 0. For AdvanSys one host | ||
5018 | * structure supports one channel. Multi-channel boards have a | ||
5019 | * separate host structure for each channel. | ||
5020 | */ | ||
5021 | shp->max_channel = 0; | ||
5022 | if (ASC_NARROW_BOARD(boardp)) { | ||
5023 | shp->max_id = ASC_MAX_TID + 1; | ||
5024 | shp->max_lun = ASC_MAX_LUN + 1; | ||
5025 | |||
5026 | shp->io_port = asc_dvc_varp->iop_base; | ||
5027 | boardp->asc_n_io_port = ASC_IOADR_GAP; | ||
5028 | shp->this_id = asc_dvc_varp->cfg->chip_scsi_id; | ||
5029 | |||
5030 | /* Set maximum number of queues the adapter can handle. */ | ||
5031 | shp->can_queue = asc_dvc_varp->max_total_qng; | ||
5032 | } else { | ||
5033 | shp->max_id = ADV_MAX_TID + 1; | ||
5034 | shp->max_lun = ADV_MAX_LUN + 1; | ||
5035 | |||
5036 | /* | ||
5037 | * Save the I/O Port address and length even though | ||
5038 | * I/O ports are not used to access Wide boards. | ||
5039 | * Instead the Wide boards are accessed with | ||
5040 | * PCI Memory Mapped I/O. | ||
5041 | */ | ||
5042 | shp->io_port = iop; | ||
5043 | boardp->asc_n_io_port = iolen; | ||
5044 | |||
5045 | shp->this_id = adv_dvc_varp->chip_scsi_id; | ||
5046 | |||
5047 | /* Set maximum number of queues the adapter can handle. */ | ||
5048 | shp->can_queue = adv_dvc_varp->max_host_qng; | ||
5049 | } | ||
5050 | |||
5051 | /* | ||
5052 | * 'n_io_port' currently is one byte. | ||
5053 | * | ||
5054 | * Set a value to 'n_io_port', but never referenced it because | ||
5055 | * it may be truncated. | ||
5056 | */ | ||
5057 | shp->n_io_port = boardp->asc_n_io_port <= 255 ? | ||
5058 | boardp->asc_n_io_port : 255; | ||
5059 | |||
5060 | /* | ||
5061 | * Following v1.3.89, 'cmd_per_lun' is no longer needed | ||
5062 | * and should be set to zero. | ||
5063 | * | ||
5064 | * But because of a bug introduced in v1.3.89 if the driver is | ||
5065 | * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level | ||
5066 | * SCSI function 'allocate_device' will panic. To allow the driver | ||
5067 | * to work as a module in these kernels set 'cmd_per_lun' to 1. | ||
5068 | * | ||
5069 | * Note: This is wrong. cmd_per_lun should be set to the depth | ||
5070 | * you want on untagged devices always. | ||
5071 | #ifdef MODULE | ||
5072 | */ | ||
5073 | shp->cmd_per_lun = 1; | ||
5074 | /* #else | ||
5075 | shp->cmd_per_lun = 0; | ||
5076 | #endif */ | ||
5077 | |||
5078 | /* | ||
5079 | * Set the maximum number of scatter-gather elements the | ||
5080 | * adapter can handle. | ||
5081 | */ | ||
5082 | if (ASC_NARROW_BOARD(boardp)) { | ||
5083 | /* | ||
5084 | * Allow two commands with 'sg_tablesize' scatter-gather | ||
5085 | * elements to be executed simultaneously. This value is | ||
5086 | * the theoretical hardware limit. It may be decreased | ||
5087 | * below. | ||
5088 | */ | ||
5089 | shp->sg_tablesize = | ||
5090 | (((asc_dvc_varp->max_total_qng - 2) / 2) * | ||
5091 | ASC_SG_LIST_PER_Q) + 1; | ||
5092 | } else { | ||
5093 | shp->sg_tablesize = ADV_MAX_SG_LIST; | ||
5094 | } | ||
5095 | |||
5096 | /* | ||
5097 | * The value of 'sg_tablesize' can not exceed the SCSI | ||
5098 | * mid-level driver definition of SG_ALL. SG_ALL also | ||
5099 | * must not be exceeded, because it is used to define the | ||
5100 | * size of the scatter-gather table in 'struct asc_sg_head'. | ||
5101 | */ | ||
5102 | if (shp->sg_tablesize > SG_ALL) { | ||
5103 | shp->sg_tablesize = SG_ALL; | ||
5104 | } | ||
5105 | |||
5106 | ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n", | ||
5107 | shp->sg_tablesize); | ||
5108 | |||
5109 | /* BIOS start address. */ | ||
5110 | if (ASC_NARROW_BOARD(boardp)) { | ||
5111 | shp->base = | ||
5112 | ((ulong) AscGetChipBiosAddress( | ||
5113 | asc_dvc_varp->iop_base, | ||
5114 | asc_dvc_varp->bus_type)); | ||
5115 | } else { | ||
5116 | /* | ||
5117 | * Fill-in BIOS board variables. The Wide BIOS saves | ||
5118 | * information in LRAM that is used by the driver. | ||
5119 | */ | ||
5120 | AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE, | ||
5121 | boardp->bios_signature); | ||
5122 | AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION, | ||
5123 | boardp->bios_version); | ||
5124 | AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG, | ||
5125 | boardp->bios_codeseg); | ||
5126 | AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN, | ||
5127 | boardp->bios_codelen); | ||
5128 | |||
5129 | ASC_DBG2(1, | ||
5130 | "advansys_detect: bios_signature 0x%x, bios_version 0x%x\n", | ||
5131 | boardp->bios_signature, boardp->bios_version); | ||
5132 | |||
5133 | ASC_DBG2(1, | ||
5134 | "advansys_detect: bios_codeseg 0x%x, bios_codelen 0x%x\n", | ||
5135 | boardp->bios_codeseg, boardp->bios_codelen); | ||
5136 | |||
5137 | /* | ||
5138 | * If the BIOS saved a valid signature, then fill in | ||
5139 | * the BIOS code segment base address. | ||
5140 | */ | ||
5141 | if (boardp->bios_signature == 0x55AA) { | ||
5142 | /* | ||
5143 | * Convert x86 realmode code segment to a linear | ||
5144 | * address by shifting left 4. | ||
5145 | */ | ||
5146 | shp->base = ((ulong) boardp->bios_codeseg << 4); | ||
5147 | } else { | ||
5148 | shp->base = 0; | ||
5149 | } | ||
5150 | } | ||
5151 | |||
5152 | /* | ||
5153 | * Register Board Resources - I/O Port, DMA, IRQ | ||
5154 | */ | ||
5155 | |||
5156 | /* | ||
5157 | * Register I/O port range. | ||
5158 | * | ||
5159 | * For Wide boards the I/O ports are not used to access | ||
5160 | * the board, but request the region anyway. | ||
5161 | * | ||
5162 | * 'shp->n_io_port' is not referenced, because it may be truncated. | ||
5163 | */ | ||
5164 | ASC_DBG2(2, | ||
5165 | "advansys_detect: request_region port 0x%lx, len 0x%x\n", | ||
5166 | (ulong) shp->io_port, boardp->asc_n_io_port); | ||
5167 | if (request_region(shp->io_port, boardp->asc_n_io_port, | ||
5168 | "advansys") == NULL) { | ||
5169 | ASC_PRINT3( | ||
5170 | "advansys_detect: board %d: request_region() failed, port 0x%lx, len 0x%x\n", | ||
5171 | boardp->id, (ulong) shp->io_port, boardp->asc_n_io_port); | ||
5172 | #ifdef CONFIG_PROC_FS | ||
5173 | kfree(boardp->prtbuf); | ||
5174 | #endif /* CONFIG_PROC_FS */ | ||
5175 | scsi_unregister(shp); | ||
5176 | asc_board_count--; | ||
5177 | continue; | ||
5178 | } | ||
5179 | |||
5180 | /* Register DMA Channel for Narrow boards. */ | ||
5181 | shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */ | ||
5182 | #ifdef CONFIG_ISA | ||
5183 | if (ASC_NARROW_BOARD(boardp)) { | ||
5184 | /* Register DMA channel for ISA bus. */ | ||
5185 | if (asc_dvc_varp->bus_type & ASC_IS_ISA) { | ||
5186 | shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel; | ||
5187 | if ((ret = | ||
5188 | request_dma(shp->dma_channel, "advansys")) != 0) { | ||
5189 | ASC_PRINT3( | ||
5190 | "advansys_detect: board %d: request_dma() %d failed %d\n", | ||
5191 | boardp->id, shp->dma_channel, ret); | ||
5192 | release_region(shp->io_port, boardp->asc_n_io_port); | ||
5193 | #ifdef CONFIG_PROC_FS | ||
5194 | kfree(boardp->prtbuf); | ||
5195 | #endif /* CONFIG_PROC_FS */ | ||
5196 | scsi_unregister(shp); | ||
5197 | asc_board_count--; | ||
5198 | continue; | ||
5199 | } | ||
5200 | AscEnableIsaDma(shp->dma_channel); | ||
5201 | } | ||
5202 | } | ||
5203 | #endif /* CONFIG_ISA */ | ||
5204 | |||
5205 | /* Register IRQ Number. */ | ||
5206 | ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq); | ||
5207 | /* | ||
5208 | * If request_irq() fails with the SA_INTERRUPT flag set, | ||
5209 | * then try again without the SA_INTERRUPT flag set. This | ||
5210 | * allows IRQ sharing to work even with other drivers that | ||
5211 | * do not set the SA_INTERRUPT flag. | ||
5212 | * | ||
5213 | * If SA_INTERRUPT is not set, then interrupts are enabled | ||
5214 | * before the driver interrupt function is called. | ||
5215 | */ | ||
5216 | if (((ret = request_irq(shp->irq, advansys_interrupt, | ||
5217 | SA_INTERRUPT | (share_irq == TRUE ? SA_SHIRQ : 0), | ||
5218 | "advansys", boardp)) != 0) && | ||
5219 | ((ret = request_irq(shp->irq, advansys_interrupt, | ||
5220 | (share_irq == TRUE ? SA_SHIRQ : 0), | ||
5221 | "advansys", boardp)) != 0)) | ||
5222 | { | ||
5223 | if (ret == -EBUSY) { | ||
5224 | ASC_PRINT2( | ||
5225 | "advansys_detect: board %d: request_irq(): IRQ 0x%x already in use.\n", | ||
5226 | boardp->id, shp->irq); | ||
5227 | } else if (ret == -EINVAL) { | ||
5228 | ASC_PRINT2( | ||
5229 | "advansys_detect: board %d: request_irq(): IRQ 0x%x not valid.\n", | ||
5230 | boardp->id, shp->irq); | ||
5231 | } else { | ||
5232 | ASC_PRINT3( | ||
5233 | "advansys_detect: board %d: request_irq(): IRQ 0x%x failed with %d\n", | ||
5234 | boardp->id, shp->irq, ret); | ||
5235 | } | ||
5236 | release_region(shp->io_port, boardp->asc_n_io_port); | ||
5237 | iounmap(boardp->ioremap_addr); | ||
5238 | if (shp->dma_channel != NO_ISA_DMA) { | ||
5239 | free_dma(shp->dma_channel); | ||
5240 | } | ||
5241 | #ifdef CONFIG_PROC_FS | ||
5242 | kfree(boardp->prtbuf); | ||
5243 | #endif /* CONFIG_PROC_FS */ | ||
5244 | scsi_unregister(shp); | ||
5245 | asc_board_count--; | ||
5246 | continue; | ||
5247 | } | ||
5248 | |||
5249 | /* | ||
5250 | * Initialize board RISC chip and enable interrupts. | ||
5251 | */ | ||
5252 | if (ASC_NARROW_BOARD(boardp)) { | ||
5253 | ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n"); | ||
5254 | warn_code = AscInitAsc1000Driver(asc_dvc_varp); | ||
5255 | err_code = asc_dvc_varp->err_code; | ||
5256 | |||
5257 | if (warn_code || err_code) { | ||
5258 | ASC_PRINT4( | ||
5259 | "advansys_detect: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n", | ||
5260 | boardp->id, asc_dvc_varp->init_state, | ||
5261 | warn_code, err_code); | ||
5262 | } | ||
5263 | } else { | ||
5264 | ADV_CARR_T *carrp; | ||
5265 | int req_cnt = 0; | ||
5266 | adv_req_t *reqp = NULL; | ||
5267 | int sg_cnt = 0; | ||
5268 | |||
5269 | /* | ||
5270 | * Allocate buffer carrier structures. The total size | ||
5271 | * is about 4 KB, so allocate all at once. | ||
5272 | */ | ||
5273 | carrp = | ||
5274 | (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC); | ||
5275 | ASC_DBG1(1, "advansys_detect: carrp 0x%lx\n", (ulong) carrp); | ||
5276 | |||
5277 | if (carrp == NULL) { | ||
5278 | goto kmalloc_error; | ||
5279 | } | ||
5280 | |||
5281 | /* | ||
5282 | * Allocate up to 'max_host_qng' request structures for | ||
5283 | * the Wide board. The total size is about 16 KB, so | ||
5284 | * allocate all at once. If the allocation fails decrement | ||
5285 | * and try again. | ||
5286 | */ | ||
5287 | for (req_cnt = adv_dvc_varp->max_host_qng; | ||
5288 | req_cnt > 0; req_cnt--) { | ||
5289 | |||
5290 | reqp = (adv_req_t *) | ||
5291 | kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC); | ||
5292 | |||
5293 | ASC_DBG3(1, | ||
5294 | "advansys_detect: reqp 0x%lx, req_cnt %d, bytes %lu\n", | ||
5295 | (ulong) reqp, req_cnt, | ||
5296 | (ulong) sizeof(adv_req_t) * req_cnt); | ||
5297 | |||
5298 | if (reqp != NULL) { | ||
5299 | break; | ||
5300 | } | ||
5301 | } | ||
5302 | if (reqp == NULL) | ||
5303 | { | ||
5304 | goto kmalloc_error; | ||
5305 | } | ||
5306 | |||
5307 | /* | ||
5308 | * Allocate up to ADV_TOT_SG_BLOCK request structures for | ||
5309 | * the Wide board. Each structure is about 136 bytes. | ||
5310 | */ | ||
5311 | boardp->adv_sgblkp = NULL; | ||
5312 | for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) { | ||
5313 | |||
5314 | sgp = (adv_sgblk_t *) | ||
5315 | kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC); | ||
5316 | |||
5317 | if (sgp == NULL) { | ||
5318 | break; | ||
5319 | } | ||
5320 | |||
5321 | sgp->next_sgblkp = boardp->adv_sgblkp; | ||
5322 | boardp->adv_sgblkp = sgp; | ||
5323 | |||
5324 | } | ||
5325 | ASC_DBG3(1, | ||
5326 | "advansys_detect: sg_cnt %d * %u = %u bytes\n", | ||
5327 | sg_cnt, sizeof(adv_sgblk_t), | ||
5328 | (unsigned) (sizeof(adv_sgblk_t) * sg_cnt)); | ||
5329 | |||
5330 | /* | ||
5331 | * If no request structures or scatter-gather structures could | ||
5332 | * be allocated, then return an error. Otherwise continue with | ||
5333 | * initialization. | ||
5334 | */ | ||
5335 | kmalloc_error: | ||
5336 | if (carrp == NULL) | ||
5337 | { | ||
5338 | ASC_PRINT1( | ||
5339 | "advansys_detect: board %d error: failed to kmalloc() carrier buffer.\n", | ||
5340 | boardp->id); | ||
5341 | err_code = ADV_ERROR; | ||
5342 | } else if (reqp == NULL) { | ||
5343 | kfree(carrp); | ||
5344 | ASC_PRINT1( | ||
5345 | "advansys_detect: board %d error: failed to kmalloc() adv_req_t buffer.\n", | ||
5346 | boardp->id); | ||
5347 | err_code = ADV_ERROR; | ||
5348 | } else if (boardp->adv_sgblkp == NULL) { | ||
5349 | kfree(carrp); | ||
5350 | kfree(reqp); | ||
5351 | ASC_PRINT1( | ||
5352 | "advansys_detect: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n", | ||
5353 | boardp->id); | ||
5354 | err_code = ADV_ERROR; | ||
5355 | } else { | ||
5356 | |||
5357 | /* Save carrier buffer pointer. */ | ||
5358 | boardp->orig_carrp = carrp; | ||
5359 | |||
5360 | /* | ||
5361 | * Save original pointer for kfree() in case the | ||
5362 | * driver is built as a module and can be unloaded. | ||
5363 | */ | ||
5364 | boardp->orig_reqp = reqp; | ||
5365 | |||
5366 | adv_dvc_varp->carrier_buf = carrp; | ||
5367 | |||
5368 | /* | ||
5369 | * Point 'adv_reqp' to the request structures and | ||
5370 | * link them together. | ||
5371 | */ | ||
5372 | req_cnt--; | ||
5373 | reqp[req_cnt].next_reqp = NULL; | ||
5374 | for (; req_cnt > 0; req_cnt--) { | ||
5375 | reqp[req_cnt - 1].next_reqp = &reqp[req_cnt]; | ||
5376 | } | ||
5377 | boardp->adv_reqp = &reqp[0]; | ||
5378 | |||
5379 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) | ||
5380 | { | ||
5381 | ASC_DBG(2, | ||
5382 | "advansys_detect: AdvInitAsc3550Driver()\n"); | ||
5383 | warn_code = AdvInitAsc3550Driver(adv_dvc_varp); | ||
5384 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { | ||
5385 | ASC_DBG(2, | ||
5386 | "advansys_detect: AdvInitAsc38C0800Driver()\n"); | ||
5387 | warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp); | ||
5388 | } else { | ||
5389 | ASC_DBG(2, | ||
5390 | "advansys_detect: AdvInitAsc38C1600Driver()\n"); | ||
5391 | warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp); | ||
5392 | } | ||
5393 | err_code = adv_dvc_varp->err_code; | ||
5394 | |||
5395 | if (warn_code || err_code) { | ||
5396 | ASC_PRINT3( | ||
5397 | "advansys_detect: board %d error: warn 0x%x, error 0x%x\n", | ||
5398 | boardp->id, warn_code, err_code); | ||
5399 | } | ||
5400 | } | ||
5401 | } | ||
5402 | |||
5403 | if (err_code != 0) { | ||
5404 | release_region(shp->io_port, boardp->asc_n_io_port); | ||
5405 | if (ASC_WIDE_BOARD(boardp)) { | ||
5406 | iounmap(boardp->ioremap_addr); | ||
5407 | if (boardp->orig_carrp) { | ||
5408 | kfree(boardp->orig_carrp); | ||
5409 | boardp->orig_carrp = NULL; | ||
5410 | } | ||
5411 | if (boardp->orig_reqp) { | ||
5412 | kfree(boardp->orig_reqp); | ||
5413 | boardp->orig_reqp = boardp->adv_reqp = NULL; | ||
5414 | } | ||
5415 | while ((sgp = boardp->adv_sgblkp) != NULL) | ||
5416 | { | ||
5417 | boardp->adv_sgblkp = sgp->next_sgblkp; | ||
5418 | kfree(sgp); | ||
5419 | } | ||
5420 | } | ||
5421 | if (shp->dma_channel != NO_ISA_DMA) { | ||
5422 | free_dma(shp->dma_channel); | ||
5423 | } | ||
5424 | #ifdef CONFIG_PROC_FS | ||
5425 | kfree(boardp->prtbuf); | ||
5426 | #endif /* CONFIG_PROC_FS */ | ||
5427 | free_irq(shp->irq, boardp); | ||
5428 | scsi_unregister(shp); | ||
5429 | asc_board_count--; | ||
5430 | continue; | ||
5431 | } | ||
5432 | ASC_DBG_PRT_SCSI_HOST(2, shp); | ||
5433 | } | ||
5434 | } | ||
5435 | |||
5436 | ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count); | ||
5437 | return asc_board_count; | ||
5438 | } | ||
5439 | |||
5440 | /* | ||
5441 | * advansys_release() | ||
5442 | * | ||
5443 | * Release resources allocated for a single AdvanSys adapter. | ||
5444 | */ | ||
5445 | int | ||
5446 | advansys_release(struct Scsi_Host *shp) | ||
5447 | { | ||
5448 | asc_board_t *boardp; | ||
5449 | |||
5450 | ASC_DBG(1, "advansys_release: begin\n"); | ||
5451 | boardp = ASC_BOARDP(shp); | ||
5452 | free_irq(shp->irq, boardp); | ||
5453 | if (shp->dma_channel != NO_ISA_DMA) { | ||
5454 | ASC_DBG(1, "advansys_release: free_dma()\n"); | ||
5455 | free_dma(shp->dma_channel); | ||
5456 | } | ||
5457 | release_region(shp->io_port, boardp->asc_n_io_port); | ||
5458 | if (ASC_WIDE_BOARD(boardp)) { | ||
5459 | adv_sgblk_t *sgp = NULL; | ||
5460 | |||
5461 | iounmap(boardp->ioremap_addr); | ||
5462 | if (boardp->orig_carrp) { | ||
5463 | kfree(boardp->orig_carrp); | ||
5464 | boardp->orig_carrp = NULL; | ||
5465 | } | ||
5466 | if (boardp->orig_reqp) { | ||
5467 | kfree(boardp->orig_reqp); | ||
5468 | boardp->orig_reqp = boardp->adv_reqp = NULL; | ||
5469 | } | ||
5470 | while ((sgp = boardp->adv_sgblkp) != NULL) | ||
5471 | { | ||
5472 | boardp->adv_sgblkp = sgp->next_sgblkp; | ||
5473 | kfree(sgp); | ||
5474 | } | ||
5475 | } | ||
5476 | #ifdef CONFIG_PROC_FS | ||
5477 | ASC_ASSERT(boardp->prtbuf != NULL); | ||
5478 | kfree(boardp->prtbuf); | ||
5479 | #endif /* CONFIG_PROC_FS */ | ||
5480 | scsi_unregister(shp); | ||
5481 | ASC_DBG(1, "advansys_release: end\n"); | ||
5482 | return 0; | ||
5483 | } | ||
5484 | |||
5485 | /* | ||
5486 | * advansys_info() | ||
5487 | * | ||
5488 | * Return suitable for printing on the console with the argument | ||
5489 | * adapter's configuration information. | ||
5490 | * | ||
5491 | * Note: The information line should not exceed ASC_INFO_SIZE bytes, | ||
5492 | * otherwise the static 'info' array will be overrun. | ||
5493 | */ | ||
5494 | const char * | ||
5495 | advansys_info(struct Scsi_Host *shp) | ||
5496 | { | ||
5497 | static char info[ASC_INFO_SIZE]; | ||
5498 | asc_board_t *boardp; | ||
5499 | ASC_DVC_VAR *asc_dvc_varp; | ||
5500 | ADV_DVC_VAR *adv_dvc_varp; | ||
5501 | char *busname; | ||
5502 | int iolen; | ||
5503 | char *widename = NULL; | ||
5504 | |||
5505 | boardp = ASC_BOARDP(shp); | ||
5506 | if (ASC_NARROW_BOARD(boardp)) { | ||
5507 | asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; | ||
5508 | ASC_DBG(1, "advansys_info: begin\n"); | ||
5509 | if (asc_dvc_varp->bus_type & ASC_IS_ISA) { | ||
5510 | if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) { | ||
5511 | busname = "ISA PnP"; | ||
5512 | } else { | ||
5513 | busname = "ISA"; | ||
5514 | } | ||
5515 | /* Don't reference 'shp->n_io_port'; It may be truncated. */ | ||
5516 | sprintf(info, | ||
5517 | "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X", | ||
5518 | ASC_VERSION, busname, | ||
5519 | (ulong) shp->io_port, | ||
5520 | (ulong) shp->io_port + boardp->asc_n_io_port - 1, | ||
5521 | shp->irq, shp->dma_channel); | ||
5522 | } else { | ||
5523 | if (asc_dvc_varp->bus_type & ASC_IS_VL) { | ||
5524 | busname = "VL"; | ||
5525 | } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) { | ||
5526 | busname = "EISA"; | ||
5527 | } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) { | ||
5528 | if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA) | ||
5529 | == ASC_IS_PCI_ULTRA) { | ||
5530 | busname = "PCI Ultra"; | ||
5531 | } else { | ||
5532 | busname = "PCI"; | ||
5533 | } | ||
5534 | } else { | ||
5535 | busname = "?"; | ||
5536 | ASC_PRINT2( "advansys_info: board %d: unknown bus type %d\n", | ||
5537 | boardp->id, asc_dvc_varp->bus_type); | ||
5538 | } | ||
5539 | /* Don't reference 'shp->n_io_port'; It may be truncated. */ | ||
5540 | sprintf(info, | ||
5541 | "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X", | ||
5542 | ASC_VERSION, busname, | ||
5543 | (ulong) shp->io_port, | ||
5544 | (ulong) shp->io_port + boardp->asc_n_io_port - 1, | ||
5545 | shp->irq); | ||
5546 | } | ||
5547 | } else { | ||
5548 | /* | ||
5549 | * Wide Adapter Information | ||
5550 | * | ||
5551 | * Memory-mapped I/O is used instead of I/O space to access | ||
5552 | * the adapter, but display the I/O Port range. The Memory | ||
5553 | * I/O address is displayed through the driver /proc file. | ||
5554 | */ | ||
5555 | adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; | ||
5556 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) | ||
5557 | { | ||
5558 | iolen = ADV_3550_IOLEN; | ||
5559 | widename = "Ultra-Wide"; | ||
5560 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) | ||
5561 | { | ||
5562 | iolen = ADV_38C0800_IOLEN; | ||
5563 | widename = "Ultra2-Wide"; | ||
5564 | } else | ||
5565 | { | ||
5566 | iolen = ADV_38C1600_IOLEN; | ||
5567 | widename = "Ultra3-Wide"; | ||
5568 | } | ||
5569 | sprintf(info, "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X", | ||
5570 | ASC_VERSION, | ||
5571 | widename, | ||
5572 | (ulong) adv_dvc_varp->iop_base, | ||
5573 | (ulong) adv_dvc_varp->iop_base + iolen - 1, | ||
5574 | shp->irq); | ||
5575 | } | ||
5576 | ASC_ASSERT(strlen(info) < ASC_INFO_SIZE); | ||
5577 | ASC_DBG(1, "advansys_info: end\n"); | ||
5578 | return info; | ||
5579 | } | ||
5580 | |||
5581 | /* | ||
5582 | * advansys_queuecommand() - interrupt-driven I/O entrypoint. | ||
5583 | * | ||
5584 | * This function always returns 0. Command return status is saved | ||
5585 | * in the 'scp' result field. | ||
5586 | */ | ||
5587 | int | ||
5588 | advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) | ||
5589 | { | ||
5590 | struct Scsi_Host *shp; | ||
5591 | asc_board_t *boardp; | ||
5592 | ulong flags; | ||
5593 | struct scsi_cmnd *done_scp; | ||
5594 | |||
5595 | shp = scp->device->host; | ||
5596 | boardp = ASC_BOARDP(shp); | ||
5597 | ASC_STATS(shp, queuecommand); | ||
5598 | |||
5599 | /* host_lock taken by mid-level prior to call but need to protect */ | ||
5600 | /* against own ISR */ | ||
5601 | spin_lock_irqsave(&boardp->lock, flags); | ||
5602 | |||
5603 | /* | ||
5604 | * Block new commands while handling a reset or abort request. | ||
5605 | */ | ||
5606 | if (boardp->flags & ASC_HOST_IN_RESET) { | ||
5607 | ASC_DBG1(1, | ||
5608 | "advansys_queuecommand: scp 0x%lx blocked for reset request\n", | ||
5609 | (ulong) scp); | ||
5610 | scp->result = HOST_BYTE(DID_RESET); | ||
5611 | |||
5612 | /* | ||
5613 | * Add blocked requests to the board's 'done' queue. The queued | ||
5614 | * requests will be completed at the end of the abort or reset | ||
5615 | * handling. | ||
5616 | */ | ||
5617 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
5618 | spin_unlock_irqrestore(&boardp->lock, flags); | ||
5619 | return 0; | ||
5620 | } | ||
5621 | |||
5622 | /* | ||
5623 | * Attempt to execute any waiting commands for the board. | ||
5624 | */ | ||
5625 | if (!ASC_QUEUE_EMPTY(&boardp->waiting)) { | ||
5626 | ASC_DBG(1, | ||
5627 | "advansys_queuecommand: before asc_execute_queue() waiting\n"); | ||
5628 | asc_execute_queue(&boardp->waiting); | ||
5629 | } | ||
5630 | |||
5631 | /* | ||
5632 | * Save the function pointer to Linux mid-level 'done' function | ||
5633 | * and attempt to execute the command. | ||
5634 | * | ||
5635 | * If ASC_NOERROR is returned the request has been added to the | ||
5636 | * board's 'active' queue and will be completed by the interrupt | ||
5637 | * handler. | ||
5638 | * | ||
5639 | * If ASC_BUSY is returned add the request to the board's per | ||
5640 | * target waiting list. This is the first time the request has | ||
5641 | * been tried. Add it to the back of the waiting list. It will be | ||
5642 | * retried later. | ||
5643 | * | ||
5644 | * If an error occurred, the request will have been placed on the | ||
5645 | * board's 'done' queue and must be completed before returning. | ||
5646 | */ | ||
5647 | scp->scsi_done = done; | ||
5648 | switch (asc_execute_scsi_cmnd(scp)) { | ||
5649 | case ASC_NOERROR: | ||
5650 | break; | ||
5651 | case ASC_BUSY: | ||
5652 | asc_enqueue(&boardp->waiting, scp, ASC_BACK); | ||
5653 | break; | ||
5654 | case ASC_ERROR: | ||
5655 | default: | ||
5656 | done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL); | ||
5657 | /* Interrupts could be enabled here. */ | ||
5658 | asc_scsi_done_list(done_scp); | ||
5659 | break; | ||
5660 | } | ||
5661 | spin_unlock_irqrestore(&boardp->lock, flags); | ||
5662 | |||
5663 | return 0; | ||
5664 | } | ||
5665 | |||
5666 | /* | ||
5667 | * advansys_reset() | ||
5668 | * | ||
5669 | * Reset the bus associated with the command 'scp'. | ||
5670 | * | ||
5671 | * This function runs its own thread. Interrupts must be blocked but | ||
5672 | * sleeping is allowed and no locking other than for host structures is | ||
5673 | * required. Returns SUCCESS or FAILED. | ||
5674 | */ | ||
5675 | int | ||
5676 | advansys_reset(struct scsi_cmnd *scp) | ||
5677 | { | ||
5678 | struct Scsi_Host *shp; | ||
5679 | asc_board_t *boardp; | ||
5680 | ASC_DVC_VAR *asc_dvc_varp; | ||
5681 | ADV_DVC_VAR *adv_dvc_varp; | ||
5682 | ulong flags; | ||
5683 | struct scsi_cmnd *done_scp = NULL, *last_scp = NULL; | ||
5684 | struct scsi_cmnd *tscp, *new_last_scp; | ||
5685 | int status; | ||
5686 | int ret = SUCCESS; | ||
5687 | |||
5688 | ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong) scp); | ||
5689 | |||
5690 | #ifdef ADVANSYS_STATS | ||
5691 | if (scp->device->host != NULL) { | ||
5692 | ASC_STATS(scp->device->host, reset); | ||
5693 | } | ||
5694 | #endif /* ADVANSYS_STATS */ | ||
5695 | |||
5696 | if ((shp = scp->device->host) == NULL) { | ||
5697 | scp->result = HOST_BYTE(DID_ERROR); | ||
5698 | return FAILED; | ||
5699 | } | ||
5700 | |||
5701 | boardp = ASC_BOARDP(shp); | ||
5702 | |||
5703 | ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n", | ||
5704 | boardp->id); | ||
5705 | /* | ||
5706 | * Check for re-entrancy. | ||
5707 | */ | ||
5708 | spin_lock_irqsave(&boardp->lock, flags); | ||
5709 | if (boardp->flags & ASC_HOST_IN_RESET) { | ||
5710 | spin_unlock_irqrestore(&boardp->lock, flags); | ||
5711 | return FAILED; | ||
5712 | } | ||
5713 | boardp->flags |= ASC_HOST_IN_RESET; | ||
5714 | spin_unlock_irqrestore(&boardp->lock, flags); | ||
5715 | |||
5716 | if (ASC_NARROW_BOARD(boardp)) { | ||
5717 | /* | ||
5718 | * Narrow Board | ||
5719 | */ | ||
5720 | asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; | ||
5721 | |||
5722 | /* | ||
5723 | * Reset the chip and SCSI bus. | ||
5724 | */ | ||
5725 | ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n"); | ||
5726 | status = AscInitAsc1000Driver(asc_dvc_varp); | ||
5727 | |||
5728 | /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */ | ||
5729 | if (asc_dvc_varp->err_code) { | ||
5730 | ASC_PRINT2( | ||
5731 | "advansys_reset: board %d: SCSI bus reset error: 0x%x\n", | ||
5732 | boardp->id, asc_dvc_varp->err_code); | ||
5733 | ret = FAILED; | ||
5734 | } else if (status) { | ||
5735 | ASC_PRINT2( | ||
5736 | "advansys_reset: board %d: SCSI bus reset warning: 0x%x\n", | ||
5737 | boardp->id, status); | ||
5738 | } else { | ||
5739 | ASC_PRINT1( | ||
5740 | "advansys_reset: board %d: SCSI bus reset successful.\n", | ||
5741 | boardp->id); | ||
5742 | } | ||
5743 | |||
5744 | ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n"); | ||
5745 | spin_lock_irqsave(&boardp->lock, flags); | ||
5746 | |||
5747 | } else { | ||
5748 | /* | ||
5749 | * Wide Board | ||
5750 | * | ||
5751 | * If the suggest reset bus flags are set, then reset the bus. | ||
5752 | * Otherwise only reset the device. | ||
5753 | */ | ||
5754 | adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; | ||
5755 | |||
5756 | /* | ||
5757 | * Reset the target's SCSI bus. | ||
5758 | */ | ||
5759 | ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n"); | ||
5760 | switch (AdvResetChipAndSB(adv_dvc_varp)) { | ||
5761 | case ASC_TRUE: | ||
5762 | ASC_PRINT1("advansys_reset: board %d: SCSI bus reset successful.\n", | ||
5763 | boardp->id); | ||
5764 | break; | ||
5765 | case ASC_FALSE: | ||
5766 | default: | ||
5767 | ASC_PRINT1("advansys_reset: board %d: SCSI bus reset error.\n", | ||
5768 | boardp->id); | ||
5769 | ret = FAILED; | ||
5770 | break; | ||
5771 | } | ||
5772 | spin_lock_irqsave(&boardp->lock, flags); | ||
5773 | (void) AdvISR(adv_dvc_varp); | ||
5774 | } | ||
5775 | /* Board lock is held. */ | ||
5776 | |||
5777 | /* | ||
5778 | * Dequeue all board 'done' requests. A pointer to the last request | ||
5779 | * is returned in 'last_scp'. | ||
5780 | */ | ||
5781 | done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL); | ||
5782 | |||
5783 | /* | ||
5784 | * Dequeue all board 'active' requests for all devices and set | ||
5785 | * the request status to DID_RESET. A pointer to the last request | ||
5786 | * is returned in 'last_scp'. | ||
5787 | */ | ||
5788 | if (done_scp == NULL) { | ||
5789 | done_scp = asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL); | ||
5790 | for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) { | ||
5791 | tscp->result = HOST_BYTE(DID_RESET); | ||
5792 | } | ||
5793 | } else { | ||
5794 | /* Append to 'done_scp' at the end with 'last_scp'. */ | ||
5795 | ASC_ASSERT(last_scp != NULL); | ||
5796 | last_scp->host_scribble = (unsigned char *)asc_dequeue_list( | ||
5797 | &boardp->active, &new_last_scp, ASC_TID_ALL); | ||
5798 | if (new_last_scp != NULL) { | ||
5799 | ASC_ASSERT(REQPNEXT(last_scp) != NULL); | ||
5800 | for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) { | ||
5801 | tscp->result = HOST_BYTE(DID_RESET); | ||
5802 | } | ||
5803 | last_scp = new_last_scp; | ||
5804 | } | ||
5805 | } | ||
5806 | |||
5807 | /* | ||
5808 | * Dequeue all 'waiting' requests and set the request status | ||
5809 | * to DID_RESET. | ||
5810 | */ | ||
5811 | if (done_scp == NULL) { | ||
5812 | done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL); | ||
5813 | for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) { | ||
5814 | tscp->result = HOST_BYTE(DID_RESET); | ||
5815 | } | ||
5816 | } else { | ||
5817 | /* Append to 'done_scp' at the end with 'last_scp'. */ | ||
5818 | ASC_ASSERT(last_scp != NULL); | ||
5819 | last_scp->host_scribble = (unsigned char *)asc_dequeue_list( | ||
5820 | &boardp->waiting, &new_last_scp, ASC_TID_ALL); | ||
5821 | if (new_last_scp != NULL) { | ||
5822 | ASC_ASSERT(REQPNEXT(last_scp) != NULL); | ||
5823 | for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) { | ||
5824 | tscp->result = HOST_BYTE(DID_RESET); | ||
5825 | } | ||
5826 | last_scp = new_last_scp; | ||
5827 | } | ||
5828 | } | ||
5829 | |||
5830 | /* Save the time of the most recently completed reset. */ | ||
5831 | boardp->last_reset = jiffies; | ||
5832 | |||
5833 | /* Clear reset flag. */ | ||
5834 | boardp->flags &= ~ASC_HOST_IN_RESET; | ||
5835 | spin_unlock_irqrestore(&boardp->lock, flags); | ||
5836 | |||
5837 | /* | ||
5838 | * Complete all the 'done_scp' requests. | ||
5839 | */ | ||
5840 | if (done_scp != NULL) { | ||
5841 | asc_scsi_done_list(done_scp); | ||
5842 | } | ||
5843 | |||
5844 | ASC_DBG1(1, "advansys_reset: ret %d\n", ret); | ||
5845 | |||
5846 | return ret; | ||
5847 | } | ||
5848 | |||
5849 | /* | ||
5850 | * advansys_biosparam() | ||
5851 | * | ||
5852 | * Translate disk drive geometry if the "BIOS greater than 1 GB" | ||
5853 | * support is enabled for a drive. | ||
5854 | * | ||
5855 | * ip (information pointer) is an int array with the following definition: | ||
5856 | * ip[0]: heads | ||
5857 | * ip[1]: sectors | ||
5858 | * ip[2]: cylinders | ||
5859 | */ | ||
5860 | int | ||
5861 | advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev, | ||
5862 | sector_t capacity, int ip[]) | ||
5863 | { | ||
5864 | asc_board_t *boardp; | ||
5865 | |||
5866 | ASC_DBG(1, "advansys_biosparam: begin\n"); | ||
5867 | ASC_STATS(sdev->host, biosparam); | ||
5868 | boardp = ASC_BOARDP(sdev->host); | ||
5869 | if (ASC_NARROW_BOARD(boardp)) { | ||
5870 | if ((boardp->dvc_var.asc_dvc_var.dvc_cntl & | ||
5871 | ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) { | ||
5872 | ip[0] = 255; | ||
5873 | ip[1] = 63; | ||
5874 | } else { | ||
5875 | ip[0] = 64; | ||
5876 | ip[1] = 32; | ||
5877 | } | ||
5878 | } else { | ||
5879 | if ((boardp->dvc_var.adv_dvc_var.bios_ctrl & | ||
5880 | BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) { | ||
5881 | ip[0] = 255; | ||
5882 | ip[1] = 63; | ||
5883 | } else { | ||
5884 | ip[0] = 64; | ||
5885 | ip[1] = 32; | ||
5886 | } | ||
5887 | } | ||
5888 | ip[2] = (unsigned long)capacity / (ip[0] * ip[1]); | ||
5889 | ASC_DBG(1, "advansys_biosparam: end\n"); | ||
5890 | return 0; | ||
5891 | } | ||
5892 | |||
5893 | /* | ||
5894 | * advansys_setup() | ||
5895 | * | ||
5896 | * This function is called from init/main.c at boot time. | ||
5897 | * It it passed LILO parameters that can be set from the | ||
5898 | * LILO command line or in /etc/lilo.conf. | ||
5899 | * | ||
5900 | * It is used by the AdvanSys driver to either disable I/O | ||
5901 | * port scanning or to limit scanning to 1 - 4 I/O ports. | ||
5902 | * Regardless of the option setting EISA and PCI boards | ||
5903 | * will still be searched for and detected. This option | ||
5904 | * only affects searching for ISA and VL boards. | ||
5905 | * | ||
5906 | * If ADVANSYS_DEBUG is defined the driver debug level may | ||
5907 | * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. | ||
5908 | * | ||
5909 | * Examples: | ||
5910 | * 1. Eliminate I/O port scanning: | ||
5911 | * boot: linux advansys= | ||
5912 | * or | ||
5913 | * boot: linux advansys=0x0 | ||
5914 | * 2. Limit I/O port scanning to one I/O port: | ||
5915 | * boot: linux advansys=0x110 | ||
5916 | * 3. Limit I/O port scanning to four I/O ports: | ||
5917 | * boot: linux advansys=0x110,0x210,0x230,0x330 | ||
5918 | * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and | ||
5919 | * set the driver debug level to 2. | ||
5920 | * boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2 | ||
5921 | * | ||
5922 | * ints[0] - number of arguments | ||
5923 | * ints[1] - first argument | ||
5924 | * ints[2] - second argument | ||
5925 | * ... | ||
5926 | */ | ||
5927 | void __init | ||
5928 | advansys_setup(char *str, int *ints) | ||
5929 | { | ||
5930 | int i; | ||
5931 | |||
5932 | if (asc_iopflag == ASC_TRUE) { | ||
5933 | printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n"); | ||
5934 | return; | ||
5935 | } | ||
5936 | |||
5937 | asc_iopflag = ASC_TRUE; | ||
5938 | |||
5939 | if (ints[0] > ASC_NUM_IOPORT_PROBE) { | ||
5940 | #ifdef ADVANSYS_DEBUG | ||
5941 | if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) && | ||
5942 | (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) { | ||
5943 | asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf; | ||
5944 | } else { | ||
5945 | #endif /* ADVANSYS_DEBUG */ | ||
5946 | printk("AdvanSys SCSI: only %d I/O ports accepted\n", | ||
5947 | ASC_NUM_IOPORT_PROBE); | ||
5948 | #ifdef ADVANSYS_DEBUG | ||
5949 | } | ||
5950 | #endif /* ADVANSYS_DEBUG */ | ||
5951 | } | ||
5952 | |||
5953 | #ifdef ADVANSYS_DEBUG | ||
5954 | ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]); | ||
5955 | for (i = 1; i < ints[0]; i++) { | ||
5956 | ASC_DBG2(1, " ints[%d] 0x%x", i, ints[i]); | ||
5957 | } | ||
5958 | ASC_DBG(1, "\n"); | ||
5959 | #endif /* ADVANSYS_DEBUG */ | ||
5960 | |||
5961 | for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) { | ||
5962 | asc_ioport[i-1] = ints[i]; | ||
5963 | ASC_DBG2(1, "advansys_setup: asc_ioport[%d] 0x%x\n", | ||
5964 | i - 1, asc_ioport[i-1]); | ||
5965 | } | ||
5966 | } | ||
5967 | |||
5968 | |||
5969 | /* | ||
5970 | * --- Loadable Driver Support | ||
5971 | */ | ||
5972 | |||
5973 | static struct scsi_host_template driver_template = { | ||
5974 | .proc_name = "advansys", | ||
5975 | #ifdef CONFIG_PROC_FS | ||
5976 | .proc_info = advansys_proc_info, | ||
5977 | #endif | ||
5978 | .name = "advansys", | ||
5979 | .detect = advansys_detect, | ||
5980 | .release = advansys_release, | ||
5981 | .info = advansys_info, | ||
5982 | .queuecommand = advansys_queuecommand, | ||
5983 | .eh_bus_reset_handler = advansys_reset, | ||
5984 | .bios_param = advansys_biosparam, | ||
5985 | .slave_configure = advansys_slave_configure, | ||
5986 | /* | ||
5987 | * Because the driver may control an ISA adapter 'unchecked_isa_dma' | ||
5988 | * must be set. The flag will be cleared in advansys_detect for non-ISA | ||
5989 | * adapters. Refer to the comment in scsi_module.c for more information. | ||
5990 | */ | ||
5991 | .unchecked_isa_dma = 1, | ||
5992 | /* | ||
5993 | * All adapters controlled by this driver are capable of large | ||
5994 | * scatter-gather lists. According to the mid-level SCSI documentation | ||
5995 | * this obviates any performance gain provided by setting | ||
5996 | * 'use_clustering'. But empirically while CPU utilization is increased | ||
5997 | * by enabling clustering, I/O throughput increases as well. | ||
5998 | */ | ||
5999 | .use_clustering = ENABLE_CLUSTERING, | ||
6000 | }; | ||
6001 | #include "scsi_module.c" | ||
6002 | |||
6003 | |||
6004 | /* | ||
6005 | * --- Miscellaneous Driver Functions | ||
6006 | */ | ||
6007 | |||
6008 | /* | ||
6009 | * First-level interrupt handler. | ||
6010 | * | ||
6011 | * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because | ||
6012 | * all boards are currently checked for interrupts on each interrupt, 'dev_id' | ||
6013 | * is not referenced. 'dev_id' could be used to identify an interrupt passed | ||
6014 | * to the AdvanSys driver which is for a device sharing an interrupt with | ||
6015 | * an AdvanSys adapter. | ||
6016 | */ | ||
6017 | STATIC irqreturn_t | ||
6018 | advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
6019 | { | ||
6020 | ulong flags; | ||
6021 | int i; | ||
6022 | asc_board_t *boardp; | ||
6023 | struct scsi_cmnd *done_scp = NULL, *last_scp = NULL; | ||
6024 | struct scsi_cmnd *new_last_scp; | ||
6025 | struct Scsi_Host *shp; | ||
6026 | |||
6027 | ASC_DBG(1, "advansys_interrupt: begin\n"); | ||
6028 | |||
6029 | /* | ||
6030 | * Check for interrupts on all boards. | ||
6031 | * AscISR() will call asc_isr_callback(). | ||
6032 | */ | ||
6033 | for (i = 0; i < asc_board_count; i++) { | ||
6034 | shp = asc_host[i]; | ||
6035 | boardp = ASC_BOARDP(shp); | ||
6036 | ASC_DBG2(2, "advansys_interrupt: i %d, boardp 0x%lx\n", | ||
6037 | i, (ulong) boardp); | ||
6038 | spin_lock_irqsave(&boardp->lock, flags); | ||
6039 | if (ASC_NARROW_BOARD(boardp)) { | ||
6040 | /* | ||
6041 | * Narrow Board | ||
6042 | */ | ||
6043 | if (AscIsIntPending(shp->io_port)) { | ||
6044 | ASC_STATS(shp, interrupt); | ||
6045 | ASC_DBG(1, "advansys_interrupt: before AscISR()\n"); | ||
6046 | AscISR(&boardp->dvc_var.asc_dvc_var); | ||
6047 | } | ||
6048 | } else { | ||
6049 | /* | ||
6050 | * Wide Board | ||
6051 | */ | ||
6052 | ASC_DBG(1, "advansys_interrupt: before AdvISR()\n"); | ||
6053 | if (AdvISR(&boardp->dvc_var.adv_dvc_var)) { | ||
6054 | ASC_STATS(shp, interrupt); | ||
6055 | } | ||
6056 | } | ||
6057 | |||
6058 | /* | ||
6059 | * Start waiting requests and create a list of completed requests. | ||
6060 | * | ||
6061 | * If a reset request is being performed for the board, the reset | ||
6062 | * handler will complete pending requests after it has completed. | ||
6063 | */ | ||
6064 | if ((boardp->flags & ASC_HOST_IN_RESET) == 0) { | ||
6065 | ASC_DBG2(1, "advansys_interrupt: done_scp 0x%lx, last_scp 0x%lx\n", | ||
6066 | (ulong) done_scp, (ulong) last_scp); | ||
6067 | |||
6068 | /* Start any waiting commands for the board. */ | ||
6069 | if (!ASC_QUEUE_EMPTY(&boardp->waiting)) { | ||
6070 | ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n"); | ||
6071 | asc_execute_queue(&boardp->waiting); | ||
6072 | } | ||
6073 | |||
6074 | /* | ||
6075 | * Add to the list of requests that must be completed. | ||
6076 | * | ||
6077 | * 'done_scp' will always be NULL on the first iteration | ||
6078 | * of this loop. 'last_scp' is set at the same time as | ||
6079 | * 'done_scp'. | ||
6080 | */ | ||
6081 | if (done_scp == NULL) { | ||
6082 | done_scp = asc_dequeue_list(&boardp->done, &last_scp, | ||
6083 | ASC_TID_ALL); | ||
6084 | } else { | ||
6085 | ASC_ASSERT(last_scp != NULL); | ||
6086 | last_scp->host_scribble = (unsigned char *)asc_dequeue_list( | ||
6087 | &boardp->done, &new_last_scp, ASC_TID_ALL); | ||
6088 | if (new_last_scp != NULL) { | ||
6089 | ASC_ASSERT(REQPNEXT(last_scp) != NULL); | ||
6090 | last_scp = new_last_scp; | ||
6091 | } | ||
6092 | } | ||
6093 | } | ||
6094 | spin_unlock_irqrestore(&boardp->lock, flags); | ||
6095 | } | ||
6096 | |||
6097 | /* | ||
6098 | * If interrupts were enabled on entry, then they | ||
6099 | * are now enabled here. | ||
6100 | * | ||
6101 | * Complete all requests on the done list. | ||
6102 | */ | ||
6103 | |||
6104 | asc_scsi_done_list(done_scp); | ||
6105 | |||
6106 | ASC_DBG(1, "advansys_interrupt: end\n"); | ||
6107 | return IRQ_HANDLED; | ||
6108 | } | ||
6109 | |||
6110 | /* | ||
6111 | * Set the number of commands to queue per device for the | ||
6112 | * specified host adapter. | ||
6113 | */ | ||
6114 | STATIC int | ||
6115 | advansys_slave_configure(struct scsi_device *device) | ||
6116 | { | ||
6117 | asc_board_t *boardp; | ||
6118 | |||
6119 | boardp = ASC_BOARDP(device->host); | ||
6120 | boardp->flags |= ASC_SELECT_QUEUE_DEPTHS; | ||
6121 | /* | ||
6122 | * Save a pointer to the device and set its initial/maximum | ||
6123 | * queue depth. Only save the pointer for a lun0 dev though. | ||
6124 | */ | ||
6125 | if(device->lun == 0) | ||
6126 | boardp->device[device->id] = device; | ||
6127 | if(device->tagged_supported) { | ||
6128 | if (ASC_NARROW_BOARD(boardp)) { | ||
6129 | scsi_adjust_queue_depth(device, MSG_ORDERED_TAG, | ||
6130 | boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id]); | ||
6131 | } else { | ||
6132 | scsi_adjust_queue_depth(device, MSG_ORDERED_TAG, | ||
6133 | boardp->dvc_var.adv_dvc_var.max_dvc_qng); | ||
6134 | } | ||
6135 | } else { | ||
6136 | scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun); | ||
6137 | } | ||
6138 | ASC_DBG4(1, "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n", | ||
6139 | (ulong) device, (ulong) boardp, device->id, device->queue_depth); | ||
6140 | return 0; | ||
6141 | } | ||
6142 | |||
6143 | /* | ||
6144 | * Complete all requests on the singly linked list pointed | ||
6145 | * to by 'scp'. | ||
6146 | * | ||
6147 | * Interrupts can be enabled on entry. | ||
6148 | */ | ||
6149 | STATIC void | ||
6150 | asc_scsi_done_list(struct scsi_cmnd *scp) | ||
6151 | { | ||
6152 | struct scsi_cmnd *tscp; | ||
6153 | |||
6154 | ASC_DBG(2, "asc_scsi_done_list: begin\n"); | ||
6155 | while (scp != NULL) { | ||
6156 | asc_board_t *boardp; | ||
6157 | struct device *dev; | ||
6158 | |||
6159 | ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp); | ||
6160 | tscp = REQPNEXT(scp); | ||
6161 | scp->host_scribble = NULL; | ||
6162 | |||
6163 | boardp = ASC_BOARDP(scp->device->host); | ||
6164 | |||
6165 | if (ASC_NARROW_BOARD(boardp)) | ||
6166 | dev = boardp->dvc_cfg.asc_dvc_cfg.dev; | ||
6167 | else | ||
6168 | dev = boardp->dvc_cfg.adv_dvc_cfg.dev; | ||
6169 | |||
6170 | if (scp->use_sg) | ||
6171 | dma_unmap_sg(dev, (struct scatterlist *)scp->request_buffer, | ||
6172 | scp->use_sg, scp->sc_data_direction); | ||
6173 | else if (scp->request_bufflen) | ||
6174 | dma_unmap_single(dev, scp->SCp.dma_handle, | ||
6175 | scp->request_bufflen, scp->sc_data_direction); | ||
6176 | |||
6177 | ASC_STATS(scp->device->host, done); | ||
6178 | ASC_ASSERT(scp->scsi_done != NULL); | ||
6179 | |||
6180 | scp->scsi_done(scp); | ||
6181 | |||
6182 | scp = tscp; | ||
6183 | } | ||
6184 | ASC_DBG(2, "asc_scsi_done_list: done\n"); | ||
6185 | return; | ||
6186 | } | ||
6187 | |||
6188 | /* | ||
6189 | * Execute a single 'Scsi_Cmnd'. | ||
6190 | * | ||
6191 | * The function 'done' is called when the request has been completed. | ||
6192 | * | ||
6193 | * Scsi_Cmnd: | ||
6194 | * | ||
6195 | * host - board controlling device | ||
6196 | * device - device to send command | ||
6197 | * target - target of device | ||
6198 | * lun - lun of device | ||
6199 | * cmd_len - length of SCSI CDB | ||
6200 | * cmnd - buffer for SCSI 8, 10, or 12 byte CDB | ||
6201 | * use_sg - if non-zero indicates scatter-gather request with use_sg elements | ||
6202 | * | ||
6203 | * if (use_sg == 0) { | ||
6204 | * request_buffer - buffer address for request | ||
6205 | * request_bufflen - length of request buffer | ||
6206 | * } else { | ||
6207 | * request_buffer - pointer to scatterlist structure | ||
6208 | * } | ||
6209 | * | ||
6210 | * sense_buffer - sense command buffer | ||
6211 | * | ||
6212 | * result (4 bytes of an int): | ||
6213 | * Byte Meaning | ||
6214 | * 0 SCSI Status Byte Code | ||
6215 | * 1 SCSI One Byte Message Code | ||
6216 | * 2 Host Error Code | ||
6217 | * 3 Mid-Level Error Code | ||
6218 | * | ||
6219 | * host driver fields: | ||
6220 | * SCp - Scsi_Pointer used for command processing status | ||
6221 | * scsi_done - used to save caller's done function | ||
6222 | * host_scribble - used for pointer to another struct scsi_cmnd | ||
6223 | * | ||
6224 | * If this function returns ASC_NOERROR the request has been enqueued | ||
6225 | * on the board's 'active' queue and will be completed from the | ||
6226 | * interrupt handler. | ||
6227 | * | ||
6228 | * If this function returns ASC_NOERROR the request has been enqueued | ||
6229 | * on the board's 'done' queue and must be completed by the caller. | ||
6230 | * | ||
6231 | * If ASC_BUSY is returned the request will be enqueued by the | ||
6232 | * caller on the target's waiting queue and re-tried later. | ||
6233 | */ | ||
6234 | STATIC int | ||
6235 | asc_execute_scsi_cmnd(struct scsi_cmnd *scp) | ||
6236 | { | ||
6237 | asc_board_t *boardp; | ||
6238 | ASC_DVC_VAR *asc_dvc_varp; | ||
6239 | ADV_DVC_VAR *adv_dvc_varp; | ||
6240 | ADV_SCSI_REQ_Q *adv_scsiqp; | ||
6241 | struct scsi_device *device; | ||
6242 | int ret; | ||
6243 | |||
6244 | ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n", | ||
6245 | (ulong) scp, (ulong) scp->scsi_done); | ||
6246 | |||
6247 | boardp = ASC_BOARDP(scp->device->host); | ||
6248 | device = boardp->device[scp->device->id]; | ||
6249 | |||
6250 | if (ASC_NARROW_BOARD(boardp)) { | ||
6251 | /* | ||
6252 | * Build and execute Narrow Board request. | ||
6253 | */ | ||
6254 | |||
6255 | asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; | ||
6256 | |||
6257 | /* | ||
6258 | * Build Asc Library request structure using the | ||
6259 | * global structures 'asc_scsi_req' and 'asc_sg_head'. | ||
6260 | * | ||
6261 | * If an error is returned, then the request has been | ||
6262 | * queued on the board done queue. It will be completed | ||
6263 | * by the caller. | ||
6264 | * | ||
6265 | * asc_build_req() can not return ASC_BUSY. | ||
6266 | */ | ||
6267 | if (asc_build_req(boardp, scp) == ASC_ERROR) { | ||
6268 | ASC_STATS(scp->device->host, build_error); | ||
6269 | return ASC_ERROR; | ||
6270 | } | ||
6271 | |||
6272 | /* | ||
6273 | * Execute the command. If there is no error, add the command | ||
6274 | * to the active queue. | ||
6275 | */ | ||
6276 | switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) { | ||
6277 | case ASC_NOERROR: | ||
6278 | ASC_STATS(scp->device->host, exe_noerror); | ||
6279 | /* | ||
6280 | * Increment monotonically increasing per device successful | ||
6281 | * request counter. Wrapping doesn't matter. | ||
6282 | */ | ||
6283 | boardp->reqcnt[scp->device->id]++; | ||
6284 | asc_enqueue(&boardp->active, scp, ASC_BACK); | ||
6285 | ASC_DBG(1, | ||
6286 | "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n"); | ||
6287 | break; | ||
6288 | case ASC_BUSY: | ||
6289 | /* | ||
6290 | * Caller will enqueue request on the target's waiting queue | ||
6291 | * and retry later. | ||
6292 | */ | ||
6293 | ASC_STATS(scp->device->host, exe_busy); | ||
6294 | break; | ||
6295 | case ASC_ERROR: | ||
6296 | ASC_PRINT2( | ||
6297 | "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n", | ||
6298 | boardp->id, asc_dvc_varp->err_code); | ||
6299 | ASC_STATS(scp->device->host, exe_error); | ||
6300 | scp->result = HOST_BYTE(DID_ERROR); | ||
6301 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
6302 | break; | ||
6303 | default: | ||
6304 | ASC_PRINT2( | ||
6305 | "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n", | ||
6306 | boardp->id, asc_dvc_varp->err_code); | ||
6307 | ASC_STATS(scp->device->host, exe_unknown); | ||
6308 | scp->result = HOST_BYTE(DID_ERROR); | ||
6309 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
6310 | break; | ||
6311 | } | ||
6312 | } else { | ||
6313 | /* | ||
6314 | * Build and execute Wide Board request. | ||
6315 | */ | ||
6316 | adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; | ||
6317 | |||
6318 | /* | ||
6319 | * Build and get a pointer to an Adv Library request structure. | ||
6320 | * | ||
6321 | * If the request is successfully built then send it below, | ||
6322 | * otherwise return with an error. | ||
6323 | */ | ||
6324 | switch (adv_build_req(boardp, scp, &adv_scsiqp)) { | ||
6325 | case ASC_NOERROR: | ||
6326 | ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n"); | ||
6327 | break; | ||
6328 | case ASC_BUSY: | ||
6329 | ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n"); | ||
6330 | /* | ||
6331 | * If busy is returned the request has not been enqueued. | ||
6332 | * It will be enqueued by the caller on the target's waiting | ||
6333 | * queue and retried later. | ||
6334 | * | ||
6335 | * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg' | ||
6336 | * count wide board busy conditions. They are updated in | ||
6337 | * adv_build_req and adv_get_sglist, respectively. | ||
6338 | */ | ||
6339 | return ASC_BUSY; | ||
6340 | case ASC_ERROR: | ||
6341 | /* | ||
6342 | * If an error is returned, then the request has been | ||
6343 | * queued on the board done queue. It will be completed | ||
6344 | * by the caller. | ||
6345 | */ | ||
6346 | default: | ||
6347 | ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n"); | ||
6348 | ASC_STATS(scp->device->host, build_error); | ||
6349 | return ASC_ERROR; | ||
6350 | } | ||
6351 | |||
6352 | /* | ||
6353 | * Execute the command. If there is no error, add the command | ||
6354 | * to the active queue. | ||
6355 | */ | ||
6356 | switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) { | ||
6357 | case ASC_NOERROR: | ||
6358 | ASC_STATS(scp->device->host, exe_noerror); | ||
6359 | /* | ||
6360 | * Increment monotonically increasing per device successful | ||
6361 | * request counter. Wrapping doesn't matter. | ||
6362 | */ | ||
6363 | boardp->reqcnt[scp->device->id]++; | ||
6364 | asc_enqueue(&boardp->active, scp, ASC_BACK); | ||
6365 | ASC_DBG(1, | ||
6366 | "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n"); | ||
6367 | break; | ||
6368 | case ASC_BUSY: | ||
6369 | /* | ||
6370 | * Caller will enqueue request on the target's waiting queue | ||
6371 | * and retry later. | ||
6372 | */ | ||
6373 | ASC_STATS(scp->device->host, exe_busy); | ||
6374 | break; | ||
6375 | case ASC_ERROR: | ||
6376 | ASC_PRINT2( | ||
6377 | "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n", | ||
6378 | boardp->id, adv_dvc_varp->err_code); | ||
6379 | ASC_STATS(scp->device->host, exe_error); | ||
6380 | scp->result = HOST_BYTE(DID_ERROR); | ||
6381 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
6382 | break; | ||
6383 | default: | ||
6384 | ASC_PRINT2( | ||
6385 | "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n", | ||
6386 | boardp->id, adv_dvc_varp->err_code); | ||
6387 | ASC_STATS(scp->device->host, exe_unknown); | ||
6388 | scp->result = HOST_BYTE(DID_ERROR); | ||
6389 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
6390 | break; | ||
6391 | } | ||
6392 | } | ||
6393 | |||
6394 | ASC_DBG(1, "asc_execute_scsi_cmnd: end\n"); | ||
6395 | return ret; | ||
6396 | } | ||
6397 | |||
6398 | /* | ||
6399 | * Build a request structure for the Asc Library (Narrow Board). | ||
6400 | * | ||
6401 | * The global structures 'asc_scsi_q' and 'asc_sg_head' are | ||
6402 | * used to build the request. | ||
6403 | * | ||
6404 | * If an error occurs, then queue the request on the board done | ||
6405 | * queue and return ASC_ERROR. | ||
6406 | */ | ||
6407 | STATIC int | ||
6408 | asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) | ||
6409 | { | ||
6410 | struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev; | ||
6411 | |||
6412 | /* | ||
6413 | * Mutually exclusive access is required to 'asc_scsi_q' and | ||
6414 | * 'asc_sg_head' until after the request is started. | ||
6415 | */ | ||
6416 | memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q)); | ||
6417 | |||
6418 | /* | ||
6419 | * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'. | ||
6420 | */ | ||
6421 | asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp); | ||
6422 | |||
6423 | /* | ||
6424 | * Build the ASC_SCSI_Q request. | ||
6425 | * | ||
6426 | * For narrow boards a CDB length maximum of 12 bytes | ||
6427 | * is supported. | ||
6428 | */ | ||
6429 | if (scp->cmd_len > ASC_MAX_CDB_LEN) { | ||
6430 | ASC_PRINT3( | ||
6431 | "asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN %d\n", | ||
6432 | boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN); | ||
6433 | scp->result = HOST_BYTE(DID_ERROR); | ||
6434 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
6435 | return ASC_ERROR; | ||
6436 | } | ||
6437 | asc_scsi_q.cdbptr = &scp->cmnd[0]; | ||
6438 | asc_scsi_q.q2.cdb_len = scp->cmd_len; | ||
6439 | asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id); | ||
6440 | asc_scsi_q.q1.target_lun = scp->device->lun; | ||
6441 | asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun); | ||
6442 | asc_scsi_q.q1.sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0])); | ||
6443 | asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer); | ||
6444 | |||
6445 | /* | ||
6446 | * If there are any outstanding requests for the current target, | ||
6447 | * then every 255th request send an ORDERED request. This heuristic | ||
6448 | * tries to retain the benefit of request sorting while preventing | ||
6449 | * request starvation. 255 is the max number of tags or pending commands | ||
6450 | * a device may have outstanding. | ||
6451 | * | ||
6452 | * The request count is incremented below for every successfully | ||
6453 | * started request. | ||
6454 | * | ||
6455 | */ | ||
6456 | if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) && | ||
6457 | (boardp->reqcnt[scp->device->id] % 255) == 0) { | ||
6458 | asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG; | ||
6459 | } else { | ||
6460 | asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG; | ||
6461 | } | ||
6462 | |||
6463 | /* | ||
6464 | * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather | ||
6465 | * buffer command. | ||
6466 | */ | ||
6467 | if (scp->use_sg == 0) { | ||
6468 | /* | ||
6469 | * CDB request of single contiguous buffer. | ||
6470 | */ | ||
6471 | ASC_STATS(scp->device->host, cont_cnt); | ||
6472 | scp->SCp.dma_handle = scp->request_bufflen ? | ||
6473 | dma_map_single(dev, scp->request_buffer, | ||
6474 | scp->request_bufflen, scp->sc_data_direction) : 0; | ||
6475 | asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle); | ||
6476 | asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen); | ||
6477 | ASC_STATS_ADD(scp->device->host, cont_xfer, | ||
6478 | ASC_CEILING(scp->request_bufflen, 512)); | ||
6479 | asc_scsi_q.q1.sg_queue_cnt = 0; | ||
6480 | asc_scsi_q.sg_head = NULL; | ||
6481 | } else { | ||
6482 | /* | ||
6483 | * CDB scatter-gather request list. | ||
6484 | */ | ||
6485 | int sgcnt; | ||
6486 | int use_sg; | ||
6487 | struct scatterlist *slp; | ||
6488 | |||
6489 | slp = (struct scatterlist *)scp->request_buffer; | ||
6490 | use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction); | ||
6491 | |||
6492 | if (use_sg > scp->device->host->sg_tablesize) { | ||
6493 | ASC_PRINT3( | ||
6494 | "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n", | ||
6495 | boardp->id, use_sg, scp->device->host->sg_tablesize); | ||
6496 | dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction); | ||
6497 | scp->result = HOST_BYTE(DID_ERROR); | ||
6498 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
6499 | return ASC_ERROR; | ||
6500 | } | ||
6501 | |||
6502 | ASC_STATS(scp->device->host, sg_cnt); | ||
6503 | |||
6504 | /* | ||
6505 | * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q | ||
6506 | * structure to point to it. | ||
6507 | */ | ||
6508 | memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD)); | ||
6509 | |||
6510 | asc_scsi_q.q1.cntl |= QC_SG_HEAD; | ||
6511 | asc_scsi_q.sg_head = &asc_sg_head; | ||
6512 | asc_scsi_q.q1.data_cnt = 0; | ||
6513 | asc_scsi_q.q1.data_addr = 0; | ||
6514 | /* This is a byte value, otherwise it would need to be swapped. */ | ||
6515 | asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg; | ||
6516 | ASC_STATS_ADD(scp->device->host, sg_elem, asc_sg_head.entry_cnt); | ||
6517 | |||
6518 | /* | ||
6519 | * Convert scatter-gather list into ASC_SG_HEAD list. | ||
6520 | */ | ||
6521 | for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) { | ||
6522 | asc_sg_head.sg_list[sgcnt].addr = cpu_to_le32(sg_dma_address(slp)); | ||
6523 | asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(sg_dma_len(slp)); | ||
6524 | ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512)); | ||
6525 | } | ||
6526 | } | ||
6527 | |||
6528 | ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q); | ||
6529 | ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len); | ||
6530 | |||
6531 | return ASC_NOERROR; | ||
6532 | } | ||
6533 | |||
6534 | /* | ||
6535 | * Build a request structure for the Adv Library (Wide Board). | ||
6536 | * | ||
6537 | * If an adv_req_t can not be allocated to issue the request, | ||
6538 | * then return ASC_BUSY. If an error occurs, then return ASC_ERROR. | ||
6539 | * | ||
6540 | * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the | ||
6541 | * microcode for DMA addresses or math operations are byte swapped | ||
6542 | * to little-endian order. | ||
6543 | */ | ||
6544 | STATIC int | ||
6545 | adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp, | ||
6546 | ADV_SCSI_REQ_Q **adv_scsiqpp) | ||
6547 | { | ||
6548 | adv_req_t *reqp; | ||
6549 | ADV_SCSI_REQ_Q *scsiqp; | ||
6550 | int i; | ||
6551 | int ret; | ||
6552 | struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev; | ||
6553 | |||
6554 | /* | ||
6555 | * Allocate an adv_req_t structure from the board to execute | ||
6556 | * the command. | ||
6557 | */ | ||
6558 | if (boardp->adv_reqp == NULL) { | ||
6559 | ASC_DBG(1, "adv_build_req: no free adv_req_t\n"); | ||
6560 | ASC_STATS(scp->device->host, adv_build_noreq); | ||
6561 | return ASC_BUSY; | ||
6562 | } else { | ||
6563 | reqp = boardp->adv_reqp; | ||
6564 | boardp->adv_reqp = reqp->next_reqp; | ||
6565 | reqp->next_reqp = NULL; | ||
6566 | } | ||
6567 | |||
6568 | /* | ||
6569 | * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers. | ||
6570 | */ | ||
6571 | scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q); | ||
6572 | |||
6573 | /* | ||
6574 | * Initialize the structure. | ||
6575 | */ | ||
6576 | scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0; | ||
6577 | |||
6578 | /* | ||
6579 | * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure. | ||
6580 | */ | ||
6581 | scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp); | ||
6582 | |||
6583 | /* | ||
6584 | * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure. | ||
6585 | */ | ||
6586 | reqp->cmndp = scp; | ||
6587 | |||
6588 | /* | ||
6589 | * Build the ADV_SCSI_REQ_Q request. | ||
6590 | */ | ||
6591 | |||
6592 | /* | ||
6593 | * Set CDB length and copy it to the request structure. | ||
6594 | * For wide boards a CDB length maximum of 16 bytes | ||
6595 | * is supported. | ||
6596 | */ | ||
6597 | if (scp->cmd_len > ADV_MAX_CDB_LEN) { | ||
6598 | ASC_PRINT3( | ||
6599 | "adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n", | ||
6600 | boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN); | ||
6601 | scp->result = HOST_BYTE(DID_ERROR); | ||
6602 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
6603 | return ASC_ERROR; | ||
6604 | } | ||
6605 | scsiqp->cdb_len = scp->cmd_len; | ||
6606 | /* Copy first 12 CDB bytes to cdb[]. */ | ||
6607 | for (i = 0; i < scp->cmd_len && i < 12; i++) { | ||
6608 | scsiqp->cdb[i] = scp->cmnd[i]; | ||
6609 | } | ||
6610 | /* Copy last 4 CDB bytes, if present, to cdb16[]. */ | ||
6611 | for (; i < scp->cmd_len; i++) { | ||
6612 | scsiqp->cdb16[i - 12] = scp->cmnd[i]; | ||
6613 | } | ||
6614 | |||
6615 | scsiqp->target_id = scp->device->id; | ||
6616 | scsiqp->target_lun = scp->device->lun; | ||
6617 | |||
6618 | scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0])); | ||
6619 | scsiqp->sense_len = sizeof(scp->sense_buffer); | ||
6620 | |||
6621 | /* | ||
6622 | * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather | ||
6623 | * buffer command. | ||
6624 | */ | ||
6625 | |||
6626 | scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen); | ||
6627 | scsiqp->vdata_addr = scp->request_buffer; | ||
6628 | scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer)); | ||
6629 | |||
6630 | if (scp->use_sg == 0) { | ||
6631 | /* | ||
6632 | * CDB request of single contiguous buffer. | ||
6633 | */ | ||
6634 | reqp->sgblkp = NULL; | ||
6635 | scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen); | ||
6636 | if (scp->request_bufflen) { | ||
6637 | scsiqp->vdata_addr = scp->request_buffer; | ||
6638 | scp->SCp.dma_handle = | ||
6639 | dma_map_single(dev, scp->request_buffer, | ||
6640 | scp->request_bufflen, scp->sc_data_direction); | ||
6641 | } else { | ||
6642 | scsiqp->vdata_addr = 0; | ||
6643 | scp->SCp.dma_handle = 0; | ||
6644 | } | ||
6645 | scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle); | ||
6646 | scsiqp->sg_list_ptr = NULL; | ||
6647 | scsiqp->sg_real_addr = 0; | ||
6648 | ASC_STATS(scp->device->host, cont_cnt); | ||
6649 | ASC_STATS_ADD(scp->device->host, cont_xfer, | ||
6650 | ASC_CEILING(scp->request_bufflen, 512)); | ||
6651 | } else { | ||
6652 | /* | ||
6653 | * CDB scatter-gather request list. | ||
6654 | */ | ||
6655 | struct scatterlist *slp; | ||
6656 | int use_sg; | ||
6657 | |||
6658 | slp = (struct scatterlist *)scp->request_buffer; | ||
6659 | use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction); | ||
6660 | |||
6661 | if (use_sg > ADV_MAX_SG_LIST) { | ||
6662 | ASC_PRINT3( | ||
6663 | "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n", | ||
6664 | boardp->id, use_sg, scp->device->host->sg_tablesize); | ||
6665 | dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction); | ||
6666 | scp->result = HOST_BYTE(DID_ERROR); | ||
6667 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
6668 | |||
6669 | /* | ||
6670 | * Free the 'adv_req_t' structure by adding it back to the | ||
6671 | * board free list. | ||
6672 | */ | ||
6673 | reqp->next_reqp = boardp->adv_reqp; | ||
6674 | boardp->adv_reqp = reqp; | ||
6675 | |||
6676 | return ASC_ERROR; | ||
6677 | } | ||
6678 | |||
6679 | if ((ret = adv_get_sglist(boardp, reqp, scp, use_sg)) != ADV_SUCCESS) { | ||
6680 | /* | ||
6681 | * Free the adv_req_t structure by adding it back to the | ||
6682 | * board free list. | ||
6683 | */ | ||
6684 | reqp->next_reqp = boardp->adv_reqp; | ||
6685 | boardp->adv_reqp = reqp; | ||
6686 | |||
6687 | return ret; | ||
6688 | } | ||
6689 | |||
6690 | ASC_STATS(scp->device->host, sg_cnt); | ||
6691 | ASC_STATS_ADD(scp->device->host, sg_elem, use_sg); | ||
6692 | } | ||
6693 | |||
6694 | ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp); | ||
6695 | ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len); | ||
6696 | |||
6697 | *adv_scsiqpp = scsiqp; | ||
6698 | |||
6699 | return ASC_NOERROR; | ||
6700 | } | ||
6701 | |||
6702 | /* | ||
6703 | * Build scatter-gather list for Adv Library (Wide Board). | ||
6704 | * | ||
6705 | * Additional ADV_SG_BLOCK structures will need to be allocated | ||
6706 | * if the total number of scatter-gather elements exceeds | ||
6707 | * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are | ||
6708 | * assumed to be physically contiguous. | ||
6709 | * | ||
6710 | * Return: | ||
6711 | * ADV_SUCCESS(1) - SG List successfully created | ||
6712 | * ADV_ERROR(-1) - SG List creation failed | ||
6713 | */ | ||
6714 | STATIC int | ||
6715 | adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, int use_sg) | ||
6716 | { | ||
6717 | adv_sgblk_t *sgblkp; | ||
6718 | ADV_SCSI_REQ_Q *scsiqp; | ||
6719 | struct scatterlist *slp; | ||
6720 | int sg_elem_cnt; | ||
6721 | ADV_SG_BLOCK *sg_block, *prev_sg_block; | ||
6722 | ADV_PADDR sg_block_paddr; | ||
6723 | int i; | ||
6724 | |||
6725 | scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q); | ||
6726 | slp = (struct scatterlist *) scp->request_buffer; | ||
6727 | sg_elem_cnt = use_sg; | ||
6728 | prev_sg_block = NULL; | ||
6729 | reqp->sgblkp = NULL; | ||
6730 | |||
6731 | do | ||
6732 | { | ||
6733 | /* | ||
6734 | * Allocate a 'adv_sgblk_t' structure from the board free | ||
6735 | * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK | ||
6736 | * (15) scatter-gather elements. | ||
6737 | */ | ||
6738 | if ((sgblkp = boardp->adv_sgblkp) == NULL) { | ||
6739 | ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n"); | ||
6740 | ASC_STATS(scp->device->host, adv_build_nosg); | ||
6741 | |||
6742 | /* | ||
6743 | * Allocation failed. Free 'adv_sgblk_t' structures already | ||
6744 | * allocated for the request. | ||
6745 | */ | ||
6746 | while ((sgblkp = reqp->sgblkp) != NULL) | ||
6747 | { | ||
6748 | /* Remove 'sgblkp' from the request list. */ | ||
6749 | reqp->sgblkp = sgblkp->next_sgblkp; | ||
6750 | |||
6751 | /* Add 'sgblkp' to the board free list. */ | ||
6752 | sgblkp->next_sgblkp = boardp->adv_sgblkp; | ||
6753 | boardp->adv_sgblkp = sgblkp; | ||
6754 | } | ||
6755 | return ASC_BUSY; | ||
6756 | } else { | ||
6757 | /* Complete 'adv_sgblk_t' board allocation. */ | ||
6758 | boardp->adv_sgblkp = sgblkp->next_sgblkp; | ||
6759 | sgblkp->next_sgblkp = NULL; | ||
6760 | |||
6761 | /* | ||
6762 | * Get 8 byte aligned virtual and physical addresses for | ||
6763 | * the allocated ADV_SG_BLOCK structure. | ||
6764 | */ | ||
6765 | sg_block = (ADV_SG_BLOCK *) ADV_8BALIGN(&sgblkp->sg_block); | ||
6766 | sg_block_paddr = virt_to_bus(sg_block); | ||
6767 | |||
6768 | /* | ||
6769 | * Check if this is the first 'adv_sgblk_t' for the request. | ||
6770 | */ | ||
6771 | if (reqp->sgblkp == NULL) | ||
6772 | { | ||
6773 | /* Request's first scatter-gather block. */ | ||
6774 | reqp->sgblkp = sgblkp; | ||
6775 | |||
6776 | /* | ||
6777 | * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical | ||
6778 | * address pointers. | ||
6779 | */ | ||
6780 | scsiqp->sg_list_ptr = sg_block; | ||
6781 | scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr); | ||
6782 | } else | ||
6783 | { | ||
6784 | /* Request's second or later scatter-gather block. */ | ||
6785 | sgblkp->next_sgblkp = reqp->sgblkp; | ||
6786 | reqp->sgblkp = sgblkp; | ||
6787 | |||
6788 | /* | ||
6789 | * Point the previous ADV_SG_BLOCK structure to | ||
6790 | * the newly allocated ADV_SG_BLOCK structure. | ||
6791 | */ | ||
6792 | ASC_ASSERT(prev_sg_block != NULL); | ||
6793 | prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr); | ||
6794 | } | ||
6795 | } | ||
6796 | |||
6797 | for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) | ||
6798 | { | ||
6799 | sg_block->sg_list[i].sg_addr = cpu_to_le32(sg_dma_address(slp)); | ||
6800 | sg_block->sg_list[i].sg_count = cpu_to_le32(sg_dma_len(slp)); | ||
6801 | ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512)); | ||
6802 | |||
6803 | if (--sg_elem_cnt == 0) | ||
6804 | { /* Last ADV_SG_BLOCK and scatter-gather entry. */ | ||
6805 | sg_block->sg_cnt = i + 1; | ||
6806 | sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */ | ||
6807 | return ADV_SUCCESS; | ||
6808 | } | ||
6809 | slp++; | ||
6810 | } | ||
6811 | sg_block->sg_cnt = NO_OF_SG_PER_BLOCK; | ||
6812 | prev_sg_block = sg_block; | ||
6813 | } | ||
6814 | while (1); | ||
6815 | /* NOTREACHED */ | ||
6816 | } | ||
6817 | |||
6818 | /* | ||
6819 | * asc_isr_callback() - Second Level Interrupt Handler called by AscISR(). | ||
6820 | * | ||
6821 | * Interrupt callback function for the Narrow SCSI Asc Library. | ||
6822 | */ | ||
6823 | STATIC void | ||
6824 | asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) | ||
6825 | { | ||
6826 | asc_board_t *boardp; | ||
6827 | struct scsi_cmnd *scp; | ||
6828 | struct Scsi_Host *shp; | ||
6829 | int i; | ||
6830 | |||
6831 | ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n", | ||
6832 | (ulong) asc_dvc_varp, (ulong) qdonep); | ||
6833 | ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep); | ||
6834 | |||
6835 | /* | ||
6836 | * Get the struct scsi_cmnd structure and Scsi_Host structure for the | ||
6837 | * command that has been completed. | ||
6838 | */ | ||
6839 | scp = (struct scsi_cmnd *) ASC_U32_TO_VADDR(qdonep->d2.srb_ptr); | ||
6840 | ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong) scp); | ||
6841 | |||
6842 | if (scp == NULL) { | ||
6843 | ASC_PRINT("asc_isr_callback: scp is NULL\n"); | ||
6844 | return; | ||
6845 | } | ||
6846 | ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len); | ||
6847 | |||
6848 | /* | ||
6849 | * If the request's host pointer is not valid, display a | ||
6850 | * message and return. | ||
6851 | */ | ||
6852 | shp = scp->device->host; | ||
6853 | for (i = 0; i < asc_board_count; i++) { | ||
6854 | if (asc_host[i] == shp) { | ||
6855 | break; | ||
6856 | } | ||
6857 | } | ||
6858 | if (i == asc_board_count) { | ||
6859 | ASC_PRINT2( | ||
6860 | "asc_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n", | ||
6861 | (ulong) scp, (ulong) shp); | ||
6862 | return; | ||
6863 | } | ||
6864 | |||
6865 | ASC_STATS(shp, callback); | ||
6866 | ASC_DBG1(1, "asc_isr_callback: shp 0x%lx\n", (ulong) shp); | ||
6867 | |||
6868 | /* | ||
6869 | * If the request isn't found on the active queue, it may | ||
6870 | * have been removed to handle a reset request. | ||
6871 | * Display a message and return. | ||
6872 | */ | ||
6873 | boardp = ASC_BOARDP(shp); | ||
6874 | ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var); | ||
6875 | if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) { | ||
6876 | ASC_PRINT2( | ||
6877 | "asc_isr_callback: board %d: scp 0x%lx not on active queue\n", | ||
6878 | boardp->id, (ulong) scp); | ||
6879 | return; | ||
6880 | } | ||
6881 | |||
6882 | /* | ||
6883 | * 'qdonep' contains the command's ending status. | ||
6884 | */ | ||
6885 | switch (qdonep->d3.done_stat) { | ||
6886 | case QD_NO_ERROR: | ||
6887 | ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n"); | ||
6888 | scp->result = 0; | ||
6889 | |||
6890 | /* | ||
6891 | * If an INQUIRY command completed successfully, then call | ||
6892 | * the AscInquiryHandling() function to set-up the device. | ||
6893 | */ | ||
6894 | if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 && | ||
6895 | (scp->request_bufflen - qdonep->remain_bytes) >= 8) | ||
6896 | { | ||
6897 | AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7, | ||
6898 | (ASC_SCSI_INQUIRY *) scp->request_buffer); | ||
6899 | } | ||
6900 | |||
6901 | /* | ||
6902 | * Check for an underrun condition. | ||
6903 | * | ||
6904 | * If there was no error and an underrun condition, then | ||
6905 | * then return the number of underrun bytes. | ||
6906 | */ | ||
6907 | if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 && | ||
6908 | qdonep->remain_bytes <= scp->request_bufflen) { | ||
6909 | ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n", | ||
6910 | (unsigned) qdonep->remain_bytes); | ||
6911 | scp->resid = qdonep->remain_bytes; | ||
6912 | } | ||
6913 | break; | ||
6914 | |||
6915 | case QD_WITH_ERROR: | ||
6916 | ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n"); | ||
6917 | switch (qdonep->d3.host_stat) { | ||
6918 | case QHSTA_NO_ERROR: | ||
6919 | if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) { | ||
6920 | ASC_DBG(2, "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n"); | ||
6921 | ASC_DBG_PRT_SENSE(2, scp->sense_buffer, | ||
6922 | sizeof(scp->sense_buffer)); | ||
6923 | /* | ||
6924 | * Note: The 'status_byte()' macro used by target drivers | ||
6925 | * defined in scsi.h shifts the status byte returned by | ||
6926 | * host drivers right by 1 bit. This is why target drivers | ||
6927 | * also use right shifted status byte definitions. For | ||
6928 | * instance target drivers use CHECK_CONDITION, defined to | ||
6929 | * 0x1, instead of the SCSI defined check condition value | ||
6930 | * of 0x2. Host drivers are supposed to return the status | ||
6931 | * byte as it is defined by SCSI. | ||
6932 | */ | ||
6933 | scp->result = DRIVER_BYTE(DRIVER_SENSE) | | ||
6934 | STATUS_BYTE(qdonep->d3.scsi_stat); | ||
6935 | } else { | ||
6936 | scp->result = STATUS_BYTE(qdonep->d3.scsi_stat); | ||
6937 | } | ||
6938 | break; | ||
6939 | |||
6940 | default: | ||
6941 | /* QHSTA error occurred */ | ||
6942 | ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n", | ||
6943 | qdonep->d3.host_stat); | ||
6944 | scp->result = HOST_BYTE(DID_BAD_TARGET); | ||
6945 | break; | ||
6946 | } | ||
6947 | break; | ||
6948 | |||
6949 | case QD_ABORTED_BY_HOST: | ||
6950 | ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n"); | ||
6951 | scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) | | ||
6952 | STATUS_BYTE(qdonep->d3.scsi_stat); | ||
6953 | break; | ||
6954 | |||
6955 | default: | ||
6956 | ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n", qdonep->d3.done_stat); | ||
6957 | scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) | | ||
6958 | STATUS_BYTE(qdonep->d3.scsi_stat); | ||
6959 | break; | ||
6960 | } | ||
6961 | |||
6962 | /* | ||
6963 | * If the 'init_tidmask' bit isn't already set for the target and the | ||
6964 | * current request finished normally, then set the bit for the target | ||
6965 | * to indicate that a device is present. | ||
6966 | */ | ||
6967 | if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 && | ||
6968 | qdonep->d3.done_stat == QD_NO_ERROR && | ||
6969 | qdonep->d3.host_stat == QHSTA_NO_ERROR) { | ||
6970 | boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id); | ||
6971 | } | ||
6972 | |||
6973 | /* | ||
6974 | * Because interrupts may be enabled by the 'struct scsi_cmnd' done | ||
6975 | * function, add the command to the end of the board's done queue. | ||
6976 | * The done function for the command will be called from | ||
6977 | * advansys_interrupt(). | ||
6978 | */ | ||
6979 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
6980 | |||
6981 | return; | ||
6982 | } | ||
6983 | |||
6984 | /* | ||
6985 | * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR(). | ||
6986 | * | ||
6987 | * Callback function for the Wide SCSI Adv Library. | ||
6988 | */ | ||
6989 | STATIC void | ||
6990 | adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) | ||
6991 | { | ||
6992 | asc_board_t *boardp; | ||
6993 | adv_req_t *reqp; | ||
6994 | adv_sgblk_t *sgblkp; | ||
6995 | struct scsi_cmnd *scp; | ||
6996 | struct Scsi_Host *shp; | ||
6997 | int i; | ||
6998 | ADV_DCNT resid_cnt; | ||
6999 | |||
7000 | |||
7001 | ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n", | ||
7002 | (ulong) adv_dvc_varp, (ulong) scsiqp); | ||
7003 | ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp); | ||
7004 | |||
7005 | /* | ||
7006 | * Get the adv_req_t structure for the command that has been | ||
7007 | * completed. The adv_req_t structure actually contains the | ||
7008 | * completed ADV_SCSI_REQ_Q structure. | ||
7009 | */ | ||
7010 | reqp = (adv_req_t *) ADV_U32_TO_VADDR(scsiqp->srb_ptr); | ||
7011 | ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong) reqp); | ||
7012 | if (reqp == NULL) { | ||
7013 | ASC_PRINT("adv_isr_callback: reqp is NULL\n"); | ||
7014 | return; | ||
7015 | } | ||
7016 | |||
7017 | /* | ||
7018 | * Get the struct scsi_cmnd structure and Scsi_Host structure for the | ||
7019 | * command that has been completed. | ||
7020 | * | ||
7021 | * Note: The adv_req_t request structure and adv_sgblk_t structure, | ||
7022 | * if any, are dropped, because a board structure pointer can not be | ||
7023 | * determined. | ||
7024 | */ | ||
7025 | scp = reqp->cmndp; | ||
7026 | ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong) scp); | ||
7027 | if (scp == NULL) { | ||
7028 | ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n"); | ||
7029 | return; | ||
7030 | } | ||
7031 | ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len); | ||
7032 | |||
7033 | /* | ||
7034 | * If the request's host pointer is not valid, display a message | ||
7035 | * and return. | ||
7036 | */ | ||
7037 | shp = scp->device->host; | ||
7038 | for (i = 0; i < asc_board_count; i++) { | ||
7039 | if (asc_host[i] == shp) { | ||
7040 | break; | ||
7041 | } | ||
7042 | } | ||
7043 | /* | ||
7044 | * Note: If the host structure is not found, the adv_req_t request | ||
7045 | * structure and adv_sgblk_t structure, if any, is dropped. | ||
7046 | */ | ||
7047 | if (i == asc_board_count) { | ||
7048 | ASC_PRINT2( | ||
7049 | "adv_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n", | ||
7050 | (ulong) scp, (ulong) shp); | ||
7051 | return; | ||
7052 | } | ||
7053 | |||
7054 | ASC_STATS(shp, callback); | ||
7055 | ASC_DBG1(1, "adv_isr_callback: shp 0x%lx\n", (ulong) shp); | ||
7056 | |||
7057 | /* | ||
7058 | * If the request isn't found on the active queue, it may have been | ||
7059 | * removed to handle a reset request. Display a message and return. | ||
7060 | * | ||
7061 | * Note: Because the structure may still be in use don't attempt | ||
7062 | * to free the adv_req_t and adv_sgblk_t, if any, structures. | ||
7063 | */ | ||
7064 | boardp = ASC_BOARDP(shp); | ||
7065 | ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var); | ||
7066 | if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) { | ||
7067 | ASC_PRINT2( | ||
7068 | "adv_isr_callback: board %d: scp 0x%lx not on active queue\n", | ||
7069 | boardp->id, (ulong) scp); | ||
7070 | return; | ||
7071 | } | ||
7072 | |||
7073 | /* | ||
7074 | * 'done_status' contains the command's ending status. | ||
7075 | */ | ||
7076 | switch (scsiqp->done_status) { | ||
7077 | case QD_NO_ERROR: | ||
7078 | ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n"); | ||
7079 | scp->result = 0; | ||
7080 | |||
7081 | /* | ||
7082 | * Check for an underrun condition. | ||
7083 | * | ||
7084 | * If there was no error and an underrun condition, then | ||
7085 | * then return the number of underrun bytes. | ||
7086 | */ | ||
7087 | resid_cnt = le32_to_cpu(scsiqp->data_cnt); | ||
7088 | if (scp->request_bufflen != 0 && resid_cnt != 0 && | ||
7089 | resid_cnt <= scp->request_bufflen) { | ||
7090 | ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n", | ||
7091 | (ulong) resid_cnt); | ||
7092 | scp->resid = resid_cnt; | ||
7093 | } | ||
7094 | break; | ||
7095 | |||
7096 | case QD_WITH_ERROR: | ||
7097 | ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n"); | ||
7098 | switch (scsiqp->host_status) { | ||
7099 | case QHSTA_NO_ERROR: | ||
7100 | if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) { | ||
7101 | ASC_DBG(2, "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n"); | ||
7102 | ASC_DBG_PRT_SENSE(2, scp->sense_buffer, | ||
7103 | sizeof(scp->sense_buffer)); | ||
7104 | /* | ||
7105 | * Note: The 'status_byte()' macro used by target drivers | ||
7106 | * defined in scsi.h shifts the status byte returned by | ||
7107 | * host drivers right by 1 bit. This is why target drivers | ||
7108 | * also use right shifted status byte definitions. For | ||
7109 | * instance target drivers use CHECK_CONDITION, defined to | ||
7110 | * 0x1, instead of the SCSI defined check condition value | ||
7111 | * of 0x2. Host drivers are supposed to return the status | ||
7112 | * byte as it is defined by SCSI. | ||
7113 | */ | ||
7114 | scp->result = DRIVER_BYTE(DRIVER_SENSE) | | ||
7115 | STATUS_BYTE(scsiqp->scsi_status); | ||
7116 | } else { | ||
7117 | scp->result = STATUS_BYTE(scsiqp->scsi_status); | ||
7118 | } | ||
7119 | break; | ||
7120 | |||
7121 | default: | ||
7122 | /* Some other QHSTA error occurred. */ | ||
7123 | ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n", | ||
7124 | scsiqp->host_status); | ||
7125 | scp->result = HOST_BYTE(DID_BAD_TARGET); | ||
7126 | break; | ||
7127 | } | ||
7128 | break; | ||
7129 | |||
7130 | case QD_ABORTED_BY_HOST: | ||
7131 | ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n"); | ||
7132 | scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status); | ||
7133 | break; | ||
7134 | |||
7135 | default: | ||
7136 | ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n", scsiqp->done_status); | ||
7137 | scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status); | ||
7138 | break; | ||
7139 | } | ||
7140 | |||
7141 | /* | ||
7142 | * If the 'init_tidmask' bit isn't already set for the target and the | ||
7143 | * current request finished normally, then set the bit for the target | ||
7144 | * to indicate that a device is present. | ||
7145 | */ | ||
7146 | if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 && | ||
7147 | scsiqp->done_status == QD_NO_ERROR && | ||
7148 | scsiqp->host_status == QHSTA_NO_ERROR) { | ||
7149 | boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id); | ||
7150 | } | ||
7151 | |||
7152 | /* | ||
7153 | * Because interrupts may be enabled by the 'struct scsi_cmnd' done | ||
7154 | * function, add the command to the end of the board's done queue. | ||
7155 | * The done function for the command will be called from | ||
7156 | * advansys_interrupt(). | ||
7157 | */ | ||
7158 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
7159 | |||
7160 | /* | ||
7161 | * Free all 'adv_sgblk_t' structures allocated for the request. | ||
7162 | */ | ||
7163 | while ((sgblkp = reqp->sgblkp) != NULL) | ||
7164 | { | ||
7165 | /* Remove 'sgblkp' from the request list. */ | ||
7166 | reqp->sgblkp = sgblkp->next_sgblkp; | ||
7167 | |||
7168 | /* Add 'sgblkp' to the board free list. */ | ||
7169 | sgblkp->next_sgblkp = boardp->adv_sgblkp; | ||
7170 | boardp->adv_sgblkp = sgblkp; | ||
7171 | } | ||
7172 | |||
7173 | /* | ||
7174 | * Free the adv_req_t structure used with the command by adding | ||
7175 | * it back to the board free list. | ||
7176 | */ | ||
7177 | reqp->next_reqp = boardp->adv_reqp; | ||
7178 | boardp->adv_reqp = reqp; | ||
7179 | |||
7180 | ASC_DBG(1, "adv_isr_callback: done\n"); | ||
7181 | |||
7182 | return; | ||
7183 | } | ||
7184 | |||
7185 | /* | ||
7186 | * adv_async_callback() - Adv Library asynchronous event callback function. | ||
7187 | */ | ||
7188 | STATIC void | ||
7189 | adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code) | ||
7190 | { | ||
7191 | switch (code) | ||
7192 | { | ||
7193 | case ADV_ASYNC_SCSI_BUS_RESET_DET: | ||
7194 | /* | ||
7195 | * The firmware detected a SCSI Bus reset. | ||
7196 | */ | ||
7197 | ASC_DBG(0, "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n"); | ||
7198 | break; | ||
7199 | |||
7200 | case ADV_ASYNC_RDMA_FAILURE: | ||
7201 | /* | ||
7202 | * Handle RDMA failure by resetting the SCSI Bus and | ||
7203 | * possibly the chip if it is unresponsive. Log the error | ||
7204 | * with a unique code. | ||
7205 | */ | ||
7206 | ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n"); | ||
7207 | AdvResetChipAndSB(adv_dvc_varp); | ||
7208 | break; | ||
7209 | |||
7210 | case ADV_HOST_SCSI_BUS_RESET: | ||
7211 | /* | ||
7212 | * Host generated SCSI bus reset occurred. | ||
7213 | */ | ||
7214 | ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n"); | ||
7215 | break; | ||
7216 | |||
7217 | default: | ||
7218 | ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code); | ||
7219 | break; | ||
7220 | } | ||
7221 | } | ||
7222 | |||
7223 | /* | ||
7224 | * Add a 'REQP' to the end of specified queue. Set 'tidmask' | ||
7225 | * to indicate a command is queued for the device. | ||
7226 | * | ||
7227 | * 'flag' may be either ASC_FRONT or ASC_BACK. | ||
7228 | * | ||
7229 | * 'REQPNEXT(reqp)' returns reqp's next pointer. | ||
7230 | */ | ||
7231 | STATIC void | ||
7232 | asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag) | ||
7233 | { | ||
7234 | int tid; | ||
7235 | |||
7236 | ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n", | ||
7237 | (ulong) ascq, (ulong) reqp, flag); | ||
7238 | ASC_ASSERT(reqp != NULL); | ||
7239 | ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK); | ||
7240 | tid = REQPTID(reqp); | ||
7241 | ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID); | ||
7242 | if (flag == ASC_FRONT) { | ||
7243 | reqp->host_scribble = (unsigned char *)ascq->q_first[tid]; | ||
7244 | ascq->q_first[tid] = reqp; | ||
7245 | /* If the queue was empty, set the last pointer. */ | ||
7246 | if (ascq->q_last[tid] == NULL) { | ||
7247 | ascq->q_last[tid] = reqp; | ||
7248 | } | ||
7249 | } else { /* ASC_BACK */ | ||
7250 | if (ascq->q_last[tid] != NULL) { | ||
7251 | ascq->q_last[tid]->host_scribble = (unsigned char *)reqp; | ||
7252 | } | ||
7253 | ascq->q_last[tid] = reqp; | ||
7254 | reqp->host_scribble = NULL; | ||
7255 | /* If the queue was empty, set the first pointer. */ | ||
7256 | if (ascq->q_first[tid] == NULL) { | ||
7257 | ascq->q_first[tid] = reqp; | ||
7258 | } | ||
7259 | } | ||
7260 | /* The queue has at least one entry, set its bit. */ | ||
7261 | ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid); | ||
7262 | #ifdef ADVANSYS_STATS | ||
7263 | /* Maintain request queue statistics. */ | ||
7264 | ascq->q_tot_cnt[tid]++; | ||
7265 | ascq->q_cur_cnt[tid]++; | ||
7266 | if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) { | ||
7267 | ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid]; | ||
7268 | ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n", | ||
7269 | tid, ascq->q_max_cnt[tid]); | ||
7270 | } | ||
7271 | REQPTIME(reqp) = REQTIMESTAMP(); | ||
7272 | #endif /* ADVANSYS_STATS */ | ||
7273 | ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong) reqp); | ||
7274 | return; | ||
7275 | } | ||
7276 | |||
7277 | /* | ||
7278 | * Return first queued 'REQP' on the specified queue for | ||
7279 | * the specified target device. Clear the 'tidmask' bit for | ||
7280 | * the device if no more commands are left queued for it. | ||
7281 | * | ||
7282 | * 'REQPNEXT(reqp)' returns reqp's next pointer. | ||
7283 | */ | ||
7284 | STATIC REQP | ||
7285 | asc_dequeue(asc_queue_t *ascq, int tid) | ||
7286 | { | ||
7287 | REQP reqp; | ||
7288 | |||
7289 | ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong) ascq, tid); | ||
7290 | ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID); | ||
7291 | if ((reqp = ascq->q_first[tid]) != NULL) { | ||
7292 | ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)); | ||
7293 | ascq->q_first[tid] = REQPNEXT(reqp); | ||
7294 | /* If the queue is empty, clear its bit and the last pointer. */ | ||
7295 | if (ascq->q_first[tid] == NULL) { | ||
7296 | ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid); | ||
7297 | ASC_ASSERT(ascq->q_last[tid] == reqp); | ||
7298 | ascq->q_last[tid] = NULL; | ||
7299 | } | ||
7300 | #ifdef ADVANSYS_STATS | ||
7301 | /* Maintain request queue statistics. */ | ||
7302 | ascq->q_cur_cnt[tid]--; | ||
7303 | ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0); | ||
7304 | REQTIMESTAT("asc_dequeue", ascq, reqp, tid); | ||
7305 | #endif /* ADVANSYS_STATS */ | ||
7306 | } | ||
7307 | ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong) reqp); | ||
7308 | return reqp; | ||
7309 | } | ||
7310 | |||
7311 | /* | ||
7312 | * Return a pointer to a singly linked list of all the requests queued | ||
7313 | * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'. | ||
7314 | * | ||
7315 | * If 'lastpp' is not NULL, '*lastpp' will be set to point to the | ||
7316 | * the last request returned in the singly linked list. | ||
7317 | * | ||
7318 | * 'tid' should either be a valid target id or if it is ASC_TID_ALL, | ||
7319 | * then all queued requests are concatenated into one list and | ||
7320 | * returned. | ||
7321 | * | ||
7322 | * Note: If 'lastpp' is used to append a new list to the end of | ||
7323 | * an old list, only change the old list last pointer if '*lastpp' | ||
7324 | * (or the function return value) is not NULL, i.e. use a temporary | ||
7325 | * variable for 'lastpp' and check its value after the function return | ||
7326 | * before assigning it to the list last pointer. | ||
7327 | * | ||
7328 | * Unfortunately collecting queuing time statistics adds overhead to | ||
7329 | * the function that isn't inherent to the function's algorithm. | ||
7330 | */ | ||
7331 | STATIC REQP | ||
7332 | asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid) | ||
7333 | { | ||
7334 | REQP firstp, lastp; | ||
7335 | int i; | ||
7336 | |||
7337 | ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong) ascq, tid); | ||
7338 | ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID)); | ||
7339 | |||
7340 | /* | ||
7341 | * If 'tid' is not ASC_TID_ALL, return requests only for | ||
7342 | * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all | ||
7343 | * requests for all tids. | ||
7344 | */ | ||
7345 | if (tid != ASC_TID_ALL) { | ||
7346 | /* Return all requests for the specified 'tid'. */ | ||
7347 | if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) { | ||
7348 | /* List is empty; Set first and last return pointers to NULL. */ | ||
7349 | firstp = lastp = NULL; | ||
7350 | } else { | ||
7351 | firstp = ascq->q_first[tid]; | ||
7352 | lastp = ascq->q_last[tid]; | ||
7353 | ascq->q_first[tid] = ascq->q_last[tid] = NULL; | ||
7354 | ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid); | ||
7355 | #ifdef ADVANSYS_STATS | ||
7356 | { | ||
7357 | REQP reqp; | ||
7358 | ascq->q_cur_cnt[tid] = 0; | ||
7359 | for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) { | ||
7360 | REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid); | ||
7361 | } | ||
7362 | } | ||
7363 | #endif /* ADVANSYS_STATS */ | ||
7364 | } | ||
7365 | } else { | ||
7366 | /* Return all requests for all tids. */ | ||
7367 | firstp = lastp = NULL; | ||
7368 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
7369 | if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) { | ||
7370 | if (firstp == NULL) { | ||
7371 | firstp = ascq->q_first[i]; | ||
7372 | lastp = ascq->q_last[i]; | ||
7373 | } else { | ||
7374 | ASC_ASSERT(lastp != NULL); | ||
7375 | lastp->host_scribble = (unsigned char *)ascq->q_first[i]; | ||
7376 | lastp = ascq->q_last[i]; | ||
7377 | } | ||
7378 | ascq->q_first[i] = ascq->q_last[i] = NULL; | ||
7379 | ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i); | ||
7380 | #ifdef ADVANSYS_STATS | ||
7381 | ascq->q_cur_cnt[i] = 0; | ||
7382 | #endif /* ADVANSYS_STATS */ | ||
7383 | } | ||
7384 | } | ||
7385 | #ifdef ADVANSYS_STATS | ||
7386 | { | ||
7387 | REQP reqp; | ||
7388 | for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) { | ||
7389 | REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->device->id); | ||
7390 | } | ||
7391 | } | ||
7392 | #endif /* ADVANSYS_STATS */ | ||
7393 | } | ||
7394 | if (lastpp) { | ||
7395 | *lastpp = lastp; | ||
7396 | } | ||
7397 | ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong) firstp); | ||
7398 | return firstp; | ||
7399 | } | ||
7400 | |||
7401 | /* | ||
7402 | * Remove the specified 'REQP' from the specified queue for | ||
7403 | * the specified target device. Clear the 'tidmask' bit for the | ||
7404 | * device if no more commands are left queued for it. | ||
7405 | * | ||
7406 | * 'REQPNEXT(reqp)' returns reqp's the next pointer. | ||
7407 | * | ||
7408 | * Return ASC_TRUE if the command was found and removed, | ||
7409 | * otherwise return ASC_FALSE. | ||
7410 | */ | ||
7411 | STATIC int | ||
7412 | asc_rmqueue(asc_queue_t *ascq, REQP reqp) | ||
7413 | { | ||
7414 | REQP currp, prevp; | ||
7415 | int tid; | ||
7416 | int ret = ASC_FALSE; | ||
7417 | |||
7418 | ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n", | ||
7419 | (ulong) ascq, (ulong) reqp); | ||
7420 | ASC_ASSERT(reqp != NULL); | ||
7421 | |||
7422 | tid = REQPTID(reqp); | ||
7423 | ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID); | ||
7424 | |||
7425 | /* | ||
7426 | * Handle the common case of 'reqp' being the first | ||
7427 | * entry on the queue. | ||
7428 | */ | ||
7429 | if (reqp == ascq->q_first[tid]) { | ||
7430 | ret = ASC_TRUE; | ||
7431 | ascq->q_first[tid] = REQPNEXT(reqp); | ||
7432 | /* If the queue is now empty, clear its bit and the last pointer. */ | ||
7433 | if (ascq->q_first[tid] == NULL) { | ||
7434 | ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid); | ||
7435 | ASC_ASSERT(ascq->q_last[tid] == reqp); | ||
7436 | ascq->q_last[tid] = NULL; | ||
7437 | } | ||
7438 | } else if (ascq->q_first[tid] != NULL) { | ||
7439 | ASC_ASSERT(ascq->q_last[tid] != NULL); | ||
7440 | /* | ||
7441 | * Because the case of 'reqp' being the first entry has been | ||
7442 | * handled above and it is known the queue is not empty, if | ||
7443 | * 'reqp' is found on the queue it is guaranteed the queue will | ||
7444 | * not become empty and that 'q_first[tid]' will not be changed. | ||
7445 | * | ||
7446 | * Set 'prevp' to the first entry, 'currp' to the second entry, | ||
7447 | * and search for 'reqp'. | ||
7448 | */ | ||
7449 | for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp); | ||
7450 | currp; prevp = currp, currp = REQPNEXT(currp)) { | ||
7451 | if (currp == reqp) { | ||
7452 | ret = ASC_TRUE; | ||
7453 | prevp->host_scribble = (unsigned char *)REQPNEXT(currp); | ||
7454 | reqp->host_scribble = NULL; | ||
7455 | if (ascq->q_last[tid] == reqp) { | ||
7456 | ascq->q_last[tid] = prevp; | ||
7457 | } | ||
7458 | break; | ||
7459 | } | ||
7460 | } | ||
7461 | } | ||
7462 | #ifdef ADVANSYS_STATS | ||
7463 | /* Maintain request queue statistics. */ | ||
7464 | if (ret == ASC_TRUE) { | ||
7465 | ascq->q_cur_cnt[tid]--; | ||
7466 | REQTIMESTAT("asc_rmqueue", ascq, reqp, tid); | ||
7467 | } | ||
7468 | ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0); | ||
7469 | #endif /* ADVANSYS_STATS */ | ||
7470 | ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong) reqp, ret); | ||
7471 | return ret; | ||
7472 | } | ||
7473 | |||
7474 | /* | ||
7475 | * Execute as many queued requests as possible for the specified queue. | ||
7476 | * | ||
7477 | * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd. | ||
7478 | */ | ||
7479 | STATIC void | ||
7480 | asc_execute_queue(asc_queue_t *ascq) | ||
7481 | { | ||
7482 | ADV_SCSI_BIT_ID_TYPE scan_tidmask; | ||
7483 | REQP reqp; | ||
7484 | int i; | ||
7485 | |||
7486 | ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong) ascq); | ||
7487 | /* | ||
7488 | * Execute queued commands for devices attached to | ||
7489 | * the current board in round-robin fashion. | ||
7490 | */ | ||
7491 | scan_tidmask = ascq->q_tidmask; | ||
7492 | do { | ||
7493 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
7494 | if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) { | ||
7495 | if ((reqp = asc_dequeue(ascq, i)) == NULL) { | ||
7496 | scan_tidmask &= ~ADV_TID_TO_TIDMASK(i); | ||
7497 | } else if (asc_execute_scsi_cmnd((struct scsi_cmnd *) reqp) | ||
7498 | == ASC_BUSY) { | ||
7499 | scan_tidmask &= ~ADV_TID_TO_TIDMASK(i); | ||
7500 | /* | ||
7501 | * The request returned ASC_BUSY. Enqueue at the front of | ||
7502 | * target's waiting list to maintain correct ordering. | ||
7503 | */ | ||
7504 | asc_enqueue(ascq, reqp, ASC_FRONT); | ||
7505 | } | ||
7506 | } | ||
7507 | } | ||
7508 | } while (scan_tidmask); | ||
7509 | return; | ||
7510 | } | ||
7511 | |||
7512 | #ifdef CONFIG_PROC_FS | ||
7513 | /* | ||
7514 | * asc_prt_board_devices() | ||
7515 | * | ||
7516 | * Print driver information for devices attached to the board. | ||
7517 | * | ||
7518 | * Note: no single line should be greater than ASC_PRTLINE_SIZE, | ||
7519 | * cf. asc_prt_line(). | ||
7520 | * | ||
7521 | * Return the number of characters copied into 'cp'. No more than | ||
7522 | * 'cplen' characters will be copied to 'cp'. | ||
7523 | */ | ||
7524 | STATIC int | ||
7525 | asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen) | ||
7526 | { | ||
7527 | asc_board_t *boardp; | ||
7528 | int leftlen; | ||
7529 | int totlen; | ||
7530 | int len; | ||
7531 | int chip_scsi_id; | ||
7532 | int i; | ||
7533 | |||
7534 | boardp = ASC_BOARDP(shp); | ||
7535 | leftlen = cplen; | ||
7536 | totlen = len = 0; | ||
7537 | |||
7538 | len = asc_prt_line(cp, leftlen, | ||
7539 | "\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no); | ||
7540 | ASC_PRT_NEXT(); | ||
7541 | |||
7542 | if (ASC_NARROW_BOARD(boardp)) { | ||
7543 | chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; | ||
7544 | } else { | ||
7545 | chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id; | ||
7546 | } | ||
7547 | |||
7548 | len = asc_prt_line(cp, leftlen, "Target IDs Detected:"); | ||
7549 | ASC_PRT_NEXT(); | ||
7550 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
7551 | if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) { | ||
7552 | len = asc_prt_line(cp, leftlen, " %X,", i); | ||
7553 | ASC_PRT_NEXT(); | ||
7554 | } | ||
7555 | } | ||
7556 | len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id); | ||
7557 | ASC_PRT_NEXT(); | ||
7558 | |||
7559 | return totlen; | ||
7560 | } | ||
7561 | |||
7562 | /* | ||
7563 | * Display Wide Board BIOS Information. | ||
7564 | */ | ||
7565 | STATIC int | ||
7566 | asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen) | ||
7567 | { | ||
7568 | asc_board_t *boardp; | ||
7569 | int leftlen; | ||
7570 | int totlen; | ||
7571 | int len; | ||
7572 | ushort major, minor, letter; | ||
7573 | |||
7574 | boardp = ASC_BOARDP(shp); | ||
7575 | leftlen = cplen; | ||
7576 | totlen = len = 0; | ||
7577 | |||
7578 | len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: "); | ||
7579 | ASC_PRT_NEXT(); | ||
7580 | |||
7581 | /* | ||
7582 | * If the BIOS saved a valid signature, then fill in | ||
7583 | * the BIOS code segment base address. | ||
7584 | */ | ||
7585 | if (boardp->bios_signature != 0x55AA) { | ||
7586 | len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n"); | ||
7587 | ASC_PRT_NEXT(); | ||
7588 | len = asc_prt_line(cp, leftlen, | ||
7589 | "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n"); | ||
7590 | ASC_PRT_NEXT(); | ||
7591 | len = asc_prt_line(cp, leftlen, | ||
7592 | "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n"); | ||
7593 | ASC_PRT_NEXT(); | ||
7594 | } else { | ||
7595 | major = (boardp->bios_version >> 12) & 0xF; | ||
7596 | minor = (boardp->bios_version >> 8) & 0xF; | ||
7597 | letter = (boardp->bios_version & 0xFF); | ||
7598 | |||
7599 | len = asc_prt_line(cp, leftlen, "%d.%d%c\n", | ||
7600 | major, minor, letter >= 26 ? '?' : letter + 'A'); | ||
7601 | ASC_PRT_NEXT(); | ||
7602 | |||
7603 | /* | ||
7604 | * Current available ROM BIOS release is 3.1I for UW | ||
7605 | * and 3.2I for U2W. This code doesn't differentiate | ||
7606 | * UW and U2W boards. | ||
7607 | */ | ||
7608 | if (major < 3 || (major <= 3 && minor < 1) || | ||
7609 | (major <= 3 && minor <= 1 && letter < ('I'- 'A'))) { | ||
7610 | len = asc_prt_line(cp, leftlen, | ||
7611 | "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n"); | ||
7612 | ASC_PRT_NEXT(); | ||
7613 | len = asc_prt_line(cp, leftlen, | ||
7614 | "ftp://ftp.connectcom.net/pub\n"); | ||
7615 | ASC_PRT_NEXT(); | ||
7616 | } | ||
7617 | } | ||
7618 | |||
7619 | return totlen; | ||
7620 | } | ||
7621 | |||
7622 | /* | ||
7623 | * Add serial number to information bar if signature AAh | ||
7624 | * is found in at bit 15-9 (7 bits) of word 1. | ||
7625 | * | ||
7626 | * Serial Number consists fo 12 alpha-numeric digits. | ||
7627 | * | ||
7628 | * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits) | ||
7629 | * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits) | ||
7630 | * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits) | ||
7631 | * 5 - Product revision (A-J) Word0: " " | ||
7632 | * | ||
7633 | * Signature Word1: 15-9 (7 bits) | ||
7634 | * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit) | ||
7635 | * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits) | ||
7636 | * | ||
7637 | * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits) | ||
7638 | * | ||
7639 | * Note 1: Only production cards will have a serial number. | ||
7640 | * | ||
7641 | * Note 2: Signature is most significant 7 bits (0xFE). | ||
7642 | * | ||
7643 | * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE. | ||
7644 | */ | ||
7645 | STATIC int | ||
7646 | asc_get_eeprom_string(ushort *serialnum, uchar *cp) | ||
7647 | { | ||
7648 | ushort w, num; | ||
7649 | |||
7650 | if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) { | ||
7651 | return ASC_FALSE; | ||
7652 | } else { | ||
7653 | /* | ||
7654 | * First word - 6 digits. | ||
7655 | */ | ||
7656 | w = serialnum[0]; | ||
7657 | |||
7658 | /* Product type - 1st digit. */ | ||
7659 | if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') { | ||
7660 | /* Product type is P=Prototype */ | ||
7661 | *cp += 0x8; | ||
7662 | } | ||
7663 | cp++; | ||
7664 | |||
7665 | /* Manufacturing location - 2nd digit. */ | ||
7666 | *cp++ = 'A' + ((w & 0x1C00) >> 10); | ||
7667 | |||
7668 | /* Product ID - 3rd, 4th digits. */ | ||
7669 | num = w & 0x3FF; | ||
7670 | *cp++ = '0' + (num / 100); | ||
7671 | num %= 100; | ||
7672 | *cp++ = '0' + (num / 10); | ||
7673 | |||
7674 | /* Product revision - 5th digit. */ | ||
7675 | *cp++ = 'A' + (num % 10); | ||
7676 | |||
7677 | /* | ||
7678 | * Second word | ||
7679 | */ | ||
7680 | w = serialnum[1]; | ||
7681 | |||
7682 | /* | ||
7683 | * Year - 6th digit. | ||
7684 | * | ||
7685 | * If bit 15 of third word is set, then the | ||
7686 | * last digit of the year is greater than 7. | ||
7687 | */ | ||
7688 | if (serialnum[2] & 0x8000) { | ||
7689 | *cp++ = '8' + ((w & 0x1C0) >> 6); | ||
7690 | } else { | ||
7691 | *cp++ = '0' + ((w & 0x1C0) >> 6); | ||
7692 | } | ||
7693 | |||
7694 | /* Week of year - 7th, 8th digits. */ | ||
7695 | num = w & 0x003F; | ||
7696 | *cp++ = '0' + num / 10; | ||
7697 | num %= 10; | ||
7698 | *cp++ = '0' + num; | ||
7699 | |||
7700 | /* | ||
7701 | * Third word | ||
7702 | */ | ||
7703 | w = serialnum[2] & 0x7FFF; | ||
7704 | |||
7705 | /* Serial number - 9th digit. */ | ||
7706 | *cp++ = 'A' + (w / 1000); | ||
7707 | |||
7708 | /* 10th, 11th, 12th digits. */ | ||
7709 | num = w % 1000; | ||
7710 | *cp++ = '0' + num / 100; | ||
7711 | num %= 100; | ||
7712 | *cp++ = '0' + num / 10; | ||
7713 | num %= 10; | ||
7714 | *cp++ = '0' + num; | ||
7715 | |||
7716 | *cp = '\0'; /* Null Terminate the string. */ | ||
7717 | return ASC_TRUE; | ||
7718 | } | ||
7719 | } | ||
7720 | |||
7721 | /* | ||
7722 | * asc_prt_asc_board_eeprom() | ||
7723 | * | ||
7724 | * Print board EEPROM configuration. | ||
7725 | * | ||
7726 | * Note: no single line should be greater than ASC_PRTLINE_SIZE, | ||
7727 | * cf. asc_prt_line(). | ||
7728 | * | ||
7729 | * Return the number of characters copied into 'cp'. No more than | ||
7730 | * 'cplen' characters will be copied to 'cp'. | ||
7731 | */ | ||
7732 | STATIC int | ||
7733 | asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen) | ||
7734 | { | ||
7735 | asc_board_t *boardp; | ||
7736 | ASC_DVC_VAR *asc_dvc_varp; | ||
7737 | int leftlen; | ||
7738 | int totlen; | ||
7739 | int len; | ||
7740 | ASCEEP_CONFIG *ep; | ||
7741 | int i; | ||
7742 | #ifdef CONFIG_ISA | ||
7743 | int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 }; | ||
7744 | #endif /* CONFIG_ISA */ | ||
7745 | uchar serialstr[13]; | ||
7746 | |||
7747 | boardp = ASC_BOARDP(shp); | ||
7748 | asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; | ||
7749 | ep = &boardp->eep_config.asc_eep; | ||
7750 | |||
7751 | leftlen = cplen; | ||
7752 | totlen = len = 0; | ||
7753 | |||
7754 | len = asc_prt_line(cp, leftlen, | ||
7755 | "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no); | ||
7756 | ASC_PRT_NEXT(); | ||
7757 | |||
7758 | if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) == | ||
7759 | ASC_TRUE) { | ||
7760 | len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr); | ||
7761 | ASC_PRT_NEXT(); | ||
7762 | } else { | ||
7763 | if (ep->adapter_info[5] == 0xBB) { | ||
7764 | len = asc_prt_line(cp, leftlen, | ||
7765 | " Default Settings Used for EEPROM-less Adapter.\n"); | ||
7766 | ASC_PRT_NEXT(); | ||
7767 | } else { | ||
7768 | len = asc_prt_line(cp, leftlen, | ||
7769 | " Serial Number Signature Not Present.\n"); | ||
7770 | ASC_PRT_NEXT(); | ||
7771 | } | ||
7772 | } | ||
7773 | |||
7774 | len = asc_prt_line(cp, leftlen, | ||
7775 | " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", | ||
7776 | ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng, ep->max_tag_qng); | ||
7777 | ASC_PRT_NEXT(); | ||
7778 | |||
7779 | len = asc_prt_line(cp, leftlen, | ||
7780 | " cntl 0x%x, no_scam 0x%x\n", | ||
7781 | ep->cntl, ep->no_scam); | ||
7782 | ASC_PRT_NEXT(); | ||
7783 | |||
7784 | len = asc_prt_line(cp, leftlen, | ||
7785 | " Target ID: "); | ||
7786 | ASC_PRT_NEXT(); | ||
7787 | for (i = 0; i <= ASC_MAX_TID; i++) { | ||
7788 | len = asc_prt_line(cp, leftlen, " %d", i); | ||
7789 | ASC_PRT_NEXT(); | ||
7790 | } | ||
7791 | len = asc_prt_line(cp, leftlen, "\n"); | ||
7792 | ASC_PRT_NEXT(); | ||
7793 | |||
7794 | len = asc_prt_line(cp, leftlen, | ||
7795 | " Disconnects: "); | ||
7796 | ASC_PRT_NEXT(); | ||
7797 | for (i = 0; i <= ASC_MAX_TID; i++) { | ||
7798 | len = asc_prt_line(cp, leftlen, " %c", | ||
7799 | (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); | ||
7800 | ASC_PRT_NEXT(); | ||
7801 | } | ||
7802 | len = asc_prt_line(cp, leftlen, "\n"); | ||
7803 | ASC_PRT_NEXT(); | ||
7804 | |||
7805 | len = asc_prt_line(cp, leftlen, | ||
7806 | " Command Queuing: "); | ||
7807 | ASC_PRT_NEXT(); | ||
7808 | for (i = 0; i <= ASC_MAX_TID; i++) { | ||
7809 | len = asc_prt_line(cp, leftlen, " %c", | ||
7810 | (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); | ||
7811 | ASC_PRT_NEXT(); | ||
7812 | } | ||
7813 | len = asc_prt_line(cp, leftlen, "\n"); | ||
7814 | ASC_PRT_NEXT(); | ||
7815 | |||
7816 | len = asc_prt_line(cp, leftlen, | ||
7817 | " Start Motor: "); | ||
7818 | ASC_PRT_NEXT(); | ||
7819 | for (i = 0; i <= ASC_MAX_TID; i++) { | ||
7820 | len = asc_prt_line(cp, leftlen, " %c", | ||
7821 | (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); | ||
7822 | ASC_PRT_NEXT(); | ||
7823 | } | ||
7824 | len = asc_prt_line(cp, leftlen, "\n"); | ||
7825 | ASC_PRT_NEXT(); | ||
7826 | |||
7827 | len = asc_prt_line(cp, leftlen, | ||
7828 | " Synchronous Transfer:"); | ||
7829 | ASC_PRT_NEXT(); | ||
7830 | for (i = 0; i <= ASC_MAX_TID; i++) { | ||
7831 | len = asc_prt_line(cp, leftlen, " %c", | ||
7832 | (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); | ||
7833 | ASC_PRT_NEXT(); | ||
7834 | } | ||
7835 | len = asc_prt_line(cp, leftlen, "\n"); | ||
7836 | ASC_PRT_NEXT(); | ||
7837 | |||
7838 | #ifdef CONFIG_ISA | ||
7839 | if (asc_dvc_varp->bus_type & ASC_IS_ISA) { | ||
7840 | len = asc_prt_line(cp, leftlen, | ||
7841 | " Host ISA DMA speed: %d MB/S\n", | ||
7842 | isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]); | ||
7843 | ASC_PRT_NEXT(); | ||
7844 | } | ||
7845 | #endif /* CONFIG_ISA */ | ||
7846 | |||
7847 | return totlen; | ||
7848 | } | ||
7849 | |||
7850 | /* | ||
7851 | * asc_prt_adv_board_eeprom() | ||
7852 | * | ||
7853 | * Print board EEPROM configuration. | ||
7854 | * | ||
7855 | * Note: no single line should be greater than ASC_PRTLINE_SIZE, | ||
7856 | * cf. asc_prt_line(). | ||
7857 | * | ||
7858 | * Return the number of characters copied into 'cp'. No more than | ||
7859 | * 'cplen' characters will be copied to 'cp'. | ||
7860 | */ | ||
7861 | STATIC int | ||
7862 | asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen) | ||
7863 | { | ||
7864 | asc_board_t *boardp; | ||
7865 | ADV_DVC_VAR *adv_dvc_varp; | ||
7866 | int leftlen; | ||
7867 | int totlen; | ||
7868 | int len; | ||
7869 | int i; | ||
7870 | char *termstr; | ||
7871 | uchar serialstr[13]; | ||
7872 | ADVEEP_3550_CONFIG *ep_3550 = NULL; | ||
7873 | ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL; | ||
7874 | ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL; | ||
7875 | ushort word; | ||
7876 | ushort *wordp; | ||
7877 | ushort sdtr_speed = 0; | ||
7878 | |||
7879 | boardp = ASC_BOARDP(shp); | ||
7880 | adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; | ||
7881 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) | ||
7882 | { | ||
7883 | ep_3550 = &boardp->eep_config.adv_3550_eep; | ||
7884 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) | ||
7885 | { | ||
7886 | ep_38C0800 = &boardp->eep_config.adv_38C0800_eep; | ||
7887 | } else | ||
7888 | { | ||
7889 | ep_38C1600 = &boardp->eep_config.adv_38C1600_eep; | ||
7890 | } | ||
7891 | |||
7892 | leftlen = cplen; | ||
7893 | totlen = len = 0; | ||
7894 | |||
7895 | len = asc_prt_line(cp, leftlen, | ||
7896 | "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no); | ||
7897 | ASC_PRT_NEXT(); | ||
7898 | |||
7899 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) | ||
7900 | { | ||
7901 | wordp = &ep_3550->serial_number_word1; | ||
7902 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) | ||
7903 | { | ||
7904 | wordp = &ep_38C0800->serial_number_word1; | ||
7905 | } else | ||
7906 | { | ||
7907 | wordp = &ep_38C1600->serial_number_word1; | ||
7908 | } | ||
7909 | |||
7910 | if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) { | ||
7911 | len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr); | ||
7912 | ASC_PRT_NEXT(); | ||
7913 | } else { | ||
7914 | len = asc_prt_line(cp, leftlen, | ||
7915 | " Serial Number Signature Not Present.\n"); | ||
7916 | ASC_PRT_NEXT(); | ||
7917 | } | ||
7918 | |||
7919 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) | ||
7920 | { | ||
7921 | len = asc_prt_line(cp, leftlen, | ||
7922 | " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", | ||
7923 | ep_3550->adapter_scsi_id, ep_3550->max_host_qng, | ||
7924 | ep_3550->max_dvc_qng); | ||
7925 | ASC_PRT_NEXT(); | ||
7926 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) | ||
7927 | { | ||
7928 | len = asc_prt_line(cp, leftlen, | ||
7929 | " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", | ||
7930 | ep_38C0800->adapter_scsi_id, ep_38C0800->max_host_qng, | ||
7931 | ep_38C0800->max_dvc_qng); | ||
7932 | ASC_PRT_NEXT(); | ||
7933 | } else | ||
7934 | { | ||
7935 | len = asc_prt_line(cp, leftlen, | ||
7936 | " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", | ||
7937 | ep_38C1600->adapter_scsi_id, ep_38C1600->max_host_qng, | ||
7938 | ep_38C1600->max_dvc_qng); | ||
7939 | ASC_PRT_NEXT(); | ||
7940 | } | ||
7941 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) | ||
7942 | { | ||
7943 | word = ep_3550->termination; | ||
7944 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) | ||
7945 | { | ||
7946 | word = ep_38C0800->termination_lvd; | ||
7947 | } else | ||
7948 | { | ||
7949 | word = ep_38C1600->termination_lvd; | ||
7950 | } | ||
7951 | switch (word) { | ||
7952 | case 1: | ||
7953 | termstr = "Low Off/High Off"; | ||
7954 | break; | ||
7955 | case 2: | ||
7956 | termstr = "Low Off/High On"; | ||
7957 | break; | ||
7958 | case 3: | ||
7959 | termstr = "Low On/High On"; | ||
7960 | break; | ||
7961 | default: | ||
7962 | case 0: | ||
7963 | termstr = "Automatic"; | ||
7964 | break; | ||
7965 | } | ||
7966 | |||
7967 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) | ||
7968 | { | ||
7969 | len = asc_prt_line(cp, leftlen, | ||
7970 | " termination: %u (%s), bios_ctrl: 0x%x\n", | ||
7971 | ep_3550->termination, termstr, ep_3550->bios_ctrl); | ||
7972 | ASC_PRT_NEXT(); | ||
7973 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) | ||
7974 | { | ||
7975 | len = asc_prt_line(cp, leftlen, | ||
7976 | " termination: %u (%s), bios_ctrl: 0x%x\n", | ||
7977 | ep_38C0800->termination_lvd, termstr, ep_38C0800->bios_ctrl); | ||
7978 | ASC_PRT_NEXT(); | ||
7979 | } else | ||
7980 | { | ||
7981 | len = asc_prt_line(cp, leftlen, | ||
7982 | " termination: %u (%s), bios_ctrl: 0x%x\n", | ||
7983 | ep_38C1600->termination_lvd, termstr, ep_38C1600->bios_ctrl); | ||
7984 | ASC_PRT_NEXT(); | ||
7985 | } | ||
7986 | |||
7987 | len = asc_prt_line(cp, leftlen, | ||
7988 | " Target ID: "); | ||
7989 | ASC_PRT_NEXT(); | ||
7990 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
7991 | len = asc_prt_line(cp, leftlen, " %X", i); | ||
7992 | ASC_PRT_NEXT(); | ||
7993 | } | ||
7994 | len = asc_prt_line(cp, leftlen, "\n"); | ||
7995 | ASC_PRT_NEXT(); | ||
7996 | |||
7997 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) | ||
7998 | { | ||
7999 | word = ep_3550->disc_enable; | ||
8000 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) | ||
8001 | { | ||
8002 | word = ep_38C0800->disc_enable; | ||
8003 | } else | ||
8004 | { | ||
8005 | word = ep_38C1600->disc_enable; | ||
8006 | } | ||
8007 | len = asc_prt_line(cp, leftlen, | ||
8008 | " Disconnects: "); | ||
8009 | ASC_PRT_NEXT(); | ||
8010 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
8011 | len = asc_prt_line(cp, leftlen, " %c", | ||
8012 | (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); | ||
8013 | ASC_PRT_NEXT(); | ||
8014 | } | ||
8015 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8016 | ASC_PRT_NEXT(); | ||
8017 | |||
8018 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) | ||
8019 | { | ||
8020 | word = ep_3550->tagqng_able; | ||
8021 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) | ||
8022 | { | ||
8023 | word = ep_38C0800->tagqng_able; | ||
8024 | } else | ||
8025 | { | ||
8026 | word = ep_38C1600->tagqng_able; | ||
8027 | } | ||
8028 | len = asc_prt_line(cp, leftlen, | ||
8029 | " Command Queuing: "); | ||
8030 | ASC_PRT_NEXT(); | ||
8031 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
8032 | len = asc_prt_line(cp, leftlen, " %c", | ||
8033 | (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); | ||
8034 | ASC_PRT_NEXT(); | ||
8035 | } | ||
8036 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8037 | ASC_PRT_NEXT(); | ||
8038 | |||
8039 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) | ||
8040 | { | ||
8041 | word = ep_3550->start_motor; | ||
8042 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) | ||
8043 | { | ||
8044 | word = ep_38C0800->start_motor; | ||
8045 | } else | ||
8046 | { | ||
8047 | word = ep_38C1600->start_motor; | ||
8048 | } | ||
8049 | len = asc_prt_line(cp, leftlen, | ||
8050 | " Start Motor: "); | ||
8051 | ASC_PRT_NEXT(); | ||
8052 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
8053 | len = asc_prt_line(cp, leftlen, " %c", | ||
8054 | (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); | ||
8055 | ASC_PRT_NEXT(); | ||
8056 | } | ||
8057 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8058 | ASC_PRT_NEXT(); | ||
8059 | |||
8060 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) | ||
8061 | { | ||
8062 | len = asc_prt_line(cp, leftlen, | ||
8063 | " Synchronous Transfer:"); | ||
8064 | ASC_PRT_NEXT(); | ||
8065 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
8066 | len = asc_prt_line(cp, leftlen, " %c", | ||
8067 | (ep_3550->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); | ||
8068 | ASC_PRT_NEXT(); | ||
8069 | } | ||
8070 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8071 | ASC_PRT_NEXT(); | ||
8072 | } | ||
8073 | |||
8074 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) | ||
8075 | { | ||
8076 | len = asc_prt_line(cp, leftlen, | ||
8077 | " Ultra Transfer: "); | ||
8078 | ASC_PRT_NEXT(); | ||
8079 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
8080 | len = asc_prt_line(cp, leftlen, " %c", | ||
8081 | (ep_3550->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); | ||
8082 | ASC_PRT_NEXT(); | ||
8083 | } | ||
8084 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8085 | ASC_PRT_NEXT(); | ||
8086 | } | ||
8087 | |||
8088 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) | ||
8089 | { | ||
8090 | word = ep_3550->wdtr_able; | ||
8091 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) | ||
8092 | { | ||
8093 | word = ep_38C0800->wdtr_able; | ||
8094 | } else | ||
8095 | { | ||
8096 | word = ep_38C1600->wdtr_able; | ||
8097 | } | ||
8098 | len = asc_prt_line(cp, leftlen, | ||
8099 | " Wide Transfer: "); | ||
8100 | ASC_PRT_NEXT(); | ||
8101 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
8102 | len = asc_prt_line(cp, leftlen, " %c", | ||
8103 | (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); | ||
8104 | ASC_PRT_NEXT(); | ||
8105 | } | ||
8106 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8107 | ASC_PRT_NEXT(); | ||
8108 | |||
8109 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 || | ||
8110 | adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) | ||
8111 | { | ||
8112 | len = asc_prt_line(cp, leftlen, | ||
8113 | " Synchronous Transfer Speed (Mhz):\n "); | ||
8114 | ASC_PRT_NEXT(); | ||
8115 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
8116 | char *speed_str; | ||
8117 | |||
8118 | if (i == 0) | ||
8119 | { | ||
8120 | sdtr_speed = adv_dvc_varp->sdtr_speed1; | ||
8121 | } else if (i == 4) | ||
8122 | { | ||
8123 | sdtr_speed = adv_dvc_varp->sdtr_speed2; | ||
8124 | } else if (i == 8) | ||
8125 | { | ||
8126 | sdtr_speed = adv_dvc_varp->sdtr_speed3; | ||
8127 | } else if (i == 12) | ||
8128 | { | ||
8129 | sdtr_speed = adv_dvc_varp->sdtr_speed4; | ||
8130 | } | ||
8131 | switch (sdtr_speed & ADV_MAX_TID) | ||
8132 | { | ||
8133 | case 0: speed_str = "Off"; break; | ||
8134 | case 1: speed_str = " 5"; break; | ||
8135 | case 2: speed_str = " 10"; break; | ||
8136 | case 3: speed_str = " 20"; break; | ||
8137 | case 4: speed_str = " 40"; break; | ||
8138 | case 5: speed_str = " 80"; break; | ||
8139 | default: speed_str = "Unk"; break; | ||
8140 | } | ||
8141 | len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str); | ||
8142 | ASC_PRT_NEXT(); | ||
8143 | if (i == 7) | ||
8144 | { | ||
8145 | len = asc_prt_line(cp, leftlen, "\n "); | ||
8146 | ASC_PRT_NEXT(); | ||
8147 | } | ||
8148 | sdtr_speed >>= 4; | ||
8149 | } | ||
8150 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8151 | ASC_PRT_NEXT(); | ||
8152 | } | ||
8153 | |||
8154 | return totlen; | ||
8155 | } | ||
8156 | |||
8157 | /* | ||
8158 | * asc_prt_driver_conf() | ||
8159 | * | ||
8160 | * Note: no single line should be greater than ASC_PRTLINE_SIZE, | ||
8161 | * cf. asc_prt_line(). | ||
8162 | * | ||
8163 | * Return the number of characters copied into 'cp'. No more than | ||
8164 | * 'cplen' characters will be copied to 'cp'. | ||
8165 | */ | ||
8166 | STATIC int | ||
8167 | asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen) | ||
8168 | { | ||
8169 | asc_board_t *boardp; | ||
8170 | int leftlen; | ||
8171 | int totlen; | ||
8172 | int len; | ||
8173 | int chip_scsi_id; | ||
8174 | |||
8175 | boardp = ASC_BOARDP(shp); | ||
8176 | |||
8177 | leftlen = cplen; | ||
8178 | totlen = len = 0; | ||
8179 | |||
8180 | len = asc_prt_line(cp, leftlen, | ||
8181 | "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n", | ||
8182 | shp->host_no); | ||
8183 | ASC_PRT_NEXT(); | ||
8184 | |||
8185 | len = asc_prt_line(cp, leftlen, | ||
8186 | " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n", | ||
8187 | shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun, | ||
8188 | shp->max_channel); | ||
8189 | ASC_PRT_NEXT(); | ||
8190 | |||
8191 | len = asc_prt_line(cp, leftlen, | ||
8192 | " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n", | ||
8193 | shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize, | ||
8194 | shp->cmd_per_lun); | ||
8195 | ASC_PRT_NEXT(); | ||
8196 | |||
8197 | len = asc_prt_line(cp, leftlen, | ||
8198 | " unchecked_isa_dma %d, use_clustering %d\n", | ||
8199 | shp->unchecked_isa_dma, shp->use_clustering); | ||
8200 | ASC_PRT_NEXT(); | ||
8201 | |||
8202 | len = asc_prt_line(cp, leftlen, | ||
8203 | " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n", | ||
8204 | boardp->flags, boardp->last_reset, jiffies, boardp->asc_n_io_port); | ||
8205 | ASC_PRT_NEXT(); | ||
8206 | |||
8207 | /* 'shp->n_io_port' may be truncated because it is only one byte. */ | ||
8208 | len = asc_prt_line(cp, leftlen, | ||
8209 | " io_port 0x%x, n_io_port 0x%x\n", | ||
8210 | shp->io_port, shp->n_io_port); | ||
8211 | ASC_PRT_NEXT(); | ||
8212 | |||
8213 | if (ASC_NARROW_BOARD(boardp)) { | ||
8214 | chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; | ||
8215 | } else { | ||
8216 | chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id; | ||
8217 | } | ||
8218 | |||
8219 | return totlen; | ||
8220 | } | ||
8221 | |||
8222 | /* | ||
8223 | * asc_prt_asc_board_info() | ||
8224 | * | ||
8225 | * Print dynamic board configuration information. | ||
8226 | * | ||
8227 | * Note: no single line should be greater than ASC_PRTLINE_SIZE, | ||
8228 | * cf. asc_prt_line(). | ||
8229 | * | ||
8230 | * Return the number of characters copied into 'cp'. No more than | ||
8231 | * 'cplen' characters will be copied to 'cp'. | ||
8232 | */ | ||
8233 | STATIC int | ||
8234 | asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen) | ||
8235 | { | ||
8236 | asc_board_t *boardp; | ||
8237 | int chip_scsi_id; | ||
8238 | int leftlen; | ||
8239 | int totlen; | ||
8240 | int len; | ||
8241 | ASC_DVC_VAR *v; | ||
8242 | ASC_DVC_CFG *c; | ||
8243 | int i; | ||
8244 | int renegotiate = 0; | ||
8245 | |||
8246 | boardp = ASC_BOARDP(shp); | ||
8247 | v = &boardp->dvc_var.asc_dvc_var; | ||
8248 | c = &boardp->dvc_cfg.asc_dvc_cfg; | ||
8249 | chip_scsi_id = c->chip_scsi_id; | ||
8250 | |||
8251 | leftlen = cplen; | ||
8252 | totlen = len = 0; | ||
8253 | |||
8254 | len = asc_prt_line(cp, leftlen, | ||
8255 | "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n", | ||
8256 | shp->host_no); | ||
8257 | ASC_PRT_NEXT(); | ||
8258 | |||
8259 | len = asc_prt_line(cp, leftlen, | ||
8260 | " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n", | ||
8261 | c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date); | ||
8262 | ASC_PRT_NEXT(); | ||
8263 | |||
8264 | len = asc_prt_line(cp, leftlen, | ||
8265 | " mcode_version 0x%x, err_code %u\n", | ||
8266 | c->mcode_version, v->err_code); | ||
8267 | ASC_PRT_NEXT(); | ||
8268 | |||
8269 | /* Current number of commands waiting for the host. */ | ||
8270 | len = asc_prt_line(cp, leftlen, | ||
8271 | " Total Command Pending: %d\n", v->cur_total_qng); | ||
8272 | ASC_PRT_NEXT(); | ||
8273 | |||
8274 | len = asc_prt_line(cp, leftlen, | ||
8275 | " Command Queuing:"); | ||
8276 | ASC_PRT_NEXT(); | ||
8277 | for (i = 0; i <= ASC_MAX_TID; i++) { | ||
8278 | if ((chip_scsi_id == i) || | ||
8279 | ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { | ||
8280 | continue; | ||
8281 | } | ||
8282 | len = asc_prt_line(cp, leftlen, " %X:%c", | ||
8283 | i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); | ||
8284 | ASC_PRT_NEXT(); | ||
8285 | } | ||
8286 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8287 | ASC_PRT_NEXT(); | ||
8288 | |||
8289 | /* Current number of commands waiting for a device. */ | ||
8290 | len = asc_prt_line(cp, leftlen, | ||
8291 | " Command Queue Pending:"); | ||
8292 | ASC_PRT_NEXT(); | ||
8293 | for (i = 0; i <= ASC_MAX_TID; i++) { | ||
8294 | if ((chip_scsi_id == i) || | ||
8295 | ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { | ||
8296 | continue; | ||
8297 | } | ||
8298 | len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]); | ||
8299 | ASC_PRT_NEXT(); | ||
8300 | } | ||
8301 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8302 | ASC_PRT_NEXT(); | ||
8303 | |||
8304 | /* Current limit on number of commands that can be sent to a device. */ | ||
8305 | len = asc_prt_line(cp, leftlen, | ||
8306 | " Command Queue Limit:"); | ||
8307 | ASC_PRT_NEXT(); | ||
8308 | for (i = 0; i <= ASC_MAX_TID; i++) { | ||
8309 | if ((chip_scsi_id == i) || | ||
8310 | ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { | ||
8311 | continue; | ||
8312 | } | ||
8313 | len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]); | ||
8314 | ASC_PRT_NEXT(); | ||
8315 | } | ||
8316 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8317 | ASC_PRT_NEXT(); | ||
8318 | |||
8319 | /* Indicate whether the device has returned queue full status. */ | ||
8320 | len = asc_prt_line(cp, leftlen, | ||
8321 | " Command Queue Full:"); | ||
8322 | ASC_PRT_NEXT(); | ||
8323 | for (i = 0; i <= ASC_MAX_TID; i++) { | ||
8324 | if ((chip_scsi_id == i) || | ||
8325 | ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { | ||
8326 | continue; | ||
8327 | } | ||
8328 | if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) { | ||
8329 | len = asc_prt_line(cp, leftlen, " %X:Y-%d", | ||
8330 | i, boardp->queue_full_cnt[i]); | ||
8331 | } else { | ||
8332 | len = asc_prt_line(cp, leftlen, " %X:N", i); | ||
8333 | } | ||
8334 | ASC_PRT_NEXT(); | ||
8335 | } | ||
8336 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8337 | ASC_PRT_NEXT(); | ||
8338 | |||
8339 | len = asc_prt_line(cp, leftlen, | ||
8340 | " Synchronous Transfer:"); | ||
8341 | ASC_PRT_NEXT(); | ||
8342 | for (i = 0; i <= ASC_MAX_TID; i++) { | ||
8343 | if ((chip_scsi_id == i) || | ||
8344 | ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { | ||
8345 | continue; | ||
8346 | } | ||
8347 | len = asc_prt_line(cp, leftlen, " %X:%c", | ||
8348 | i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); | ||
8349 | ASC_PRT_NEXT(); | ||
8350 | } | ||
8351 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8352 | ASC_PRT_NEXT(); | ||
8353 | |||
8354 | for (i = 0; i <= ASC_MAX_TID; i++) { | ||
8355 | uchar syn_period_ix; | ||
8356 | |||
8357 | if ((chip_scsi_id == i) || | ||
8358 | ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) || | ||
8359 | ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) { | ||
8360 | continue; | ||
8361 | } | ||
8362 | |||
8363 | len = asc_prt_line(cp, leftlen, " %X:", i); | ||
8364 | ASC_PRT_NEXT(); | ||
8365 | |||
8366 | if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) | ||
8367 | { | ||
8368 | len = asc_prt_line(cp, leftlen, " Asynchronous"); | ||
8369 | ASC_PRT_NEXT(); | ||
8370 | } else | ||
8371 | { | ||
8372 | syn_period_ix = | ||
8373 | (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1); | ||
8374 | |||
8375 | len = asc_prt_line(cp, leftlen, | ||
8376 | " Transfer Period Factor: %d (%d.%d Mhz),", | ||
8377 | v->sdtr_period_tbl[syn_period_ix], | ||
8378 | 250 / v->sdtr_period_tbl[syn_period_ix], | ||
8379 | ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix])); | ||
8380 | ASC_PRT_NEXT(); | ||
8381 | |||
8382 | len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d", | ||
8383 | boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET); | ||
8384 | ASC_PRT_NEXT(); | ||
8385 | } | ||
8386 | |||
8387 | if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) { | ||
8388 | len = asc_prt_line(cp, leftlen, "*\n"); | ||
8389 | renegotiate = 1; | ||
8390 | } else | ||
8391 | { | ||
8392 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8393 | } | ||
8394 | ASC_PRT_NEXT(); | ||
8395 | } | ||
8396 | |||
8397 | if (renegotiate) | ||
8398 | { | ||
8399 | len = asc_prt_line(cp, leftlen, | ||
8400 | " * = Re-negotiation pending before next command.\n"); | ||
8401 | ASC_PRT_NEXT(); | ||
8402 | } | ||
8403 | |||
8404 | return totlen; | ||
8405 | } | ||
8406 | |||
8407 | /* | ||
8408 | * asc_prt_adv_board_info() | ||
8409 | * | ||
8410 | * Print dynamic board configuration information. | ||
8411 | * | ||
8412 | * Note: no single line should be greater than ASC_PRTLINE_SIZE, | ||
8413 | * cf. asc_prt_line(). | ||
8414 | * | ||
8415 | * Return the number of characters copied into 'cp'. No more than | ||
8416 | * 'cplen' characters will be copied to 'cp'. | ||
8417 | */ | ||
8418 | STATIC int | ||
8419 | asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen) | ||
8420 | { | ||
8421 | asc_board_t *boardp; | ||
8422 | int leftlen; | ||
8423 | int totlen; | ||
8424 | int len; | ||
8425 | int i; | ||
8426 | ADV_DVC_VAR *v; | ||
8427 | ADV_DVC_CFG *c; | ||
8428 | AdvPortAddr iop_base; | ||
8429 | ushort chip_scsi_id; | ||
8430 | ushort lramword; | ||
8431 | uchar lrambyte; | ||
8432 | ushort tagqng_able; | ||
8433 | ushort sdtr_able, wdtr_able; | ||
8434 | ushort wdtr_done, sdtr_done; | ||
8435 | ushort period = 0; | ||
8436 | int renegotiate = 0; | ||
8437 | |||
8438 | boardp = ASC_BOARDP(shp); | ||
8439 | v = &boardp->dvc_var.adv_dvc_var; | ||
8440 | c = &boardp->dvc_cfg.adv_dvc_cfg; | ||
8441 | iop_base = v->iop_base; | ||
8442 | chip_scsi_id = v->chip_scsi_id; | ||
8443 | |||
8444 | leftlen = cplen; | ||
8445 | totlen = len = 0; | ||
8446 | |||
8447 | len = asc_prt_line(cp, leftlen, | ||
8448 | "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n", | ||
8449 | shp->host_no); | ||
8450 | ASC_PRT_NEXT(); | ||
8451 | |||
8452 | len = asc_prt_line(cp, leftlen, | ||
8453 | " iop_base 0x%lx, cable_detect: %X, err_code %u\n", | ||
8454 | v->iop_base, | ||
8455 | AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT, | ||
8456 | v->err_code); | ||
8457 | ASC_PRT_NEXT(); | ||
8458 | |||
8459 | len = asc_prt_line(cp, leftlen, | ||
8460 | " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n", | ||
8461 | c->chip_version, c->lib_version, c->mcode_date, c->mcode_version); | ||
8462 | ASC_PRT_NEXT(); | ||
8463 | |||
8464 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
8465 | len = asc_prt_line(cp, leftlen, | ||
8466 | " Queuing Enabled:"); | ||
8467 | ASC_PRT_NEXT(); | ||
8468 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
8469 | if ((chip_scsi_id == i) || | ||
8470 | ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { | ||
8471 | continue; | ||
8472 | } | ||
8473 | |||
8474 | len = asc_prt_line(cp, leftlen, " %X:%c", | ||
8475 | i, (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); | ||
8476 | ASC_PRT_NEXT(); | ||
8477 | } | ||
8478 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8479 | ASC_PRT_NEXT(); | ||
8480 | |||
8481 | len = asc_prt_line(cp, leftlen, | ||
8482 | " Queue Limit:"); | ||
8483 | ASC_PRT_NEXT(); | ||
8484 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
8485 | if ((chip_scsi_id == i) || | ||
8486 | ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { | ||
8487 | continue; | ||
8488 | } | ||
8489 | |||
8490 | AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte); | ||
8491 | |||
8492 | len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte); | ||
8493 | ASC_PRT_NEXT(); | ||
8494 | } | ||
8495 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8496 | ASC_PRT_NEXT(); | ||
8497 | |||
8498 | len = asc_prt_line(cp, leftlen, | ||
8499 | " Command Pending:"); | ||
8500 | ASC_PRT_NEXT(); | ||
8501 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
8502 | if ((chip_scsi_id == i) || | ||
8503 | ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { | ||
8504 | continue; | ||
8505 | } | ||
8506 | |||
8507 | AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte); | ||
8508 | |||
8509 | len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte); | ||
8510 | ASC_PRT_NEXT(); | ||
8511 | } | ||
8512 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8513 | ASC_PRT_NEXT(); | ||
8514 | |||
8515 | AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
8516 | len = asc_prt_line(cp, leftlen, | ||
8517 | " Wide Enabled:"); | ||
8518 | ASC_PRT_NEXT(); | ||
8519 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
8520 | if ((chip_scsi_id == i) || | ||
8521 | ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { | ||
8522 | continue; | ||
8523 | } | ||
8524 | |||
8525 | len = asc_prt_line(cp, leftlen, " %X:%c", | ||
8526 | i, (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); | ||
8527 | ASC_PRT_NEXT(); | ||
8528 | } | ||
8529 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8530 | ASC_PRT_NEXT(); | ||
8531 | |||
8532 | AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done); | ||
8533 | len = asc_prt_line(cp, leftlen, | ||
8534 | " Transfer Bit Width:"); | ||
8535 | ASC_PRT_NEXT(); | ||
8536 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
8537 | if ((chip_scsi_id == i) || | ||
8538 | ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { | ||
8539 | continue; | ||
8540 | } | ||
8541 | |||
8542 | AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i), | ||
8543 | lramword); | ||
8544 | |||
8545 | len = asc_prt_line(cp, leftlen, " %X:%d", | ||
8546 | i, (lramword & 0x8000) ? 16 : 8); | ||
8547 | ASC_PRT_NEXT(); | ||
8548 | |||
8549 | if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) && | ||
8550 | (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) { | ||
8551 | len = asc_prt_line(cp, leftlen, "*"); | ||
8552 | ASC_PRT_NEXT(); | ||
8553 | renegotiate = 1; | ||
8554 | } | ||
8555 | } | ||
8556 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8557 | ASC_PRT_NEXT(); | ||
8558 | |||
8559 | AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
8560 | len = asc_prt_line(cp, leftlen, | ||
8561 | " Synchronous Enabled:"); | ||
8562 | ASC_PRT_NEXT(); | ||
8563 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
8564 | if ((chip_scsi_id == i) || | ||
8565 | ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { | ||
8566 | continue; | ||
8567 | } | ||
8568 | |||
8569 | len = asc_prt_line(cp, leftlen, " %X:%c", | ||
8570 | i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); | ||
8571 | ASC_PRT_NEXT(); | ||
8572 | } | ||
8573 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8574 | ASC_PRT_NEXT(); | ||
8575 | |||
8576 | AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done); | ||
8577 | for (i = 0; i <= ADV_MAX_TID; i++) { | ||
8578 | |||
8579 | AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i), | ||
8580 | lramword); | ||
8581 | lramword &= ~0x8000; | ||
8582 | |||
8583 | if ((chip_scsi_id == i) || | ||
8584 | ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) || | ||
8585 | ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) { | ||
8586 | continue; | ||
8587 | } | ||
8588 | |||
8589 | len = asc_prt_line(cp, leftlen, " %X:", i); | ||
8590 | ASC_PRT_NEXT(); | ||
8591 | |||
8592 | if ((lramword & 0x1F) == 0) /* Check for REQ/ACK Offset 0. */ | ||
8593 | { | ||
8594 | len = asc_prt_line(cp, leftlen, " Asynchronous"); | ||
8595 | ASC_PRT_NEXT(); | ||
8596 | } else | ||
8597 | { | ||
8598 | len = asc_prt_line(cp, leftlen, " Transfer Period Factor: "); | ||
8599 | ASC_PRT_NEXT(); | ||
8600 | |||
8601 | if ((lramword & 0x1F00) == 0x1100) /* 80 Mhz */ | ||
8602 | { | ||
8603 | len = asc_prt_line(cp, leftlen, "9 (80.0 Mhz),"); | ||
8604 | ASC_PRT_NEXT(); | ||
8605 | } else if ((lramword & 0x1F00) == 0x1000) /* 40 Mhz */ | ||
8606 | { | ||
8607 | len = asc_prt_line(cp, leftlen, "10 (40.0 Mhz),"); | ||
8608 | ASC_PRT_NEXT(); | ||
8609 | } else /* 20 Mhz or below. */ | ||
8610 | { | ||
8611 | period = (((lramword >> 8) * 25) + 50)/4; | ||
8612 | |||
8613 | if (period == 0) /* Should never happen. */ | ||
8614 | { | ||
8615 | len = asc_prt_line(cp, leftlen, "%d (? Mhz), "); | ||
8616 | ASC_PRT_NEXT(); | ||
8617 | } else | ||
8618 | { | ||
8619 | len = asc_prt_line(cp, leftlen, | ||
8620 | "%d (%d.%d Mhz),", | ||
8621 | period, 250/period, ASC_TENTHS(250, period)); | ||
8622 | ASC_PRT_NEXT(); | ||
8623 | } | ||
8624 | } | ||
8625 | |||
8626 | len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d", | ||
8627 | lramword & 0x1F); | ||
8628 | ASC_PRT_NEXT(); | ||
8629 | } | ||
8630 | |||
8631 | if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) { | ||
8632 | len = asc_prt_line(cp, leftlen, "*\n"); | ||
8633 | renegotiate = 1; | ||
8634 | } else | ||
8635 | { | ||
8636 | len = asc_prt_line(cp, leftlen, "\n"); | ||
8637 | } | ||
8638 | ASC_PRT_NEXT(); | ||
8639 | } | ||
8640 | |||
8641 | if (renegotiate) | ||
8642 | { | ||
8643 | len = asc_prt_line(cp, leftlen, | ||
8644 | " * = Re-negotiation pending before next command.\n"); | ||
8645 | ASC_PRT_NEXT(); | ||
8646 | } | ||
8647 | |||
8648 | return totlen; | ||
8649 | } | ||
8650 | |||
8651 | /* | ||
8652 | * asc_proc_copy() | ||
8653 | * | ||
8654 | * Copy proc information to a read buffer taking into account the current | ||
8655 | * read offset in the file and the remaining space in the read buffer. | ||
8656 | */ | ||
8657 | STATIC int | ||
8658 | asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen, | ||
8659 | char *cp, int cplen) | ||
8660 | { | ||
8661 | int cnt = 0; | ||
8662 | |||
8663 | ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n", | ||
8664 | (unsigned) offset, (unsigned) advoffset, cplen); | ||
8665 | if (offset <= advoffset) { | ||
8666 | /* Read offset below current offset, copy everything. */ | ||
8667 | cnt = min(cplen, leftlen); | ||
8668 | ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n", | ||
8669 | (ulong) curbuf, (ulong) cp, cnt); | ||
8670 | memcpy(curbuf, cp, cnt); | ||
8671 | } else if (offset < advoffset + cplen) { | ||
8672 | /* Read offset within current range, partial copy. */ | ||
8673 | cnt = (advoffset + cplen) - offset; | ||
8674 | cp = (cp + cplen) - cnt; | ||
8675 | cnt = min(cnt, leftlen); | ||
8676 | ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n", | ||
8677 | (ulong) curbuf, (ulong) cp, cnt); | ||
8678 | memcpy(curbuf, cp, cnt); | ||
8679 | } | ||
8680 | return cnt; | ||
8681 | } | ||
8682 | |||
8683 | /* | ||
8684 | * asc_prt_line() | ||
8685 | * | ||
8686 | * If 'cp' is NULL print to the console, otherwise print to a buffer. | ||
8687 | * | ||
8688 | * Return 0 if printing to the console, otherwise return the number of | ||
8689 | * bytes written to the buffer. | ||
8690 | * | ||
8691 | * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack | ||
8692 | * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes. | ||
8693 | */ | ||
8694 | STATIC int | ||
8695 | asc_prt_line(char *buf, int buflen, char *fmt, ...) | ||
8696 | { | ||
8697 | va_list args; | ||
8698 | int ret; | ||
8699 | char s[ASC_PRTLINE_SIZE]; | ||
8700 | |||
8701 | va_start(args, fmt); | ||
8702 | ret = vsprintf(s, fmt, args); | ||
8703 | ASC_ASSERT(ret < ASC_PRTLINE_SIZE); | ||
8704 | if (buf == NULL) { | ||
8705 | (void) printk(s); | ||
8706 | ret = 0; | ||
8707 | } else { | ||
8708 | ret = min(buflen, ret); | ||
8709 | memcpy(buf, s, ret); | ||
8710 | } | ||
8711 | va_end(args); | ||
8712 | return ret; | ||
8713 | } | ||
8714 | #endif /* CONFIG_PROC_FS */ | ||
8715 | |||
8716 | |||
8717 | /* | ||
8718 | * --- Functions Required by the Asc Library | ||
8719 | */ | ||
8720 | |||
8721 | /* | ||
8722 | * Delay for 'n' milliseconds. Don't use the 'jiffies' | ||
8723 | * global variable which is incremented once every 5 ms | ||
8724 | * from a timer interrupt, because this function may be | ||
8725 | * called when interrupts are disabled. | ||
8726 | */ | ||
8727 | STATIC void | ||
8728 | DvcSleepMilliSecond(ADV_DCNT n) | ||
8729 | { | ||
8730 | ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong) n); | ||
8731 | mdelay(n); | ||
8732 | } | ||
8733 | |||
8734 | /* | ||
8735 | * Currently and inline noop but leave as a placeholder. | ||
8736 | * Leave DvcEnterCritical() as a noop placeholder. | ||
8737 | */ | ||
8738 | STATIC inline ulong | ||
8739 | DvcEnterCritical(void) | ||
8740 | { | ||
8741 | return 0; | ||
8742 | } | ||
8743 | |||
8744 | /* | ||
8745 | * Critical sections are all protected by the board spinlock. | ||
8746 | * Leave DvcLeaveCritical() as a noop placeholder. | ||
8747 | */ | ||
8748 | STATIC inline void | ||
8749 | DvcLeaveCritical(ulong flags) | ||
8750 | { | ||
8751 | return; | ||
8752 | } | ||
8753 | |||
8754 | /* | ||
8755 | * void | ||
8756 | * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words) | ||
8757 | * | ||
8758 | * Calling/Exit State: | ||
8759 | * none | ||
8760 | * | ||
8761 | * Description: | ||
8762 | * Output an ASC_SCSI_Q structure to the chip | ||
8763 | */ | ||
8764 | STATIC void | ||
8765 | DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words) | ||
8766 | { | ||
8767 | int i; | ||
8768 | |||
8769 | ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words); | ||
8770 | AscSetChipLramAddr(iop_base, s_addr); | ||
8771 | for (i = 0; i < 2 * words; i += 2) { | ||
8772 | if (i == 4 || i == 20) { | ||
8773 | continue; | ||
8774 | } | ||
8775 | outpw(iop_base + IOP_RAM_DATA, | ||
8776 | ((ushort) outbuf[i + 1] << 8) | outbuf[i]); | ||
8777 | } | ||
8778 | } | ||
8779 | |||
8780 | /* | ||
8781 | * void | ||
8782 | * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words) | ||
8783 | * | ||
8784 | * Calling/Exit State: | ||
8785 | * none | ||
8786 | * | ||
8787 | * Description: | ||
8788 | * Input an ASC_QDONE_INFO structure from the chip | ||
8789 | */ | ||
8790 | STATIC void | ||
8791 | DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words) | ||
8792 | { | ||
8793 | int i; | ||
8794 | ushort word; | ||
8795 | |||
8796 | AscSetChipLramAddr(iop_base, s_addr); | ||
8797 | for (i = 0; i < 2 * words; i += 2) { | ||
8798 | if (i == 10) { | ||
8799 | continue; | ||
8800 | } | ||
8801 | word = inpw(iop_base + IOP_RAM_DATA); | ||
8802 | inbuf[i] = word & 0xff; | ||
8803 | inbuf[i + 1] = (word >> 8) & 0xff; | ||
8804 | } | ||
8805 | ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words); | ||
8806 | } | ||
8807 | |||
8808 | /* | ||
8809 | * Read a PCI configuration byte. | ||
8810 | */ | ||
8811 | STATIC uchar __init | ||
8812 | DvcReadPCIConfigByte( | ||
8813 | ASC_DVC_VAR *asc_dvc, | ||
8814 | ushort offset) | ||
8815 | { | ||
8816 | #ifdef CONFIG_PCI | ||
8817 | uchar byte_data; | ||
8818 | pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data); | ||
8819 | return byte_data; | ||
8820 | #else /* !defined(CONFIG_PCI) */ | ||
8821 | return 0; | ||
8822 | #endif /* !defined(CONFIG_PCI) */ | ||
8823 | } | ||
8824 | |||
8825 | /* | ||
8826 | * Write a PCI configuration byte. | ||
8827 | */ | ||
8828 | STATIC void __init | ||
8829 | DvcWritePCIConfigByte( | ||
8830 | ASC_DVC_VAR *asc_dvc, | ||
8831 | ushort offset, | ||
8832 | uchar byte_data) | ||
8833 | { | ||
8834 | #ifdef CONFIG_PCI | ||
8835 | pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data); | ||
8836 | #endif /* CONFIG_PCI */ | ||
8837 | } | ||
8838 | |||
8839 | /* | ||
8840 | * Return the BIOS address of the adapter at the specified | ||
8841 | * I/O port and with the specified bus type. | ||
8842 | */ | ||
8843 | STATIC ushort __init | ||
8844 | AscGetChipBiosAddress( | ||
8845 | PortAddr iop_base, | ||
8846 | ushort bus_type) | ||
8847 | { | ||
8848 | ushort cfg_lsw; | ||
8849 | ushort bios_addr; | ||
8850 | |||
8851 | /* | ||
8852 | * The PCI BIOS is re-located by the motherboard BIOS. Because | ||
8853 | * of this the driver can not determine where a PCI BIOS is | ||
8854 | * loaded and executes. | ||
8855 | */ | ||
8856 | if (bus_type & ASC_IS_PCI) | ||
8857 | { | ||
8858 | return(0); | ||
8859 | } | ||
8860 | |||
8861 | #ifdef CONFIG_ISA | ||
8862 | if((bus_type & ASC_IS_EISA) != 0) | ||
8863 | { | ||
8864 | cfg_lsw = AscGetEisaChipCfg(iop_base); | ||
8865 | cfg_lsw &= 0x000F; | ||
8866 | bios_addr = (ushort)(ASC_BIOS_MIN_ADDR + | ||
8867 | (cfg_lsw * ASC_BIOS_BANK_SIZE)); | ||
8868 | return(bios_addr); | ||
8869 | }/* if */ | ||
8870 | #endif /* CONFIG_ISA */ | ||
8871 | |||
8872 | cfg_lsw = AscGetChipCfgLsw(iop_base); | ||
8873 | |||
8874 | /* | ||
8875 | * ISA PnP uses the top bit as the 32K BIOS flag | ||
8876 | */ | ||
8877 | if (bus_type == ASC_IS_ISAPNP) | ||
8878 | { | ||
8879 | cfg_lsw &= 0x7FFF; | ||
8880 | }/* if */ | ||
8881 | |||
8882 | bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) + | ||
8883 | ASC_BIOS_MIN_ADDR); | ||
8884 | return(bios_addr); | ||
8885 | } | ||
8886 | |||
8887 | |||
8888 | /* | ||
8889 | * --- Functions Required by the Adv Library | ||
8890 | */ | ||
8891 | |||
8892 | /* | ||
8893 | * DvcGetPhyAddr() | ||
8894 | * | ||
8895 | * Return the physical address of 'vaddr' and set '*lenp' to the | ||
8896 | * number of physically contiguous bytes that follow 'vaddr'. | ||
8897 | * 'flag' indicates the type of structure whose physical address | ||
8898 | * is being translated. | ||
8899 | * | ||
8900 | * Note: Because Linux currently doesn't page the kernel and all | ||
8901 | * kernel buffers are physically contiguous, leave '*lenp' unchanged. | ||
8902 | */ | ||
8903 | ADV_PADDR | ||
8904 | DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq, | ||
8905 | uchar *vaddr, ADV_SDCNT *lenp, int flag) | ||
8906 | { | ||
8907 | ADV_PADDR paddr; | ||
8908 | |||
8909 | paddr = virt_to_bus(vaddr); | ||
8910 | |||
8911 | ASC_DBG4(4, | ||
8912 | "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n", | ||
8913 | (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), (ulong) paddr); | ||
8914 | |||
8915 | return paddr; | ||
8916 | } | ||
8917 | |||
8918 | /* | ||
8919 | * Read a PCI configuration byte. | ||
8920 | */ | ||
8921 | STATIC uchar __init | ||
8922 | DvcAdvReadPCIConfigByte( | ||
8923 | ADV_DVC_VAR *asc_dvc, | ||
8924 | ushort offset) | ||
8925 | { | ||
8926 | #ifdef CONFIG_PCI | ||
8927 | uchar byte_data; | ||
8928 | pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data); | ||
8929 | return byte_data; | ||
8930 | #else /* CONFIG_PCI */ | ||
8931 | return 0; | ||
8932 | #endif /* CONFIG_PCI */ | ||
8933 | } | ||
8934 | |||
8935 | /* | ||
8936 | * Write a PCI configuration byte. | ||
8937 | */ | ||
8938 | STATIC void __init | ||
8939 | DvcAdvWritePCIConfigByte( | ||
8940 | ADV_DVC_VAR *asc_dvc, | ||
8941 | ushort offset, | ||
8942 | uchar byte_data) | ||
8943 | { | ||
8944 | #ifdef CONFIG_PCI | ||
8945 | pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data); | ||
8946 | #else /* CONFIG_PCI */ | ||
8947 | return; | ||
8948 | #endif /* CONFIG_PCI */ | ||
8949 | } | ||
8950 | |||
8951 | /* | ||
8952 | * --- Tracing and Debugging Functions | ||
8953 | */ | ||
8954 | |||
8955 | #ifdef ADVANSYS_STATS | ||
8956 | #ifdef CONFIG_PROC_FS | ||
8957 | /* | ||
8958 | * asc_prt_board_stats() | ||
8959 | * | ||
8960 | * Note: no single line should be greater than ASC_PRTLINE_SIZE, | ||
8961 | * cf. asc_prt_line(). | ||
8962 | * | ||
8963 | * Return the number of characters copied into 'cp'. No more than | ||
8964 | * 'cplen' characters will be copied to 'cp'. | ||
8965 | */ | ||
8966 | STATIC int | ||
8967 | asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen) | ||
8968 | { | ||
8969 | int leftlen; | ||
8970 | int totlen; | ||
8971 | int len; | ||
8972 | struct asc_stats *s; | ||
8973 | asc_board_t *boardp; | ||
8974 | |||
8975 | leftlen = cplen; | ||
8976 | totlen = len = 0; | ||
8977 | |||
8978 | boardp = ASC_BOARDP(shp); | ||
8979 | s = &boardp->asc_stats; | ||
8980 | |||
8981 | len = asc_prt_line(cp, leftlen, | ||
8982 | "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no); | ||
8983 | ASC_PRT_NEXT(); | ||
8984 | |||
8985 | len = asc_prt_line(cp, leftlen, | ||
8986 | " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n", | ||
8987 | s->queuecommand, s->reset, s->biosparam, s->interrupt); | ||
8988 | ASC_PRT_NEXT(); | ||
8989 | |||
8990 | len = asc_prt_line(cp, leftlen, | ||
8991 | " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n", | ||
8992 | s->callback, s->done, s->build_error, s->adv_build_noreq, | ||
8993 | s->adv_build_nosg); | ||
8994 | ASC_PRT_NEXT(); | ||
8995 | |||
8996 | len = asc_prt_line(cp, leftlen, | ||
8997 | " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n", | ||
8998 | s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown); | ||
8999 | ASC_PRT_NEXT(); | ||
9000 | |||
9001 | /* | ||
9002 | * Display data transfer statistics. | ||
9003 | */ | ||
9004 | if (s->cont_cnt > 0) { | ||
9005 | len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt); | ||
9006 | ASC_PRT_NEXT(); | ||
9007 | |||
9008 | len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ", | ||
9009 | s->cont_xfer/2, | ||
9010 | ASC_TENTHS(s->cont_xfer, 2)); | ||
9011 | ASC_PRT_NEXT(); | ||
9012 | |||
9013 | /* Contiguous transfer average size */ | ||
9014 | len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n", | ||
9015 | (s->cont_xfer/2)/s->cont_cnt, | ||
9016 | ASC_TENTHS((s->cont_xfer/2), s->cont_cnt)); | ||
9017 | ASC_PRT_NEXT(); | ||
9018 | } | ||
9019 | |||
9020 | if (s->sg_cnt > 0) { | ||
9021 | |||
9022 | len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ", | ||
9023 | s->sg_cnt, s->sg_elem); | ||
9024 | ASC_PRT_NEXT(); | ||
9025 | |||
9026 | len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n", | ||
9027 | s->sg_xfer/2, | ||
9028 | ASC_TENTHS(s->sg_xfer, 2)); | ||
9029 | ASC_PRT_NEXT(); | ||
9030 | |||
9031 | /* Scatter gather transfer statistics */ | ||
9032 | len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ", | ||
9033 | s->sg_elem/s->sg_cnt, | ||
9034 | ASC_TENTHS(s->sg_elem, s->sg_cnt)); | ||
9035 | ASC_PRT_NEXT(); | ||
9036 | |||
9037 | len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ", | ||
9038 | (s->sg_xfer/2)/s->sg_elem, | ||
9039 | ASC_TENTHS((s->sg_xfer/2), s->sg_elem)); | ||
9040 | ASC_PRT_NEXT(); | ||
9041 | |||
9042 | len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n", | ||
9043 | (s->sg_xfer/2)/s->sg_cnt, | ||
9044 | ASC_TENTHS((s->sg_xfer/2), s->sg_cnt)); | ||
9045 | ASC_PRT_NEXT(); | ||
9046 | } | ||
9047 | |||
9048 | /* | ||
9049 | * Display request queuing statistics. | ||
9050 | */ | ||
9051 | len = asc_prt_line(cp, leftlen, | ||
9052 | " Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ); | ||
9053 | ASC_PRT_NEXT(); | ||
9054 | |||
9055 | |||
9056 | return totlen; | ||
9057 | } | ||
9058 | |||
9059 | /* | ||
9060 | * asc_prt_target_stats() | ||
9061 | * | ||
9062 | * Note: no single line should be greater than ASC_PRTLINE_SIZE, | ||
9063 | * cf. asc_prt_line(). | ||
9064 | * | ||
9065 | * This is separated from asc_prt_board_stats because a full set | ||
9066 | * of targets will overflow ASC_PRTBUF_SIZE. | ||
9067 | * | ||
9068 | * Return the number of characters copied into 'cp'. No more than | ||
9069 | * 'cplen' characters will be copied to 'cp'. | ||
9070 | */ | ||
9071 | STATIC int | ||
9072 | asc_prt_target_stats(struct Scsi_Host *shp, int tgt_id, char *cp, int cplen) | ||
9073 | { | ||
9074 | int leftlen; | ||
9075 | int totlen; | ||
9076 | int len; | ||
9077 | struct asc_stats *s; | ||
9078 | ushort chip_scsi_id; | ||
9079 | asc_board_t *boardp; | ||
9080 | asc_queue_t *active; | ||
9081 | asc_queue_t *waiting; | ||
9082 | |||
9083 | leftlen = cplen; | ||
9084 | totlen = len = 0; | ||
9085 | |||
9086 | boardp = ASC_BOARDP(shp); | ||
9087 | s = &boardp->asc_stats; | ||
9088 | |||
9089 | active = &ASC_BOARDP(shp)->active; | ||
9090 | waiting = &ASC_BOARDP(shp)->waiting; | ||
9091 | |||
9092 | if (ASC_NARROW_BOARD(boardp)) { | ||
9093 | chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; | ||
9094 | } else { | ||
9095 | chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id; | ||
9096 | } | ||
9097 | |||
9098 | if ((chip_scsi_id == tgt_id) || | ||
9099 | ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) { | ||
9100 | return 0; | ||
9101 | } | ||
9102 | |||
9103 | do { | ||
9104 | if (active->q_tot_cnt[tgt_id] > 0 || waiting->q_tot_cnt[tgt_id] > 0) { | ||
9105 | len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id); | ||
9106 | ASC_PRT_NEXT(); | ||
9107 | |||
9108 | len = asc_prt_line(cp, leftlen, | ||
9109 | " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n", | ||
9110 | active->q_cur_cnt[tgt_id], active->q_max_cnt[tgt_id], | ||
9111 | active->q_tot_cnt[tgt_id], | ||
9112 | active->q_min_tim[tgt_id], active->q_max_tim[tgt_id], | ||
9113 | (active->q_tot_cnt[tgt_id] == 0) ? 0 : | ||
9114 | (active->q_tot_tim[tgt_id]/active->q_tot_cnt[tgt_id]), | ||
9115 | (active->q_tot_cnt[tgt_id] == 0) ? 0 : | ||
9116 | ASC_TENTHS(active->q_tot_tim[tgt_id], | ||
9117 | active->q_tot_cnt[tgt_id])); | ||
9118 | ASC_PRT_NEXT(); | ||
9119 | |||
9120 | len = asc_prt_line(cp, leftlen, | ||
9121 | " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n", | ||
9122 | waiting->q_cur_cnt[tgt_id], waiting->q_max_cnt[tgt_id], | ||
9123 | waiting->q_tot_cnt[tgt_id], | ||
9124 | waiting->q_min_tim[tgt_id], waiting->q_max_tim[tgt_id], | ||
9125 | (waiting->q_tot_cnt[tgt_id] == 0) ? 0 : | ||
9126 | (waiting->q_tot_tim[tgt_id]/waiting->q_tot_cnt[tgt_id]), | ||
9127 | (waiting->q_tot_cnt[tgt_id] == 0) ? 0 : | ||
9128 | ASC_TENTHS(waiting->q_tot_tim[tgt_id], | ||
9129 | waiting->q_tot_cnt[tgt_id])); | ||
9130 | ASC_PRT_NEXT(); | ||
9131 | } | ||
9132 | } while (0); | ||
9133 | |||
9134 | return totlen; | ||
9135 | } | ||
9136 | #endif /* CONFIG_PROC_FS */ | ||
9137 | #endif /* ADVANSYS_STATS */ | ||
9138 | |||
9139 | #ifdef ADVANSYS_DEBUG | ||
9140 | /* | ||
9141 | * asc_prt_scsi_host() | ||
9142 | */ | ||
9143 | STATIC void | ||
9144 | asc_prt_scsi_host(struct Scsi_Host *s) | ||
9145 | { | ||
9146 | asc_board_t *boardp; | ||
9147 | |||
9148 | boardp = ASC_BOARDP(s); | ||
9149 | |||
9150 | printk("Scsi_Host at addr 0x%lx\n", (ulong) s); | ||
9151 | printk( | ||
9152 | " host_busy %u, host_no %d, last_reset %d,\n", | ||
9153 | s->host_busy, s->host_no, | ||
9154 | (unsigned) s->last_reset); | ||
9155 | |||
9156 | printk( | ||
9157 | " base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n", | ||
9158 | (ulong) s->base, (ulong) s->io_port, s->n_io_port, s->irq); | ||
9159 | |||
9160 | printk( | ||
9161 | " dma_channel %d, this_id %d, can_queue %d,\n", | ||
9162 | s->dma_channel, s->this_id, s->can_queue); | ||
9163 | |||
9164 | printk( | ||
9165 | " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n", | ||
9166 | s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma); | ||
9167 | |||
9168 | if (ASC_NARROW_BOARD(boardp)) { | ||
9169 | asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var); | ||
9170 | asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg); | ||
9171 | } else { | ||
9172 | asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var); | ||
9173 | asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg); | ||
9174 | } | ||
9175 | } | ||
9176 | |||
9177 | /* | ||
9178 | * asc_prt_scsi_cmnd() | ||
9179 | */ | ||
9180 | STATIC void | ||
9181 | asc_prt_scsi_cmnd(struct scsi_cmnd *s) | ||
9182 | { | ||
9183 | printk("struct scsi_cmnd at addr 0x%lx\n", (ulong) s); | ||
9184 | |||
9185 | printk( | ||
9186 | " host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n", | ||
9187 | (ulong) s->device->host, (ulong) s->device, s->device->id, s->device->lun, | ||
9188 | s->device->channel); | ||
9189 | |||
9190 | asc_prt_hex(" CDB", s->cmnd, s->cmd_len); | ||
9191 | |||
9192 | printk ( | ||
9193 | "sc_data_direction %u, resid %d\n", | ||
9194 | s->sc_data_direction, s->resid); | ||
9195 | |||
9196 | printk( | ||
9197 | " use_sg %u, sglist_len %u, abort_reason 0x%x\n", | ||
9198 | s->use_sg, s->sglist_len, s->abort_reason); | ||
9199 | |||
9200 | printk( | ||
9201 | " serial_number 0x%x, serial_number_at_timeout 0x%x, retries %d, allowed %d\n", | ||
9202 | (unsigned) s->serial_number, (unsigned) s->serial_number_at_timeout, | ||
9203 | s->retries, s->allowed); | ||
9204 | |||
9205 | printk( | ||
9206 | " timeout_per_command %d, timeout_total %d, timeout %d\n", | ||
9207 | s->timeout_per_command, s->timeout_total, s->timeout); | ||
9208 | |||
9209 | printk(" internal_timeout %u\n", s->internal_timeout); | ||
9210 | |||
9211 | printk( | ||
9212 | " scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n", | ||
9213 | (ulong) s->scsi_done, (ulong) s->done, | ||
9214 | (ulong) s->host_scribble, s->result); | ||
9215 | |||
9216 | printk( | ||
9217 | " tag %u, pid %u\n", | ||
9218 | (unsigned) s->tag, (unsigned) s->pid); | ||
9219 | } | ||
9220 | |||
9221 | /* | ||
9222 | * asc_prt_asc_dvc_var() | ||
9223 | */ | ||
9224 | STATIC void | ||
9225 | asc_prt_asc_dvc_var(ASC_DVC_VAR *h) | ||
9226 | { | ||
9227 | printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong) h); | ||
9228 | |||
9229 | printk( | ||
9230 | " iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n", | ||
9231 | h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl); | ||
9232 | |||
9233 | printk( | ||
9234 | " bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n", | ||
9235 | h->bus_type, (ulong) h->isr_callback, (ulong) h->exe_callback, | ||
9236 | (unsigned) h->init_sdtr); | ||
9237 | |||
9238 | printk( | ||
9239 | " sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n", | ||
9240 | (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng, | ||
9241 | (unsigned) h->unit_not_ready, (unsigned) h->chip_no); | ||
9242 | |||
9243 | printk( | ||
9244 | " queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n", | ||
9245 | (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor, | ||
9246 | (unsigned) h->scsi_reset_wait); | ||
9247 | |||
9248 | printk( | ||
9249 | " is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n", | ||
9250 | (unsigned) h->is_in_int, (unsigned) h->max_total_qng, | ||
9251 | (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt); | ||
9252 | |||
9253 | printk( | ||
9254 | " last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n", | ||
9255 | (unsigned) h->last_q_shortage, (unsigned) h->init_state, | ||
9256 | (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer); | ||
9257 | |||
9258 | printk( | ||
9259 | " cfg 0x%lx, irq_no 0x%x\n", | ||
9260 | (ulong) h->cfg, (unsigned) h->irq_no); | ||
9261 | } | ||
9262 | |||
9263 | /* | ||
9264 | * asc_prt_asc_dvc_cfg() | ||
9265 | */ | ||
9266 | STATIC void | ||
9267 | asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h) | ||
9268 | { | ||
9269 | printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong) h); | ||
9270 | |||
9271 | printk( | ||
9272 | " can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n", | ||
9273 | h->can_tagged_qng, h->cmd_qng_enabled); | ||
9274 | printk( | ||
9275 | " disc_enable 0x%x, sdtr_enable 0x%x,\n", | ||
9276 | h->disc_enable, h->sdtr_enable); | ||
9277 | |||
9278 | printk( | ||
9279 | " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n", | ||
9280 | h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel, | ||
9281 | h->chip_version); | ||
9282 | |||
9283 | printk( | ||
9284 | " pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n", | ||
9285 | to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version, | ||
9286 | h->mcode_date); | ||
9287 | |||
9288 | printk( | ||
9289 | " mcode_version %d, overrun_buf 0x%lx\n", | ||
9290 | h->mcode_version, (ulong) h->overrun_buf); | ||
9291 | } | ||
9292 | |||
9293 | /* | ||
9294 | * asc_prt_asc_scsi_q() | ||
9295 | */ | ||
9296 | STATIC void | ||
9297 | asc_prt_asc_scsi_q(ASC_SCSI_Q *q) | ||
9298 | { | ||
9299 | ASC_SG_HEAD *sgp; | ||
9300 | int i; | ||
9301 | |||
9302 | printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong) q); | ||
9303 | |||
9304 | printk( | ||
9305 | " target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n", | ||
9306 | q->q2.target_ix, q->q1.target_lun, | ||
9307 | (ulong) q->q2.srb_ptr, q->q2.tag_code); | ||
9308 | |||
9309 | printk( | ||
9310 | " data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n", | ||
9311 | (ulong) le32_to_cpu(q->q1.data_addr), | ||
9312 | (ulong) le32_to_cpu(q->q1.data_cnt), | ||
9313 | (ulong) le32_to_cpu(q->q1.sense_addr), q->q1.sense_len); | ||
9314 | |||
9315 | printk( | ||
9316 | " cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n", | ||
9317 | (ulong) q->cdbptr, q->q2.cdb_len, | ||
9318 | (ulong) q->sg_head, q->q1.sg_queue_cnt); | ||
9319 | |||
9320 | if (q->sg_head) { | ||
9321 | sgp = q->sg_head; | ||
9322 | printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong) sgp); | ||
9323 | printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt); | ||
9324 | for (i = 0; i < sgp->entry_cnt; i++) { | ||
9325 | printk(" [%u]: addr 0x%lx, bytes %lu\n", | ||
9326 | i, (ulong) le32_to_cpu(sgp->sg_list[i].addr), | ||
9327 | (ulong) le32_to_cpu(sgp->sg_list[i].bytes)); | ||
9328 | } | ||
9329 | |||
9330 | } | ||
9331 | } | ||
9332 | |||
9333 | /* | ||
9334 | * asc_prt_asc_qdone_info() | ||
9335 | */ | ||
9336 | STATIC void | ||
9337 | asc_prt_asc_qdone_info(ASC_QDONE_INFO *q) | ||
9338 | { | ||
9339 | printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong) q); | ||
9340 | printk( | ||
9341 | " srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n", | ||
9342 | (ulong) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len, | ||
9343 | q->d2.tag_code); | ||
9344 | printk( | ||
9345 | " done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n", | ||
9346 | q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg); | ||
9347 | } | ||
9348 | |||
9349 | /* | ||
9350 | * asc_prt_adv_dvc_var() | ||
9351 | * | ||
9352 | * Display an ADV_DVC_VAR structure. | ||
9353 | */ | ||
9354 | STATIC void | ||
9355 | asc_prt_adv_dvc_var(ADV_DVC_VAR *h) | ||
9356 | { | ||
9357 | printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h); | ||
9358 | |||
9359 | printk( | ||
9360 | " iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n", | ||
9361 | (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able); | ||
9362 | |||
9363 | printk( | ||
9364 | " isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n", | ||
9365 | (ulong) h->isr_callback, (unsigned) h->sdtr_able, | ||
9366 | (unsigned) h->wdtr_able); | ||
9367 | |||
9368 | printk( | ||
9369 | " start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n", | ||
9370 | (unsigned) h->start_motor, | ||
9371 | (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no); | ||
9372 | |||
9373 | printk( | ||
9374 | " max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n", | ||
9375 | (unsigned) h->max_host_qng, (unsigned) h->max_dvc_qng, | ||
9376 | (ulong) h->carr_freelist); | ||
9377 | |||
9378 | printk( | ||
9379 | " icq_sp 0x%lx, irq_sp 0x%lx\n", | ||
9380 | (ulong) h->icq_sp, (ulong) h->irq_sp); | ||
9381 | |||
9382 | printk( | ||
9383 | " no_scam 0x%x, tagqng_able 0x%x\n", | ||
9384 | (unsigned) h->no_scam, (unsigned) h->tagqng_able); | ||
9385 | |||
9386 | printk( | ||
9387 | " chip_scsi_id 0x%x, cfg 0x%lx\n", | ||
9388 | (unsigned) h->chip_scsi_id, (ulong) h->cfg); | ||
9389 | } | ||
9390 | |||
9391 | /* | ||
9392 | * asc_prt_adv_dvc_cfg() | ||
9393 | * | ||
9394 | * Display an ADV_DVC_CFG structure. | ||
9395 | */ | ||
9396 | STATIC void | ||
9397 | asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h) | ||
9398 | { | ||
9399 | printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h); | ||
9400 | |||
9401 | printk( | ||
9402 | " disc_enable 0x%x, termination 0x%x\n", | ||
9403 | h->disc_enable, h->termination); | ||
9404 | |||
9405 | printk( | ||
9406 | " chip_version 0x%x, mcode_date 0x%x\n", | ||
9407 | h->chip_version, h->mcode_date); | ||
9408 | |||
9409 | printk( | ||
9410 | " mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n", | ||
9411 | h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version); | ||
9412 | |||
9413 | printk( | ||
9414 | " control_flag 0x%x, pci_slot_info 0x%x\n", | ||
9415 | h->control_flag, h->pci_slot_info); | ||
9416 | } | ||
9417 | |||
9418 | /* | ||
9419 | * asc_prt_adv_scsi_req_q() | ||
9420 | * | ||
9421 | * Display an ADV_SCSI_REQ_Q structure. | ||
9422 | */ | ||
9423 | STATIC void | ||
9424 | asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q) | ||
9425 | { | ||
9426 | int sg_blk_cnt; | ||
9427 | struct asc_sg_block *sg_ptr; | ||
9428 | |||
9429 | printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong) q); | ||
9430 | |||
9431 | printk( | ||
9432 | " target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n", | ||
9433 | q->target_id, q->target_lun, (ulong) q->srb_ptr, q->a_flag); | ||
9434 | |||
9435 | printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n", | ||
9436 | q->cntl, (ulong) le32_to_cpu(q->data_addr), (ulong) q->vdata_addr); | ||
9437 | |||
9438 | printk( | ||
9439 | " data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n", | ||
9440 | (ulong) le32_to_cpu(q->data_cnt), | ||
9441 | (ulong) le32_to_cpu(q->sense_addr), q->sense_len); | ||
9442 | |||
9443 | printk( | ||
9444 | " cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n", | ||
9445 | q->cdb_len, q->done_status, q->host_status, q->scsi_status); | ||
9446 | |||
9447 | printk( | ||
9448 | " sg_working_ix 0x%x, target_cmd %u\n", | ||
9449 | q->sg_working_ix, q->target_cmd); | ||
9450 | |||
9451 | printk( | ||
9452 | " scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n", | ||
9453 | (ulong) le32_to_cpu(q->scsiq_rptr), | ||
9454 | (ulong) le32_to_cpu(q->sg_real_addr), (ulong) q->sg_list_ptr); | ||
9455 | |||
9456 | /* Display the request's ADV_SG_BLOCK structures. */ | ||
9457 | if (q->sg_list_ptr != NULL) | ||
9458 | { | ||
9459 | sg_blk_cnt = 0; | ||
9460 | while (1) { | ||
9461 | /* | ||
9462 | * 'sg_ptr' is a physical address. Convert it to a virtual | ||
9463 | * address by indexing 'sg_blk_cnt' into the virtual address | ||
9464 | * array 'sg_list_ptr'. | ||
9465 | * | ||
9466 | * XXX - Assumes all SG physical blocks are virtually contiguous. | ||
9467 | */ | ||
9468 | sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[sg_blk_cnt]); | ||
9469 | asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr); | ||
9470 | if (sg_ptr->sg_ptr == 0) | ||
9471 | { | ||
9472 | break; | ||
9473 | } | ||
9474 | sg_blk_cnt++; | ||
9475 | } | ||
9476 | } | ||
9477 | } | ||
9478 | |||
9479 | /* | ||
9480 | * asc_prt_adv_sgblock() | ||
9481 | * | ||
9482 | * Display an ADV_SG_BLOCK structure. | ||
9483 | */ | ||
9484 | STATIC void | ||
9485 | asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b) | ||
9486 | { | ||
9487 | int i; | ||
9488 | |||
9489 | printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n", | ||
9490 | (ulong) b, sgblockno); | ||
9491 | printk(" sg_cnt %u, sg_ptr 0x%lx\n", | ||
9492 | b->sg_cnt, (ulong) le32_to_cpu(b->sg_ptr)); | ||
9493 | ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK); | ||
9494 | if (b->sg_ptr != 0) | ||
9495 | { | ||
9496 | ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK); | ||
9497 | } | ||
9498 | for (i = 0; i < b->sg_cnt; i++) { | ||
9499 | printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n", | ||
9500 | i, (ulong) b->sg_list[i].sg_addr, (ulong) b->sg_list[i].sg_count); | ||
9501 | } | ||
9502 | } | ||
9503 | |||
9504 | /* | ||
9505 | * asc_prt_hex() | ||
9506 | * | ||
9507 | * Print hexadecimal output in 4 byte groupings 32 bytes | ||
9508 | * or 8 double-words per line. | ||
9509 | */ | ||
9510 | STATIC void | ||
9511 | asc_prt_hex(char *f, uchar *s, int l) | ||
9512 | { | ||
9513 | int i; | ||
9514 | int j; | ||
9515 | int k; | ||
9516 | int m; | ||
9517 | |||
9518 | printk("%s: (%d bytes)\n", f, l); | ||
9519 | |||
9520 | for (i = 0; i < l; i += 32) { | ||
9521 | |||
9522 | /* Display a maximum of 8 double-words per line. */ | ||
9523 | if ((k = (l - i) / 4) >= 8) { | ||
9524 | k = 8; | ||
9525 | m = 0; | ||
9526 | } else { | ||
9527 | m = (l - i) % 4; | ||
9528 | } | ||
9529 | |||
9530 | for (j = 0; j < k; j++) { | ||
9531 | printk(" %2.2X%2.2X%2.2X%2.2X", | ||
9532 | (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1], | ||
9533 | (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]); | ||
9534 | } | ||
9535 | |||
9536 | switch (m) { | ||
9537 | case 0: | ||
9538 | default: | ||
9539 | break; | ||
9540 | case 1: | ||
9541 | printk(" %2.2X", | ||
9542 | (unsigned) s[i+(j*4)]); | ||
9543 | break; | ||
9544 | case 2: | ||
9545 | printk(" %2.2X%2.2X", | ||
9546 | (unsigned) s[i+(j*4)], | ||
9547 | (unsigned) s[i+(j*4)+1]); | ||
9548 | break; | ||
9549 | case 3: | ||
9550 | printk(" %2.2X%2.2X%2.2X", | ||
9551 | (unsigned) s[i+(j*4)+1], | ||
9552 | (unsigned) s[i+(j*4)+2], | ||
9553 | (unsigned) s[i+(j*4)+3]); | ||
9554 | break; | ||
9555 | } | ||
9556 | |||
9557 | printk("\n"); | ||
9558 | } | ||
9559 | } | ||
9560 | #endif /* ADVANSYS_DEBUG */ | ||
9561 | |||
9562 | /* | ||
9563 | * --- Asc Library Functions | ||
9564 | */ | ||
9565 | |||
9566 | STATIC ushort __init | ||
9567 | AscGetEisaChipCfg( | ||
9568 | PortAddr iop_base) | ||
9569 | { | ||
9570 | PortAddr eisa_cfg_iop; | ||
9571 | |||
9572 | eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) | | ||
9573 | (PortAddr) (ASC_EISA_CFG_IOP_MASK); | ||
9574 | return (inpw(eisa_cfg_iop)); | ||
9575 | } | ||
9576 | |||
9577 | STATIC uchar __init | ||
9578 | AscSetChipScsiID( | ||
9579 | PortAddr iop_base, | ||
9580 | uchar new_host_id | ||
9581 | ) | ||
9582 | { | ||
9583 | ushort cfg_lsw; | ||
9584 | |||
9585 | if (AscGetChipScsiID(iop_base) == new_host_id) { | ||
9586 | return (new_host_id); | ||
9587 | } | ||
9588 | cfg_lsw = AscGetChipCfgLsw(iop_base); | ||
9589 | cfg_lsw &= 0xF8FF; | ||
9590 | cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8); | ||
9591 | AscSetChipCfgLsw(iop_base, cfg_lsw); | ||
9592 | return (AscGetChipScsiID(iop_base)); | ||
9593 | } | ||
9594 | |||
9595 | STATIC uchar __init | ||
9596 | AscGetChipScsiCtrl( | ||
9597 | PortAddr iop_base) | ||
9598 | { | ||
9599 | uchar sc; | ||
9600 | |||
9601 | AscSetBank(iop_base, 1); | ||
9602 | sc = inp(iop_base + IOP_REG_SC); | ||
9603 | AscSetBank(iop_base, 0); | ||
9604 | return (sc); | ||
9605 | } | ||
9606 | |||
9607 | STATIC uchar __init | ||
9608 | AscGetChipVersion( | ||
9609 | PortAddr iop_base, | ||
9610 | ushort bus_type | ||
9611 | ) | ||
9612 | { | ||
9613 | if ((bus_type & ASC_IS_EISA) != 0) { | ||
9614 | PortAddr eisa_iop; | ||
9615 | uchar revision; | ||
9616 | eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) | | ||
9617 | (PortAddr) ASC_EISA_REV_IOP_MASK; | ||
9618 | revision = inp(eisa_iop); | ||
9619 | return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision)); | ||
9620 | } | ||
9621 | return (AscGetChipVerNo(iop_base)); | ||
9622 | } | ||
9623 | |||
9624 | STATIC ushort __init | ||
9625 | AscGetChipBusType( | ||
9626 | PortAddr iop_base) | ||
9627 | { | ||
9628 | ushort chip_ver; | ||
9629 | |||
9630 | chip_ver = AscGetChipVerNo(iop_base); | ||
9631 | if ( | ||
9632 | (chip_ver >= ASC_CHIP_MIN_VER_VL) | ||
9633 | && (chip_ver <= ASC_CHIP_MAX_VER_VL) | ||
9634 | ) { | ||
9635 | if ( | ||
9636 | ((iop_base & 0x0C30) == 0x0C30) | ||
9637 | || ((iop_base & 0x0C50) == 0x0C50) | ||
9638 | ) { | ||
9639 | return (ASC_IS_EISA); | ||
9640 | } | ||
9641 | return (ASC_IS_VL); | ||
9642 | } | ||
9643 | if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) && | ||
9644 | (chip_ver <= ASC_CHIP_MAX_VER_ISA)) { | ||
9645 | if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) { | ||
9646 | return (ASC_IS_ISAPNP); | ||
9647 | } | ||
9648 | return (ASC_IS_ISA); | ||
9649 | } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) && | ||
9650 | (chip_ver <= ASC_CHIP_MAX_VER_PCI)) { | ||
9651 | return (ASC_IS_PCI); | ||
9652 | } | ||
9653 | return (0); | ||
9654 | } | ||
9655 | |||
9656 | STATIC ASC_DCNT | ||
9657 | AscLoadMicroCode( | ||
9658 | PortAddr iop_base, | ||
9659 | ushort s_addr, | ||
9660 | uchar *mcode_buf, | ||
9661 | ushort mcode_size | ||
9662 | ) | ||
9663 | { | ||
9664 | ASC_DCNT chksum; | ||
9665 | ushort mcode_word_size; | ||
9666 | ushort mcode_chksum; | ||
9667 | |||
9668 | /* Write the microcode buffer starting at LRAM address 0. */ | ||
9669 | mcode_word_size = (ushort) (mcode_size >> 1); | ||
9670 | AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size); | ||
9671 | AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size); | ||
9672 | |||
9673 | chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size); | ||
9674 | ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong) chksum); | ||
9675 | mcode_chksum = (ushort) AscMemSumLramWord(iop_base, | ||
9676 | (ushort) ASC_CODE_SEC_BEG, | ||
9677 | (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2)); | ||
9678 | ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n", | ||
9679 | (ulong) mcode_chksum); | ||
9680 | AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum); | ||
9681 | AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size); | ||
9682 | return (chksum); | ||
9683 | } | ||
9684 | |||
9685 | STATIC int | ||
9686 | AscFindSignature( | ||
9687 | PortAddr iop_base | ||
9688 | ) | ||
9689 | { | ||
9690 | ushort sig_word; | ||
9691 | |||
9692 | ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n", | ||
9693 | iop_base, AscGetChipSignatureByte(iop_base)); | ||
9694 | if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) { | ||
9695 | ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n", | ||
9696 | iop_base, AscGetChipSignatureWord(iop_base)); | ||
9697 | sig_word = AscGetChipSignatureWord(iop_base); | ||
9698 | if ((sig_word == (ushort) ASC_1000_ID0W) || | ||
9699 | (sig_word == (ushort) ASC_1000_ID0W_FIX)) { | ||
9700 | return (1); | ||
9701 | } | ||
9702 | } | ||
9703 | return (0); | ||
9704 | } | ||
9705 | |||
9706 | STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata = | ||
9707 | { | ||
9708 | 0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4, | ||
9709 | ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8 | ||
9710 | }; | ||
9711 | |||
9712 | #ifdef CONFIG_ISA | ||
9713 | STATIC uchar _isa_pnp_inited __initdata = 0; | ||
9714 | |||
9715 | STATIC PortAddr __init | ||
9716 | AscSearchIOPortAddr( | ||
9717 | PortAddr iop_beg, | ||
9718 | ushort bus_type) | ||
9719 | { | ||
9720 | if (bus_type & ASC_IS_VL) { | ||
9721 | while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) { | ||
9722 | if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) { | ||
9723 | return (iop_beg); | ||
9724 | } | ||
9725 | } | ||
9726 | return (0); | ||
9727 | } | ||
9728 | if (bus_type & ASC_IS_ISA) { | ||
9729 | if (_isa_pnp_inited == 0) { | ||
9730 | AscSetISAPNPWaitForKey(); | ||
9731 | _isa_pnp_inited++; | ||
9732 | } | ||
9733 | while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) { | ||
9734 | if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) { | ||
9735 | return (iop_beg); | ||
9736 | } | ||
9737 | } | ||
9738 | return (0); | ||
9739 | } | ||
9740 | if (bus_type & ASC_IS_EISA) { | ||
9741 | if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) { | ||
9742 | return (iop_beg); | ||
9743 | } | ||
9744 | return (0); | ||
9745 | } | ||
9746 | return (0); | ||
9747 | } | ||
9748 | |||
9749 | STATIC PortAddr __init | ||
9750 | AscSearchIOPortAddr11( | ||
9751 | PortAddr s_addr | ||
9752 | ) | ||
9753 | { | ||
9754 | int i; | ||
9755 | PortAddr iop_base; | ||
9756 | |||
9757 | for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) { | ||
9758 | if (_asc_def_iop_base[i] > s_addr) { | ||
9759 | break; | ||
9760 | } | ||
9761 | } | ||
9762 | for (; i < ASC_IOADR_TABLE_MAX_IX; i++) { | ||
9763 | iop_base = _asc_def_iop_base[i]; | ||
9764 | if (check_region(iop_base, ASC_IOADR_GAP) != 0) { | ||
9765 | ASC_DBG1(1, | ||
9766 | "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n", | ||
9767 | iop_base); | ||
9768 | continue; | ||
9769 | } | ||
9770 | ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n", iop_base); | ||
9771 | if (AscFindSignature(iop_base)) { | ||
9772 | return (iop_base); | ||
9773 | } | ||
9774 | } | ||
9775 | return (0); | ||
9776 | } | ||
9777 | |||
9778 | STATIC void __init | ||
9779 | AscSetISAPNPWaitForKey(void) | ||
9780 | { | ||
9781 | outp(ASC_ISA_PNP_PORT_ADDR, 0x02); | ||
9782 | outp(ASC_ISA_PNP_PORT_WRITE, 0x02); | ||
9783 | return; | ||
9784 | } | ||
9785 | #endif /* CONFIG_ISA */ | ||
9786 | |||
9787 | STATIC void __init | ||
9788 | AscToggleIRQAct( | ||
9789 | PortAddr iop_base | ||
9790 | ) | ||
9791 | { | ||
9792 | AscSetChipStatus(iop_base, CIW_IRQ_ACT); | ||
9793 | AscSetChipStatus(iop_base, 0); | ||
9794 | return; | ||
9795 | } | ||
9796 | |||
9797 | STATIC uchar __init | ||
9798 | AscGetChipIRQ( | ||
9799 | PortAddr iop_base, | ||
9800 | ushort bus_type) | ||
9801 | { | ||
9802 | ushort cfg_lsw; | ||
9803 | uchar chip_irq; | ||
9804 | |||
9805 | if ((bus_type & ASC_IS_EISA) != 0) { | ||
9806 | cfg_lsw = AscGetEisaChipCfg(iop_base); | ||
9807 | chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10); | ||
9808 | if ((chip_irq == 13) || (chip_irq > 15)) { | ||
9809 | return (0); | ||
9810 | } | ||
9811 | return (chip_irq); | ||
9812 | } | ||
9813 | if ((bus_type & ASC_IS_VL) != 0) { | ||
9814 | cfg_lsw = AscGetChipCfgLsw(iop_base); | ||
9815 | chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07)); | ||
9816 | if ((chip_irq == 0) || | ||
9817 | (chip_irq == 4) || | ||
9818 | (chip_irq == 7)) { | ||
9819 | return (0); | ||
9820 | } | ||
9821 | return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1))); | ||
9822 | } | ||
9823 | cfg_lsw = AscGetChipCfgLsw(iop_base); | ||
9824 | chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03)); | ||
9825 | if (chip_irq == 3) | ||
9826 | chip_irq += (uchar) 2; | ||
9827 | return ((uchar) (chip_irq + ASC_MIN_IRQ_NO)); | ||
9828 | } | ||
9829 | |||
9830 | STATIC uchar __init | ||
9831 | AscSetChipIRQ( | ||
9832 | PortAddr iop_base, | ||
9833 | uchar irq_no, | ||
9834 | ushort bus_type) | ||
9835 | { | ||
9836 | ushort cfg_lsw; | ||
9837 | |||
9838 | if ((bus_type & ASC_IS_VL) != 0) { | ||
9839 | if (irq_no != 0) { | ||
9840 | if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) { | ||
9841 | irq_no = 0; | ||
9842 | } else { | ||
9843 | irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1)); | ||
9844 | } | ||
9845 | } | ||
9846 | cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3); | ||
9847 | cfg_lsw |= (ushort) 0x0010; | ||
9848 | AscSetChipCfgLsw(iop_base, cfg_lsw); | ||
9849 | AscToggleIRQAct(iop_base); | ||
9850 | cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0); | ||
9851 | cfg_lsw |= (ushort) ((irq_no & 0x07) << 2); | ||
9852 | AscSetChipCfgLsw(iop_base, cfg_lsw); | ||
9853 | AscToggleIRQAct(iop_base); | ||
9854 | return (AscGetChipIRQ(iop_base, bus_type)); | ||
9855 | } | ||
9856 | if ((bus_type & (ASC_IS_ISA)) != 0) { | ||
9857 | if (irq_no == 15) | ||
9858 | irq_no -= (uchar) 2; | ||
9859 | irq_no -= (uchar) ASC_MIN_IRQ_NO; | ||
9860 | cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3); | ||
9861 | cfg_lsw |= (ushort) ((irq_no & 0x03) << 2); | ||
9862 | AscSetChipCfgLsw(iop_base, cfg_lsw); | ||
9863 | return (AscGetChipIRQ(iop_base, bus_type)); | ||
9864 | } | ||
9865 | return (0); | ||
9866 | } | ||
9867 | |||
9868 | #ifdef CONFIG_ISA | ||
9869 | STATIC void __init | ||
9870 | AscEnableIsaDma( | ||
9871 | uchar dma_channel) | ||
9872 | { | ||
9873 | if (dma_channel < 4) { | ||
9874 | outp(0x000B, (ushort) (0xC0 | dma_channel)); | ||
9875 | outp(0x000A, dma_channel); | ||
9876 | } else if (dma_channel < 8) { | ||
9877 | outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4))); | ||
9878 | outp(0x00D4, (ushort) (dma_channel - 4)); | ||
9879 | } | ||
9880 | return; | ||
9881 | } | ||
9882 | #endif /* CONFIG_ISA */ | ||
9883 | |||
9884 | STATIC int | ||
9885 | AscIsrChipHalted( | ||
9886 | ASC_DVC_VAR *asc_dvc | ||
9887 | ) | ||
9888 | { | ||
9889 | EXT_MSG ext_msg; | ||
9890 | EXT_MSG out_msg; | ||
9891 | ushort halt_q_addr; | ||
9892 | int sdtr_accept; | ||
9893 | ushort int_halt_code; | ||
9894 | ASC_SCSI_BIT_ID_TYPE scsi_busy; | ||
9895 | ASC_SCSI_BIT_ID_TYPE target_id; | ||
9896 | PortAddr iop_base; | ||
9897 | uchar tag_code; | ||
9898 | uchar q_status; | ||
9899 | uchar halt_qp; | ||
9900 | uchar sdtr_data; | ||
9901 | uchar target_ix; | ||
9902 | uchar q_cntl, tid_no; | ||
9903 | uchar cur_dvc_qng; | ||
9904 | uchar asyn_sdtr; | ||
9905 | uchar scsi_status; | ||
9906 | asc_board_t *boardp; | ||
9907 | |||
9908 | ASC_ASSERT(asc_dvc->drv_ptr != NULL); | ||
9909 | boardp = asc_dvc->drv_ptr; | ||
9910 | |||
9911 | iop_base = asc_dvc->iop_base; | ||
9912 | int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W); | ||
9913 | |||
9914 | halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B); | ||
9915 | halt_q_addr = ASC_QNO_TO_QADDR(halt_qp); | ||
9916 | target_ix = AscReadLramByte(iop_base, | ||
9917 | (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX)); | ||
9918 | q_cntl = AscReadLramByte(iop_base, | ||
9919 | (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL)); | ||
9920 | tid_no = ASC_TIX_TO_TID(target_ix); | ||
9921 | target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no); | ||
9922 | if (asc_dvc->pci_fix_asyn_xfer & target_id) { | ||
9923 | asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB; | ||
9924 | } else { | ||
9925 | asyn_sdtr = 0; | ||
9926 | } | ||
9927 | if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) { | ||
9928 | if (asc_dvc->pci_fix_asyn_xfer & target_id) { | ||
9929 | AscSetChipSDTR(iop_base, 0, tid_no); | ||
9930 | boardp->sdtr_data[tid_no] = 0; | ||
9931 | } | ||
9932 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); | ||
9933 | return (0); | ||
9934 | } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) { | ||
9935 | if (asc_dvc->pci_fix_asyn_xfer & target_id) { | ||
9936 | AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); | ||
9937 | boardp->sdtr_data[tid_no] = asyn_sdtr; | ||
9938 | } | ||
9939 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); | ||
9940 | return (0); | ||
9941 | } else if (int_halt_code == ASC_HALT_EXTMSG_IN) { | ||
9942 | |||
9943 | AscMemWordCopyPtrFromLram(iop_base, | ||
9944 | ASCV_MSGIN_BEG, | ||
9945 | (uchar *) &ext_msg, | ||
9946 | sizeof(EXT_MSG) >> 1); | ||
9947 | |||
9948 | if (ext_msg.msg_type == MS_EXTEND && | ||
9949 | ext_msg.msg_req == MS_SDTR_CODE && | ||
9950 | ext_msg.msg_len == MS_SDTR_LEN) { | ||
9951 | sdtr_accept = TRUE; | ||
9952 | if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) { | ||
9953 | |||
9954 | sdtr_accept = FALSE; | ||
9955 | ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET; | ||
9956 | } | ||
9957 | if ((ext_msg.xfer_period < | ||
9958 | asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) || | ||
9959 | (ext_msg.xfer_period > | ||
9960 | asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) { | ||
9961 | sdtr_accept = FALSE; | ||
9962 | ext_msg.xfer_period = | ||
9963 | asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]; | ||
9964 | } | ||
9965 | if (sdtr_accept) { | ||
9966 | sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period, | ||
9967 | ext_msg.req_ack_offset); | ||
9968 | if ((sdtr_data == 0xFF)) { | ||
9969 | |||
9970 | q_cntl |= QC_MSG_OUT; | ||
9971 | asc_dvc->init_sdtr &= ~target_id; | ||
9972 | asc_dvc->sdtr_done &= ~target_id; | ||
9973 | AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); | ||
9974 | boardp->sdtr_data[tid_no] = asyn_sdtr; | ||
9975 | } | ||
9976 | } | ||
9977 | if (ext_msg.req_ack_offset == 0) { | ||
9978 | |||
9979 | q_cntl &= ~QC_MSG_OUT; | ||
9980 | asc_dvc->init_sdtr &= ~target_id; | ||
9981 | asc_dvc->sdtr_done &= ~target_id; | ||
9982 | AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); | ||
9983 | } else { | ||
9984 | if (sdtr_accept && (q_cntl & QC_MSG_OUT)) { | ||
9985 | |||
9986 | q_cntl &= ~QC_MSG_OUT; | ||
9987 | asc_dvc->sdtr_done |= target_id; | ||
9988 | asc_dvc->init_sdtr |= target_id; | ||
9989 | asc_dvc->pci_fix_asyn_xfer &= ~target_id; | ||
9990 | sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period, | ||
9991 | ext_msg.req_ack_offset); | ||
9992 | AscSetChipSDTR(iop_base, sdtr_data, tid_no); | ||
9993 | boardp->sdtr_data[tid_no] = sdtr_data; | ||
9994 | } else { | ||
9995 | |||
9996 | q_cntl |= QC_MSG_OUT; | ||
9997 | AscMsgOutSDTR(asc_dvc, | ||
9998 | ext_msg.xfer_period, | ||
9999 | ext_msg.req_ack_offset); | ||
10000 | asc_dvc->pci_fix_asyn_xfer &= ~target_id; | ||
10001 | sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period, | ||
10002 | ext_msg.req_ack_offset); | ||
10003 | AscSetChipSDTR(iop_base, sdtr_data, tid_no); | ||
10004 | boardp->sdtr_data[tid_no] = sdtr_data; | ||
10005 | asc_dvc->sdtr_done |= target_id; | ||
10006 | asc_dvc->init_sdtr |= target_id; | ||
10007 | } | ||
10008 | } | ||
10009 | |||
10010 | AscWriteLramByte(iop_base, | ||
10011 | (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL), | ||
10012 | q_cntl); | ||
10013 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); | ||
10014 | return (0); | ||
10015 | } else if (ext_msg.msg_type == MS_EXTEND && | ||
10016 | ext_msg.msg_req == MS_WDTR_CODE && | ||
10017 | ext_msg.msg_len == MS_WDTR_LEN) { | ||
10018 | |||
10019 | ext_msg.wdtr_width = 0; | ||
10020 | AscMemWordCopyPtrToLram(iop_base, | ||
10021 | ASCV_MSGOUT_BEG, | ||
10022 | (uchar *) &ext_msg, | ||
10023 | sizeof(EXT_MSG) >> 1); | ||
10024 | q_cntl |= QC_MSG_OUT; | ||
10025 | AscWriteLramByte(iop_base, | ||
10026 | (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL), | ||
10027 | q_cntl); | ||
10028 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); | ||
10029 | return (0); | ||
10030 | } else { | ||
10031 | |||
10032 | ext_msg.msg_type = MESSAGE_REJECT; | ||
10033 | AscMemWordCopyPtrToLram(iop_base, | ||
10034 | ASCV_MSGOUT_BEG, | ||
10035 | (uchar *) &ext_msg, | ||
10036 | sizeof(EXT_MSG) >> 1); | ||
10037 | q_cntl |= QC_MSG_OUT; | ||
10038 | AscWriteLramByte(iop_base, | ||
10039 | (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL), | ||
10040 | q_cntl); | ||
10041 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); | ||
10042 | return (0); | ||
10043 | } | ||
10044 | } else if (int_halt_code == ASC_HALT_CHK_CONDITION) { | ||
10045 | |||
10046 | q_cntl |= QC_REQ_SENSE; | ||
10047 | |||
10048 | if ((asc_dvc->init_sdtr & target_id) != 0) { | ||
10049 | |||
10050 | asc_dvc->sdtr_done &= ~target_id; | ||
10051 | |||
10052 | sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no); | ||
10053 | q_cntl |= QC_MSG_OUT; | ||
10054 | AscMsgOutSDTR(asc_dvc, | ||
10055 | asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) & | ||
10056 | (uchar) (asc_dvc->max_sdtr_index - 1)], | ||
10057 | (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET)); | ||
10058 | } | ||
10059 | |||
10060 | AscWriteLramByte(iop_base, | ||
10061 | (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL), | ||
10062 | q_cntl); | ||
10063 | |||
10064 | tag_code = AscReadLramByte(iop_base, | ||
10065 | (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE)); | ||
10066 | tag_code &= 0xDC; | ||
10067 | if ( | ||
10068 | (asc_dvc->pci_fix_asyn_xfer & target_id) | ||
10069 | && !(asc_dvc->pci_fix_asyn_xfer_always & target_id) | ||
10070 | ) { | ||
10071 | |||
10072 | tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT | ||
10073 | | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX); | ||
10074 | |||
10075 | } | ||
10076 | AscWriteLramByte(iop_base, | ||
10077 | (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE), | ||
10078 | tag_code); | ||
10079 | |||
10080 | q_status = AscReadLramByte(iop_base, | ||
10081 | (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS)); | ||
10082 | q_status |= (QS_READY | QS_BUSY); | ||
10083 | AscWriteLramByte(iop_base, | ||
10084 | (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS), | ||
10085 | q_status); | ||
10086 | |||
10087 | scsi_busy = AscReadLramByte(iop_base, | ||
10088 | (ushort) ASCV_SCSIBUSY_B); | ||
10089 | scsi_busy &= ~target_id; | ||
10090 | AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy); | ||
10091 | |||
10092 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); | ||
10093 | return (0); | ||
10094 | } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) { | ||
10095 | |||
10096 | AscMemWordCopyPtrFromLram(iop_base, | ||
10097 | ASCV_MSGOUT_BEG, | ||
10098 | (uchar *) &out_msg, | ||
10099 | sizeof(EXT_MSG) >> 1); | ||
10100 | |||
10101 | if ((out_msg.msg_type == MS_EXTEND) && | ||
10102 | (out_msg.msg_len == MS_SDTR_LEN) && | ||
10103 | (out_msg.msg_req == MS_SDTR_CODE)) { | ||
10104 | |||
10105 | asc_dvc->init_sdtr &= ~target_id; | ||
10106 | asc_dvc->sdtr_done &= ~target_id; | ||
10107 | AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); | ||
10108 | boardp->sdtr_data[tid_no] = asyn_sdtr; | ||
10109 | } | ||
10110 | q_cntl &= ~QC_MSG_OUT; | ||
10111 | AscWriteLramByte(iop_base, | ||
10112 | (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL), | ||
10113 | q_cntl); | ||
10114 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); | ||
10115 | return (0); | ||
10116 | } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) { | ||
10117 | |||
10118 | scsi_status = AscReadLramByte(iop_base, | ||
10119 | (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS)); | ||
10120 | cur_dvc_qng = AscReadLramByte(iop_base, | ||
10121 | (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix)); | ||
10122 | if ((cur_dvc_qng > 0) && | ||
10123 | (asc_dvc->cur_dvc_qng[tid_no] > 0)) { | ||
10124 | |||
10125 | scsi_busy = AscReadLramByte(iop_base, | ||
10126 | (ushort) ASCV_SCSIBUSY_B); | ||
10127 | scsi_busy |= target_id; | ||
10128 | AscWriteLramByte(iop_base, | ||
10129 | (ushort) ASCV_SCSIBUSY_B, scsi_busy); | ||
10130 | asc_dvc->queue_full_or_busy |= target_id; | ||
10131 | |||
10132 | if (scsi_status == SAM_STAT_TASK_SET_FULL) { | ||
10133 | if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) { | ||
10134 | cur_dvc_qng -= 1; | ||
10135 | asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng; | ||
10136 | |||
10137 | AscWriteLramByte(iop_base, | ||
10138 | (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG + | ||
10139 | (ushort) tid_no), | ||
10140 | cur_dvc_qng); | ||
10141 | |||
10142 | /* | ||
10143 | * Set the device queue depth to the number of | ||
10144 | * active requests when the QUEUE FULL condition | ||
10145 | * was encountered. | ||
10146 | */ | ||
10147 | boardp->queue_full |= target_id; | ||
10148 | boardp->queue_full_cnt[tid_no] = cur_dvc_qng; | ||
10149 | } | ||
10150 | } | ||
10151 | } | ||
10152 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); | ||
10153 | return (0); | ||
10154 | } | ||
10155 | #if CC_VERY_LONG_SG_LIST | ||
10156 | else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) | ||
10157 | { | ||
10158 | uchar q_no; | ||
10159 | ushort q_addr; | ||
10160 | uchar sg_wk_q_no; | ||
10161 | uchar first_sg_wk_q_no; | ||
10162 | ASC_SCSI_Q *scsiq; /* Ptr to driver request. */ | ||
10163 | ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */ | ||
10164 | ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */ | ||
10165 | ushort sg_list_dwords; | ||
10166 | ushort sg_entry_cnt; | ||
10167 | uchar next_qp; | ||
10168 | int i; | ||
10169 | |||
10170 | q_no = AscReadLramByte(iop_base, (ushort) ASCV_REQ_SG_LIST_QP); | ||
10171 | if (q_no == ASC_QLINK_END) | ||
10172 | { | ||
10173 | return(0); | ||
10174 | } | ||
10175 | |||
10176 | q_addr = ASC_QNO_TO_QADDR(q_no); | ||
10177 | |||
10178 | /* | ||
10179 | * Convert the request's SRB pointer to a host ASC_SCSI_REQ | ||
10180 | * structure pointer using a macro provided by the driver. | ||
10181 | * The ASC_SCSI_REQ pointer provides a pointer to the | ||
10182 | * host ASC_SG_HEAD structure. | ||
10183 | */ | ||
10184 | /* Read request's SRB pointer. */ | ||
10185 | scsiq = (ASC_SCSI_Q *) | ||
10186 | ASC_SRB2SCSIQ( | ||
10187 | ASC_U32_TO_VADDR(AscReadLramDWord(iop_base, | ||
10188 | (ushort) (q_addr + ASC_SCSIQ_D_SRBPTR)))); | ||
10189 | |||
10190 | /* | ||
10191 | * Get request's first and working SG queue. | ||
10192 | */ | ||
10193 | sg_wk_q_no = AscReadLramByte(iop_base, | ||
10194 | (ushort) (q_addr + ASC_SCSIQ_B_SG_WK_QP)); | ||
10195 | |||
10196 | first_sg_wk_q_no = AscReadLramByte(iop_base, | ||
10197 | (ushort) (q_addr + ASC_SCSIQ_B_FIRST_SG_WK_QP)); | ||
10198 | |||
10199 | /* | ||
10200 | * Reset request's working SG queue back to the | ||
10201 | * first SG queue. | ||
10202 | */ | ||
10203 | AscWriteLramByte(iop_base, | ||
10204 | (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SG_WK_QP), | ||
10205 | first_sg_wk_q_no); | ||
10206 | |||
10207 | sg_head = scsiq->sg_head; | ||
10208 | |||
10209 | /* | ||
10210 | * Set sg_entry_cnt to the number of SG elements | ||
10211 | * that will be completed on this interrupt. | ||
10212 | * | ||
10213 | * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1 | ||
10214 | * SG elements. The data_cnt and data_addr fields which | ||
10215 | * add 1 to the SG element capacity are not used when | ||
10216 | * restarting SG handling after a halt. | ||
10217 | */ | ||
10218 | if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) | ||
10219 | { | ||
10220 | sg_entry_cnt = ASC_MAX_SG_LIST - 1; | ||
10221 | |||
10222 | /* | ||
10223 | * Keep track of remaining number of SG elements that will | ||
10224 | * need to be handled on the next interrupt. | ||
10225 | */ | ||
10226 | scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1); | ||
10227 | } else | ||
10228 | { | ||
10229 | sg_entry_cnt = scsiq->remain_sg_entry_cnt; | ||
10230 | scsiq->remain_sg_entry_cnt = 0; | ||
10231 | } | ||
10232 | |||
10233 | /* | ||
10234 | * Copy SG elements into the list of allocated SG queues. | ||
10235 | * | ||
10236 | * Last index completed is saved in scsiq->next_sg_index. | ||
10237 | */ | ||
10238 | next_qp = first_sg_wk_q_no; | ||
10239 | q_addr = ASC_QNO_TO_QADDR(next_qp); | ||
10240 | scsi_sg_q.sg_head_qp = q_no; | ||
10241 | scsi_sg_q.cntl = QCSG_SG_XFER_LIST; | ||
10242 | for( i = 0; i < sg_head->queue_cnt; i++) | ||
10243 | { | ||
10244 | scsi_sg_q.seq_no = i + 1; | ||
10245 | if (sg_entry_cnt > ASC_SG_LIST_PER_Q) | ||
10246 | { | ||
10247 | sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2); | ||
10248 | sg_entry_cnt -= ASC_SG_LIST_PER_Q; | ||
10249 | /* | ||
10250 | * After very first SG queue RISC FW uses next | ||
10251 | * SG queue first element then checks sg_list_cnt | ||
10252 | * against zero and then decrements, so set | ||
10253 | * sg_list_cnt 1 less than number of SG elements | ||
10254 | * in each SG queue. | ||
10255 | */ | ||
10256 | scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1; | ||
10257 | scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1; | ||
10258 | } else { | ||
10259 | /* | ||
10260 | * This is the last SG queue in the list of | ||
10261 | * allocated SG queues. If there are more | ||
10262 | * SG elements than will fit in the allocated | ||
10263 | * queues, then set the QCSG_SG_XFER_MORE flag. | ||
10264 | */ | ||
10265 | if (scsiq->remain_sg_entry_cnt != 0) | ||
10266 | { | ||
10267 | scsi_sg_q.cntl |= QCSG_SG_XFER_MORE; | ||
10268 | } else | ||
10269 | { | ||
10270 | scsi_sg_q.cntl |= QCSG_SG_XFER_END; | ||
10271 | } | ||
10272 | /* equals sg_entry_cnt * 2 */ | ||
10273 | sg_list_dwords = sg_entry_cnt << 1; | ||
10274 | scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1; | ||
10275 | scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1; | ||
10276 | sg_entry_cnt = 0; | ||
10277 | } | ||
10278 | |||
10279 | scsi_sg_q.q_no = next_qp; | ||
10280 | AscMemWordCopyPtrToLram(iop_base, | ||
10281 | q_addr + ASC_SCSIQ_SGHD_CPY_BEG, | ||
10282 | (uchar *) &scsi_sg_q, | ||
10283 | sizeof(ASC_SG_LIST_Q) >> 1); | ||
10284 | |||
10285 | AscMemDWordCopyPtrToLram(iop_base, | ||
10286 | q_addr + ASC_SGQ_LIST_BEG, | ||
10287 | (uchar *) &sg_head->sg_list[scsiq->next_sg_index], | ||
10288 | sg_list_dwords); | ||
10289 | |||
10290 | scsiq->next_sg_index += ASC_SG_LIST_PER_Q; | ||
10291 | |||
10292 | /* | ||
10293 | * If the just completed SG queue contained the | ||
10294 | * last SG element, then no more SG queues need | ||
10295 | * to be written. | ||
10296 | */ | ||
10297 | if (scsi_sg_q.cntl & QCSG_SG_XFER_END) | ||
10298 | { | ||
10299 | break; | ||
10300 | } | ||
10301 | |||
10302 | next_qp = AscReadLramByte( iop_base, | ||
10303 | ( ushort )( q_addr+ASC_SCSIQ_B_FWD ) ); | ||
10304 | q_addr = ASC_QNO_TO_QADDR( next_qp ); | ||
10305 | } | ||
10306 | |||
10307 | /* | ||
10308 | * Clear the halt condition so the RISC will be restarted | ||
10309 | * after the return. | ||
10310 | */ | ||
10311 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); | ||
10312 | return(0); | ||
10313 | } | ||
10314 | #endif /* CC_VERY_LONG_SG_LIST */ | ||
10315 | return (0); | ||
10316 | } | ||
10317 | |||
10318 | STATIC uchar | ||
10319 | _AscCopyLramScsiDoneQ( | ||
10320 | PortAddr iop_base, | ||
10321 | ushort q_addr, | ||
10322 | ASC_QDONE_INFO * scsiq, | ||
10323 | ASC_DCNT max_dma_count | ||
10324 | ) | ||
10325 | { | ||
10326 | ushort _val; | ||
10327 | uchar sg_queue_cnt; | ||
10328 | |||
10329 | DvcGetQinfo(iop_base, | ||
10330 | q_addr + ASC_SCSIQ_DONE_INFO_BEG, | ||
10331 | (uchar *) scsiq, | ||
10332 | (sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2); | ||
10333 | |||
10334 | _val = AscReadLramWord(iop_base, | ||
10335 | (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS)); | ||
10336 | scsiq->q_status = (uchar) _val; | ||
10337 | scsiq->q_no = (uchar) (_val >> 8); | ||
10338 | _val = AscReadLramWord(iop_base, | ||
10339 | (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL)); | ||
10340 | scsiq->cntl = (uchar) _val; | ||
10341 | sg_queue_cnt = (uchar) (_val >> 8); | ||
10342 | _val = AscReadLramWord(iop_base, | ||
10343 | (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN)); | ||
10344 | scsiq->sense_len = (uchar) _val; | ||
10345 | scsiq->extra_bytes = (uchar) (_val >> 8); | ||
10346 | |||
10347 | /* | ||
10348 | * Read high word of remain bytes from alternate location. | ||
10349 | */ | ||
10350 | scsiq->remain_bytes = (((ADV_DCNT) AscReadLramWord( iop_base, | ||
10351 | (ushort) (q_addr+ (ushort) ASC_SCSIQ_W_ALT_DC1))) << 16); | ||
10352 | /* | ||
10353 | * Read low word of remain bytes from original location. | ||
10354 | */ | ||
10355 | scsiq->remain_bytes += AscReadLramWord(iop_base, | ||
10356 | (ushort) (q_addr+ (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT)); | ||
10357 | |||
10358 | scsiq->remain_bytes &= max_dma_count; | ||
10359 | return (sg_queue_cnt); | ||
10360 | } | ||
10361 | |||
10362 | STATIC int | ||
10363 | AscIsrQDone( | ||
10364 | ASC_DVC_VAR *asc_dvc | ||
10365 | ) | ||
10366 | { | ||
10367 | uchar next_qp; | ||
10368 | uchar n_q_used; | ||
10369 | uchar sg_list_qp; | ||
10370 | uchar sg_queue_cnt; | ||
10371 | uchar q_cnt; | ||
10372 | uchar done_q_tail; | ||
10373 | uchar tid_no; | ||
10374 | ASC_SCSI_BIT_ID_TYPE scsi_busy; | ||
10375 | ASC_SCSI_BIT_ID_TYPE target_id; | ||
10376 | PortAddr iop_base; | ||
10377 | ushort q_addr; | ||
10378 | ushort sg_q_addr; | ||
10379 | uchar cur_target_qng; | ||
10380 | ASC_QDONE_INFO scsiq_buf; | ||
10381 | ASC_QDONE_INFO *scsiq; | ||
10382 | int false_overrun; | ||
10383 | ASC_ISR_CALLBACK asc_isr_callback; | ||
10384 | |||
10385 | iop_base = asc_dvc->iop_base; | ||
10386 | asc_isr_callback = asc_dvc->isr_callback; | ||
10387 | n_q_used = 1; | ||
10388 | scsiq = (ASC_QDONE_INFO *) & scsiq_buf; | ||
10389 | done_q_tail = (uchar) AscGetVarDoneQTail(iop_base); | ||
10390 | q_addr = ASC_QNO_TO_QADDR(done_q_tail); | ||
10391 | next_qp = AscReadLramByte(iop_base, | ||
10392 | (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD)); | ||
10393 | if (next_qp != ASC_QLINK_END) { | ||
10394 | AscPutVarDoneQTail(iop_base, next_qp); | ||
10395 | q_addr = ASC_QNO_TO_QADDR(next_qp); | ||
10396 | sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, | ||
10397 | asc_dvc->max_dma_count); | ||
10398 | AscWriteLramByte(iop_base, | ||
10399 | (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS), | ||
10400 | (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED))); | ||
10401 | tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix); | ||
10402 | target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix); | ||
10403 | if ((scsiq->cntl & QC_SG_HEAD) != 0) { | ||
10404 | sg_q_addr = q_addr; | ||
10405 | sg_list_qp = next_qp; | ||
10406 | for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) { | ||
10407 | sg_list_qp = AscReadLramByte(iop_base, | ||
10408 | (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD)); | ||
10409 | sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp); | ||
10410 | if (sg_list_qp == ASC_QLINK_END) { | ||
10411 | AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS); | ||
10412 | scsiq->d3.done_stat = QD_WITH_ERROR; | ||
10413 | scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED; | ||
10414 | goto FATAL_ERR_QDONE; | ||
10415 | } | ||
10416 | AscWriteLramByte(iop_base, | ||
10417 | (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS), | ||
10418 | QS_FREE); | ||
10419 | } | ||
10420 | n_q_used = sg_queue_cnt + 1; | ||
10421 | AscPutVarDoneQTail(iop_base, sg_list_qp); | ||
10422 | } | ||
10423 | if (asc_dvc->queue_full_or_busy & target_id) { | ||
10424 | cur_target_qng = AscReadLramByte(iop_base, | ||
10425 | (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix)); | ||
10426 | if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) { | ||
10427 | scsi_busy = AscReadLramByte(iop_base, | ||
10428 | (ushort) ASCV_SCSIBUSY_B); | ||
10429 | scsi_busy &= ~target_id; | ||
10430 | AscWriteLramByte(iop_base, | ||
10431 | (ushort) ASCV_SCSIBUSY_B, scsi_busy); | ||
10432 | asc_dvc->queue_full_or_busy &= ~target_id; | ||
10433 | } | ||
10434 | } | ||
10435 | if (asc_dvc->cur_total_qng >= n_q_used) { | ||
10436 | asc_dvc->cur_total_qng -= n_q_used; | ||
10437 | if (asc_dvc->cur_dvc_qng[tid_no] != 0) { | ||
10438 | asc_dvc->cur_dvc_qng[tid_no]--; | ||
10439 | } | ||
10440 | } else { | ||
10441 | AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG); | ||
10442 | scsiq->d3.done_stat = QD_WITH_ERROR; | ||
10443 | goto FATAL_ERR_QDONE; | ||
10444 | } | ||
10445 | if ((scsiq->d2.srb_ptr == 0UL) || | ||
10446 | ((scsiq->q_status & QS_ABORTED) != 0)) { | ||
10447 | return (0x11); | ||
10448 | } else if (scsiq->q_status == QS_DONE) { | ||
10449 | false_overrun = FALSE; | ||
10450 | if (scsiq->extra_bytes != 0) { | ||
10451 | scsiq->remain_bytes += (ADV_DCNT) scsiq->extra_bytes; | ||
10452 | } | ||
10453 | if (scsiq->d3.done_stat == QD_WITH_ERROR) { | ||
10454 | if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN) { | ||
10455 | if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) { | ||
10456 | scsiq->d3.done_stat = QD_NO_ERROR; | ||
10457 | scsiq->d3.host_stat = QHSTA_NO_ERROR; | ||
10458 | } else if (false_overrun) { | ||
10459 | scsiq->d3.done_stat = QD_NO_ERROR; | ||
10460 | scsiq->d3.host_stat = QHSTA_NO_ERROR; | ||
10461 | } | ||
10462 | } else if (scsiq->d3.host_stat == | ||
10463 | QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) { | ||
10464 | AscStopChip(iop_base); | ||
10465 | AscSetChipControl(iop_base, | ||
10466 | (uchar) (CC_SCSI_RESET | CC_HALT)); | ||
10467 | DvcDelayNanoSecond(asc_dvc, 60000); | ||
10468 | AscSetChipControl(iop_base, CC_HALT); | ||
10469 | AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT); | ||
10470 | AscSetChipStatus(iop_base, 0); | ||
10471 | AscSetChipControl(iop_base, 0); | ||
10472 | } | ||
10473 | } | ||
10474 | if ((scsiq->cntl & QC_NO_CALLBACK) == 0) { | ||
10475 | (*asc_isr_callback) (asc_dvc, scsiq); | ||
10476 | } else { | ||
10477 | if ((AscReadLramByte(iop_base, | ||
10478 | (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) == | ||
10479 | START_STOP)) { | ||
10480 | asc_dvc->unit_not_ready &= ~target_id; | ||
10481 | if (scsiq->d3.done_stat != QD_NO_ERROR) { | ||
10482 | asc_dvc->start_motor &= ~target_id; | ||
10483 | } | ||
10484 | } | ||
10485 | } | ||
10486 | return (1); | ||
10487 | } else { | ||
10488 | AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS); | ||
10489 | FATAL_ERR_QDONE: | ||
10490 | if ((scsiq->cntl & QC_NO_CALLBACK) == 0) { | ||
10491 | (*asc_isr_callback) (asc_dvc, scsiq); | ||
10492 | } | ||
10493 | return (0x80); | ||
10494 | } | ||
10495 | } | ||
10496 | return (0); | ||
10497 | } | ||
10498 | |||
10499 | STATIC int | ||
10500 | AscISR( | ||
10501 | ASC_DVC_VAR *asc_dvc | ||
10502 | ) | ||
10503 | { | ||
10504 | ASC_CS_TYPE chipstat; | ||
10505 | PortAddr iop_base; | ||
10506 | ushort saved_ram_addr; | ||
10507 | uchar ctrl_reg; | ||
10508 | uchar saved_ctrl_reg; | ||
10509 | int int_pending; | ||
10510 | int status; | ||
10511 | uchar host_flag; | ||
10512 | |||
10513 | iop_base = asc_dvc->iop_base; | ||
10514 | int_pending = FALSE; | ||
10515 | |||
10516 | if (AscIsIntPending(iop_base) == 0) | ||
10517 | { | ||
10518 | return int_pending; | ||
10519 | } | ||
10520 | |||
10521 | if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) | ||
10522 | || (asc_dvc->isr_callback == 0) | ||
10523 | ) { | ||
10524 | return (ERR); | ||
10525 | } | ||
10526 | if (asc_dvc->in_critical_cnt != 0) { | ||
10527 | AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL); | ||
10528 | return (ERR); | ||
10529 | } | ||
10530 | if (asc_dvc->is_in_int) { | ||
10531 | AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY); | ||
10532 | return (ERR); | ||
10533 | } | ||
10534 | asc_dvc->is_in_int = TRUE; | ||
10535 | ctrl_reg = AscGetChipControl(iop_base); | ||
10536 | saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET | | ||
10537 | CC_SINGLE_STEP | CC_DIAG | CC_TEST)); | ||
10538 | chipstat = AscGetChipStatus(iop_base); | ||
10539 | if (chipstat & CSW_SCSI_RESET_LATCH) { | ||
10540 | if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) { | ||
10541 | int i = 10; | ||
10542 | int_pending = TRUE; | ||
10543 | asc_dvc->sdtr_done = 0; | ||
10544 | saved_ctrl_reg &= (uchar) (~CC_HALT); | ||
10545 | while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) && | ||
10546 | (i-- > 0)) | ||
10547 | { | ||
10548 | DvcSleepMilliSecond(100); | ||
10549 | } | ||
10550 | AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT)); | ||
10551 | AscSetChipControl(iop_base, CC_HALT); | ||
10552 | AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT); | ||
10553 | AscSetChipStatus(iop_base, 0); | ||
10554 | chipstat = AscGetChipStatus(iop_base); | ||
10555 | } | ||
10556 | } | ||
10557 | saved_ram_addr = AscGetChipLramAddr(iop_base); | ||
10558 | host_flag = AscReadLramByte(iop_base, | ||
10559 | ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR); | ||
10560 | AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, | ||
10561 | (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR)); | ||
10562 | if ((chipstat & CSW_INT_PENDING) | ||
10563 | || (int_pending) | ||
10564 | ) { | ||
10565 | AscAckInterrupt(iop_base); | ||
10566 | int_pending = TRUE; | ||
10567 | if ((chipstat & CSW_HALTED) && | ||
10568 | (ctrl_reg & CC_SINGLE_STEP)) { | ||
10569 | if (AscIsrChipHalted(asc_dvc) == ERR) { | ||
10570 | goto ISR_REPORT_QDONE_FATAL_ERROR; | ||
10571 | } else { | ||
10572 | saved_ctrl_reg &= (uchar) (~CC_HALT); | ||
10573 | } | ||
10574 | } else { | ||
10575 | ISR_REPORT_QDONE_FATAL_ERROR: | ||
10576 | if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) { | ||
10577 | while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) { | ||
10578 | } | ||
10579 | } else { | ||
10580 | do { | ||
10581 | if ((status = AscIsrQDone(asc_dvc)) == 1) { | ||
10582 | break; | ||
10583 | } | ||
10584 | } while (status == 0x11); | ||
10585 | } | ||
10586 | if ((status & 0x80) != 0) | ||
10587 | int_pending = ERR; | ||
10588 | } | ||
10589 | } | ||
10590 | AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag); | ||
10591 | AscSetChipLramAddr(iop_base, saved_ram_addr); | ||
10592 | AscSetChipControl(iop_base, saved_ctrl_reg); | ||
10593 | asc_dvc->is_in_int = FALSE; | ||
10594 | return (int_pending); | ||
10595 | } | ||
10596 | |||
10597 | /* Microcode buffer is kept after initialization for error recovery. */ | ||
10598 | STATIC uchar _asc_mcode_buf[] = | ||
10599 | { | ||
10600 | 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
10601 | 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
10602 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
10603 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
10604 | 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, | ||
10605 | 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
10606 | 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, | ||
10607 | 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, | ||
10608 | 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40, | ||
10609 | 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2, 0xC2, 0x00, 0x92, 0x80, | ||
10610 | 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, | ||
10611 | 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62, | ||
10612 | 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8, 0xCD, 0x04, 0x4D, 0x00, | ||
10613 | 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, | ||
10614 | 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88, | ||
10615 | 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00, 0x84, 0x97, 0x07, 0xA6, | ||
10616 | 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, | ||
10617 | 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6, | ||
10618 | 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6, 0x34, 0x01, 0x00, 0x33, | ||
10619 | 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, | ||
10620 | 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23, | ||
10621 | 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01, 0x00, 0x33, 0x0A, 0x00, | ||
10622 | 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, | ||
10623 | 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01, | ||
10624 | 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3, 0x3C, 0x01, 0x00, 0x05, | ||
10625 | 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, | ||
10626 | 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, | ||
10627 | 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00, 0xC2, 0x88, 0x06, 0x23, | ||
10628 | 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, | ||
10629 | 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61, | ||
10630 | 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC, 0x4F, 0x00, 0x84, 0x97, | ||
10631 | 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, | ||
10632 | 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29, | ||
10633 | 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88, 0x04, 0x98, 0xF0, 0x80, | ||
10634 | 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, | ||
10635 | 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95, | ||
10636 | 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02, 0x07, 0xA6, 0x5A, 0x02, | ||
10637 | 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, | ||
10638 | 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC, | ||
10639 | 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, 0x6F, 0x00, 0xA5, 0x01, | ||
10640 | 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, | ||
10641 | 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02, | ||
10642 | 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E, 0x80, 0x63, 0x00, 0x43, | ||
10643 | 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, | ||
10644 | 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82, | ||
10645 | 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8, 0x00, 0x33, 0x1F, 0x00, | ||
10646 | 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, | ||
10647 | 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6, | ||
10648 | 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xEE, 0x82, | ||
10649 | 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, | ||
10650 | 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98, | ||
10651 | 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6, 0x3C, 0x04, 0x06, 0xA6, | ||
10652 | 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, | ||
10653 | 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33, | ||
10654 | 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05, 0xFF, 0xA2, 0x7A, 0x03, | ||
10655 | 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, | ||
10656 | 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03, | ||
10657 | 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6, 0xA4, 0x03, 0x00, 0xA6, | ||
10658 | 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, | ||
10659 | 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42, | ||
10660 | 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95, 0xC0, 0x83, 0x00, 0x33, | ||
10661 | 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, | ||
10662 | 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, | ||
10663 | 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04, 0x06, 0xA6, 0x0A, 0x04, | ||
10664 | 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, | ||
10665 | 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63, | ||
10666 | 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6, 0x38, 0x04, 0x00, 0x33, | ||
10667 | 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, | ||
10668 | 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63, | ||
10669 | 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0xA3, 0x01, | ||
10670 | 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, | ||
10671 | 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00, | ||
10672 | 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04, 0x08, 0x23, 0x22, 0xA3, | ||
10673 | 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, | ||
10674 | 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98, | ||
10675 | 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, 0x81, 0x62, 0xE8, 0x81, | ||
10676 | 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, | ||
10677 | 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23, | ||
10678 | 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, 0xF4, 0x04, 0x00, 0x33, | ||
10679 | 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, | ||
10680 | 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05, | ||
10681 | 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85, 0x46, 0x97, 0xCD, 0x04, | ||
10682 | 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, | ||
10683 | 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6, | ||
10684 | 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x49, 0x00, 0x81, 0x01, | ||
10685 | 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, | ||
10686 | 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00, | ||
10687 | 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, 0x07, 0xA4, 0xF8, 0x05, | ||
10688 | 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, | ||
10689 | 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05, | ||
10690 | 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, 0x62, 0x97, 0x04, 0x85, | ||
10691 | 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, | ||
10692 | 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0, | ||
10693 | 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05, 0x80, 0x67, 0x80, 0x63, | ||
10694 | 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, | ||
10695 | 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00, | ||
10696 | 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23, 0x07, 0x41, 0x83, 0x03, | ||
10697 | 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, | ||
10698 | 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05, | ||
10699 | 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00, 0x52, 0x00, 0x06, 0x61, | ||
10700 | 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, | ||
10701 | 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63, | ||
10702 | 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23, 0xDF, 0x00, 0x06, 0xA6, | ||
10703 | 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, | ||
10704 | 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06, | ||
10705 | 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B, 0x40, 0x0E, 0x80, 0x63, | ||
10706 | 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, | ||
10707 | 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E, | ||
10708 | 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x07, 0xA6, 0xD6, 0x06, | ||
10709 | 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, | ||
10710 | 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E, | ||
10711 | 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20, 0x81, 0x62, 0x04, 0x01, | ||
10712 | 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, | ||
10713 | 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, | ||
10714 | 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88, 0x00, 0x00, 0x80, 0x67, | ||
10715 | 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, | ||
10716 | 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00, | ||
10717 | 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, 0x80, 0x05, 0x81, 0x05, | ||
10718 | 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, | ||
10719 | 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01, | ||
10720 | 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, 0xF1, 0x00, 0x70, 0x00, | ||
10721 | 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, | ||
10722 | 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01, | ||
10723 | 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, 0xC4, 0x07, 0x00, 0x33, | ||
10724 | 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, | ||
10725 | 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07, | ||
10726 | 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x05, 0x05, 0x00, 0x63, | ||
10727 | 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, | ||
10728 | 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0, | ||
10729 | 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, 0xF3, 0x04, | ||
10730 | 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, | ||
10731 | 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98, | ||
10732 | 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, 0x5A, 0x88, 0x02, 0x01, | ||
10733 | 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, | ||
10734 | 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08, | ||
10735 | 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x38, 0x2B, | ||
10736 | 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, | ||
10737 | 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36, | ||
10738 | 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, 0x40, 0x36, 0x40, 0x3A, | ||
10739 | 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, | ||
10740 | 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73, | ||
10741 | 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, 0xA1, 0x23, 0xA1, 0x01, | ||
10742 | 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, | ||
10743 | 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84, | ||
10744 | }; | ||
10745 | |||
10746 | STATIC ushort _asc_mcode_size = sizeof(_asc_mcode_buf); | ||
10747 | STATIC ADV_DCNT _asc_mcode_chksum = 0x012C453FUL; | ||
10748 | |||
10749 | #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16 | ||
10750 | STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = | ||
10751 | { | ||
10752 | INQUIRY, | ||
10753 | REQUEST_SENSE, | ||
10754 | READ_CAPACITY, | ||
10755 | READ_TOC, | ||
10756 | MODE_SELECT, | ||
10757 | MODE_SENSE, | ||
10758 | MODE_SELECT_10, | ||
10759 | MODE_SENSE_10, | ||
10760 | 0xFF, | ||
10761 | 0xFF, | ||
10762 | 0xFF, | ||
10763 | 0xFF, | ||
10764 | 0xFF, | ||
10765 | 0xFF, | ||
10766 | 0xFF, | ||
10767 | 0xFF | ||
10768 | }; | ||
10769 | |||
10770 | STATIC int | ||
10771 | AscExeScsiQueue( | ||
10772 | ASC_DVC_VAR *asc_dvc, | ||
10773 | ASC_SCSI_Q *scsiq | ||
10774 | ) | ||
10775 | { | ||
10776 | PortAddr iop_base; | ||
10777 | ulong last_int_level; | ||
10778 | int sta; | ||
10779 | int n_q_required; | ||
10780 | int disable_syn_offset_one_fix; | ||
10781 | int i; | ||
10782 | ASC_PADDR addr; | ||
10783 | ASC_EXE_CALLBACK asc_exe_callback; | ||
10784 | ushort sg_entry_cnt = 0; | ||
10785 | ushort sg_entry_cnt_minus_one = 0; | ||
10786 | uchar target_ix; | ||
10787 | uchar tid_no; | ||
10788 | uchar sdtr_data; | ||
10789 | uchar extra_bytes; | ||
10790 | uchar scsi_cmd; | ||
10791 | uchar disable_cmd; | ||
10792 | ASC_SG_HEAD *sg_head; | ||
10793 | ASC_DCNT data_cnt; | ||
10794 | |||
10795 | iop_base = asc_dvc->iop_base; | ||
10796 | sg_head = scsiq->sg_head; | ||
10797 | asc_exe_callback = asc_dvc->exe_callback; | ||
10798 | if (asc_dvc->err_code != 0) | ||
10799 | return (ERR); | ||
10800 | if (scsiq == (ASC_SCSI_Q *) 0L) { | ||
10801 | AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR); | ||
10802 | return (ERR); | ||
10803 | } | ||
10804 | scsiq->q1.q_no = 0; | ||
10805 | if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) { | ||
10806 | scsiq->q1.extra_bytes = 0; | ||
10807 | } | ||
10808 | sta = 0; | ||
10809 | target_ix = scsiq->q2.target_ix; | ||
10810 | tid_no = ASC_TIX_TO_TID(target_ix); | ||
10811 | n_q_required = 1; | ||
10812 | if (scsiq->cdbptr[0] == REQUEST_SENSE) { | ||
10813 | if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) { | ||
10814 | asc_dvc->sdtr_done &= ~scsiq->q1.target_id; | ||
10815 | sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no); | ||
10816 | AscMsgOutSDTR(asc_dvc, | ||
10817 | asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) & | ||
10818 | (uchar) (asc_dvc->max_sdtr_index - 1)], | ||
10819 | (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET)); | ||
10820 | scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT); | ||
10821 | } | ||
10822 | } | ||
10823 | last_int_level = DvcEnterCritical(); | ||
10824 | if (asc_dvc->in_critical_cnt != 0) { | ||
10825 | DvcLeaveCritical(last_int_level); | ||
10826 | AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY); | ||
10827 | return (ERR); | ||
10828 | } | ||
10829 | asc_dvc->in_critical_cnt++; | ||
10830 | if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) { | ||
10831 | if ((sg_entry_cnt = sg_head->entry_cnt) == 0) { | ||
10832 | asc_dvc->in_critical_cnt--; | ||
10833 | DvcLeaveCritical(last_int_level); | ||
10834 | return (ERR); | ||
10835 | } | ||
10836 | #if !CC_VERY_LONG_SG_LIST | ||
10837 | if (sg_entry_cnt > ASC_MAX_SG_LIST) | ||
10838 | { | ||
10839 | asc_dvc->in_critical_cnt--; | ||
10840 | DvcLeaveCritical(last_int_level); | ||
10841 | return(ERR); | ||
10842 | } | ||
10843 | #endif /* !CC_VERY_LONG_SG_LIST */ | ||
10844 | if (sg_entry_cnt == 1) { | ||
10845 | scsiq->q1.data_addr = (ADV_PADDR) sg_head->sg_list[0].addr; | ||
10846 | scsiq->q1.data_cnt = (ADV_DCNT) sg_head->sg_list[0].bytes; | ||
10847 | scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE); | ||
10848 | } | ||
10849 | sg_entry_cnt_minus_one = sg_entry_cnt - 1; | ||
10850 | } | ||
10851 | scsi_cmd = scsiq->cdbptr[0]; | ||
10852 | disable_syn_offset_one_fix = FALSE; | ||
10853 | if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) && | ||
10854 | !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) { | ||
10855 | if (scsiq->q1.cntl & QC_SG_HEAD) { | ||
10856 | data_cnt = 0; | ||
10857 | for (i = 0; i < sg_entry_cnt; i++) { | ||
10858 | data_cnt += (ADV_DCNT) le32_to_cpu(sg_head->sg_list[i].bytes); | ||
10859 | } | ||
10860 | } else { | ||
10861 | data_cnt = le32_to_cpu(scsiq->q1.data_cnt); | ||
10862 | } | ||
10863 | if (data_cnt != 0UL) { | ||
10864 | if (data_cnt < 512UL) { | ||
10865 | disable_syn_offset_one_fix = TRUE; | ||
10866 | } else { | ||
10867 | for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; i++) { | ||
10868 | disable_cmd = _syn_offset_one_disable_cmd[i]; | ||
10869 | if (disable_cmd == 0xFF) { | ||
10870 | break; | ||
10871 | } | ||
10872 | if (scsi_cmd == disable_cmd) { | ||
10873 | disable_syn_offset_one_fix = TRUE; | ||
10874 | break; | ||
10875 | } | ||
10876 | } | ||
10877 | } | ||
10878 | } | ||
10879 | } | ||
10880 | if (disable_syn_offset_one_fix) { | ||
10881 | scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG; | ||
10882 | scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX | | ||
10883 | ASC_TAG_FLAG_DISABLE_DISCONNECT); | ||
10884 | } else { | ||
10885 | scsiq->q2.tag_code &= 0x27; | ||
10886 | } | ||
10887 | if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) { | ||
10888 | if (asc_dvc->bug_fix_cntl) { | ||
10889 | if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) { | ||
10890 | if ((scsi_cmd == READ_6) || | ||
10891 | (scsi_cmd == READ_10)) { | ||
10892 | addr = | ||
10893 | (ADV_PADDR) le32_to_cpu( | ||
10894 | sg_head->sg_list[sg_entry_cnt_minus_one].addr) + | ||
10895 | (ADV_DCNT) le32_to_cpu( | ||
10896 | sg_head->sg_list[sg_entry_cnt_minus_one].bytes); | ||
10897 | extra_bytes = (uchar) ((ushort) addr & 0x0003); | ||
10898 | if ((extra_bytes != 0) && | ||
10899 | ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) | ||
10900 | == 0)) { | ||
10901 | scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES; | ||
10902 | scsiq->q1.extra_bytes = extra_bytes; | ||
10903 | data_cnt = le32_to_cpu( | ||
10904 | sg_head->sg_list[sg_entry_cnt_minus_one].bytes); | ||
10905 | data_cnt -= (ASC_DCNT) extra_bytes; | ||
10906 | sg_head->sg_list[sg_entry_cnt_minus_one].bytes = | ||
10907 | cpu_to_le32(data_cnt); | ||
10908 | } | ||
10909 | } | ||
10910 | } | ||
10911 | } | ||
10912 | sg_head->entry_to_copy = sg_head->entry_cnt; | ||
10913 | #if CC_VERY_LONG_SG_LIST | ||
10914 | /* | ||
10915 | * Set the sg_entry_cnt to the maximum possible. The rest of | ||
10916 | * the SG elements will be copied when the RISC completes the | ||
10917 | * SG elements that fit and halts. | ||
10918 | */ | ||
10919 | if (sg_entry_cnt > ASC_MAX_SG_LIST) | ||
10920 | { | ||
10921 | sg_entry_cnt = ASC_MAX_SG_LIST; | ||
10922 | } | ||
10923 | #endif /* CC_VERY_LONG_SG_LIST */ | ||
10924 | n_q_required = AscSgListToQueue(sg_entry_cnt); | ||
10925 | if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >= | ||
10926 | (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) { | ||
10927 | if ((sta = AscSendScsiQueue(asc_dvc, scsiq, | ||
10928 | n_q_required)) == 1) { | ||
10929 | asc_dvc->in_critical_cnt--; | ||
10930 | if (asc_exe_callback != 0) { | ||
10931 | (*asc_exe_callback) (asc_dvc, scsiq); | ||
10932 | } | ||
10933 | DvcLeaveCritical(last_int_level); | ||
10934 | return (sta); | ||
10935 | } | ||
10936 | } | ||
10937 | } else { | ||
10938 | if (asc_dvc->bug_fix_cntl) { | ||
10939 | if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) { | ||
10940 | if ((scsi_cmd == READ_6) || | ||
10941 | (scsi_cmd == READ_10)) { | ||
10942 | addr = le32_to_cpu(scsiq->q1.data_addr) + | ||
10943 | le32_to_cpu(scsiq->q1.data_cnt); | ||
10944 | extra_bytes = (uchar) ((ushort) addr & 0x0003); | ||
10945 | if ((extra_bytes != 0) && | ||
10946 | ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) | ||
10947 | == 0)) { | ||
10948 | data_cnt = le32_to_cpu(scsiq->q1.data_cnt); | ||
10949 | if (((ushort) data_cnt & 0x01FF) == 0) { | ||
10950 | scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES; | ||
10951 | data_cnt -= (ASC_DCNT) extra_bytes; | ||
10952 | scsiq->q1.data_cnt = cpu_to_le32(data_cnt); | ||
10953 | scsiq->q1.extra_bytes = extra_bytes; | ||
10954 | } | ||
10955 | } | ||
10956 | } | ||
10957 | } | ||
10958 | } | ||
10959 | n_q_required = 1; | ||
10960 | if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) || | ||
10961 | ((scsiq->q1.cntl & QC_URGENT) != 0)) { | ||
10962 | if ((sta = AscSendScsiQueue(asc_dvc, scsiq, | ||
10963 | n_q_required)) == 1) { | ||
10964 | asc_dvc->in_critical_cnt--; | ||
10965 | if (asc_exe_callback != 0) { | ||
10966 | (*asc_exe_callback) (asc_dvc, scsiq); | ||
10967 | } | ||
10968 | DvcLeaveCritical(last_int_level); | ||
10969 | return (sta); | ||
10970 | } | ||
10971 | } | ||
10972 | } | ||
10973 | asc_dvc->in_critical_cnt--; | ||
10974 | DvcLeaveCritical(last_int_level); | ||
10975 | return (sta); | ||
10976 | } | ||
10977 | |||
10978 | STATIC int | ||
10979 | AscSendScsiQueue( | ||
10980 | ASC_DVC_VAR *asc_dvc, | ||
10981 | ASC_SCSI_Q *scsiq, | ||
10982 | uchar n_q_required | ||
10983 | ) | ||
10984 | { | ||
10985 | PortAddr iop_base; | ||
10986 | uchar free_q_head; | ||
10987 | uchar next_qp; | ||
10988 | uchar tid_no; | ||
10989 | uchar target_ix; | ||
10990 | int sta; | ||
10991 | |||
10992 | iop_base = asc_dvc->iop_base; | ||
10993 | target_ix = scsiq->q2.target_ix; | ||
10994 | tid_no = ASC_TIX_TO_TID(target_ix); | ||
10995 | sta = 0; | ||
10996 | free_q_head = (uchar) AscGetVarFreeQHead(iop_base); | ||
10997 | if (n_q_required > 1) { | ||
10998 | if ((next_qp = AscAllocMultipleFreeQueue(iop_base, | ||
10999 | free_q_head, (uchar) (n_q_required))) | ||
11000 | != (uchar) ASC_QLINK_END) { | ||
11001 | asc_dvc->last_q_shortage = 0; | ||
11002 | scsiq->sg_head->queue_cnt = n_q_required - 1; | ||
11003 | scsiq->q1.q_no = free_q_head; | ||
11004 | if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq, | ||
11005 | free_q_head)) == 1) { | ||
11006 | AscPutVarFreeQHead(iop_base, next_qp); | ||
11007 | asc_dvc->cur_total_qng += (uchar) (n_q_required); | ||
11008 | asc_dvc->cur_dvc_qng[tid_no]++; | ||
11009 | } | ||
11010 | return (sta); | ||
11011 | } | ||
11012 | } else if (n_q_required == 1) { | ||
11013 | if ((next_qp = AscAllocFreeQueue(iop_base, | ||
11014 | free_q_head)) != ASC_QLINK_END) { | ||
11015 | scsiq->q1.q_no = free_q_head; | ||
11016 | if ((sta = AscPutReadyQueue(asc_dvc, scsiq, | ||
11017 | free_q_head)) == 1) { | ||
11018 | AscPutVarFreeQHead(iop_base, next_qp); | ||
11019 | asc_dvc->cur_total_qng++; | ||
11020 | asc_dvc->cur_dvc_qng[tid_no]++; | ||
11021 | } | ||
11022 | return (sta); | ||
11023 | } | ||
11024 | } | ||
11025 | return (sta); | ||
11026 | } | ||
11027 | |||
11028 | STATIC int | ||
11029 | AscSgListToQueue( | ||
11030 | int sg_list | ||
11031 | ) | ||
11032 | { | ||
11033 | int n_sg_list_qs; | ||
11034 | |||
11035 | n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q); | ||
11036 | if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0) | ||
11037 | n_sg_list_qs++; | ||
11038 | return (n_sg_list_qs + 1); | ||
11039 | } | ||
11040 | |||
11041 | |||
11042 | STATIC uint | ||
11043 | AscGetNumOfFreeQueue( | ||
11044 | ASC_DVC_VAR *asc_dvc, | ||
11045 | uchar target_ix, | ||
11046 | uchar n_qs | ||
11047 | ) | ||
11048 | { | ||
11049 | uint cur_used_qs; | ||
11050 | uint cur_free_qs; | ||
11051 | ASC_SCSI_BIT_ID_TYPE target_id; | ||
11052 | uchar tid_no; | ||
11053 | |||
11054 | target_id = ASC_TIX_TO_TARGET_ID(target_ix); | ||
11055 | tid_no = ASC_TIX_TO_TID(target_ix); | ||
11056 | if ((asc_dvc->unit_not_ready & target_id) || | ||
11057 | (asc_dvc->queue_full_or_busy & target_id)) { | ||
11058 | return (0); | ||
11059 | } | ||
11060 | if (n_qs == 1) { | ||
11061 | cur_used_qs = (uint) asc_dvc->cur_total_qng + | ||
11062 | (uint) asc_dvc->last_q_shortage + | ||
11063 | (uint) ASC_MIN_FREE_Q; | ||
11064 | } else { | ||
11065 | cur_used_qs = (uint) asc_dvc->cur_total_qng + | ||
11066 | (uint) ASC_MIN_FREE_Q; | ||
11067 | } | ||
11068 | if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) { | ||
11069 | cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs; | ||
11070 | if (asc_dvc->cur_dvc_qng[tid_no] >= | ||
11071 | asc_dvc->max_dvc_qng[tid_no]) { | ||
11072 | return (0); | ||
11073 | } | ||
11074 | return (cur_free_qs); | ||
11075 | } | ||
11076 | if (n_qs > 1) { | ||
11077 | if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) { | ||
11078 | asc_dvc->last_q_shortage = n_qs; | ||
11079 | } | ||
11080 | } | ||
11081 | return (0); | ||
11082 | } | ||
11083 | |||
11084 | STATIC int | ||
11085 | AscPutReadyQueue( | ||
11086 | ASC_DVC_VAR *asc_dvc, | ||
11087 | ASC_SCSI_Q *scsiq, | ||
11088 | uchar q_no | ||
11089 | ) | ||
11090 | { | ||
11091 | ushort q_addr; | ||
11092 | uchar tid_no; | ||
11093 | uchar sdtr_data; | ||
11094 | uchar syn_period_ix; | ||
11095 | uchar syn_offset; | ||
11096 | PortAddr iop_base; | ||
11097 | |||
11098 | iop_base = asc_dvc->iop_base; | ||
11099 | if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) && | ||
11100 | ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) { | ||
11101 | tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix); | ||
11102 | sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no); | ||
11103 | syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1); | ||
11104 | syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET; | ||
11105 | AscMsgOutSDTR(asc_dvc, | ||
11106 | asc_dvc->sdtr_period_tbl[syn_period_ix], | ||
11107 | syn_offset); | ||
11108 | scsiq->q1.cntl |= QC_MSG_OUT; | ||
11109 | } | ||
11110 | q_addr = ASC_QNO_TO_QADDR(q_no); | ||
11111 | if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) { | ||
11112 | scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG ; | ||
11113 | } | ||
11114 | scsiq->q1.status = QS_FREE; | ||
11115 | AscMemWordCopyPtrToLram(iop_base, | ||
11116 | q_addr + ASC_SCSIQ_CDB_BEG, | ||
11117 | (uchar *) scsiq->cdbptr, | ||
11118 | scsiq->q2.cdb_len >> 1); | ||
11119 | |||
11120 | DvcPutScsiQ(iop_base, | ||
11121 | q_addr + ASC_SCSIQ_CPY_BEG, | ||
11122 | (uchar *) &scsiq->q1.cntl, | ||
11123 | ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1); | ||
11124 | AscWriteLramWord(iop_base, | ||
11125 | (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS), | ||
11126 | (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY)); | ||
11127 | return (1); | ||
11128 | } | ||
11129 | |||
11130 | STATIC int | ||
11131 | AscPutReadySgListQueue( | ||
11132 | ASC_DVC_VAR *asc_dvc, | ||
11133 | ASC_SCSI_Q *scsiq, | ||
11134 | uchar q_no | ||
11135 | ) | ||
11136 | { | ||
11137 | int sta; | ||
11138 | int i; | ||
11139 | ASC_SG_HEAD *sg_head; | ||
11140 | ASC_SG_LIST_Q scsi_sg_q; | ||
11141 | ASC_DCNT saved_data_addr; | ||
11142 | ASC_DCNT saved_data_cnt; | ||
11143 | PortAddr iop_base; | ||
11144 | ushort sg_list_dwords; | ||
11145 | ushort sg_index; | ||
11146 | ushort sg_entry_cnt; | ||
11147 | ushort q_addr; | ||
11148 | uchar next_qp; | ||
11149 | |||
11150 | iop_base = asc_dvc->iop_base; | ||
11151 | sg_head = scsiq->sg_head; | ||
11152 | saved_data_addr = scsiq->q1.data_addr; | ||
11153 | saved_data_cnt = scsiq->q1.data_cnt; | ||
11154 | scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr; | ||
11155 | scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes; | ||
11156 | #if CC_VERY_LONG_SG_LIST | ||
11157 | /* | ||
11158 | * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST | ||
11159 | * then not all SG elements will fit in the allocated queues. | ||
11160 | * The rest of the SG elements will be copied when the RISC | ||
11161 | * completes the SG elements that fit and halts. | ||
11162 | */ | ||
11163 | if (sg_head->entry_cnt > ASC_MAX_SG_LIST) | ||
11164 | { | ||
11165 | /* | ||
11166 | * Set sg_entry_cnt to be the number of SG elements that | ||
11167 | * will fit in the allocated SG queues. It is minus 1, because | ||
11168 | * the first SG element is handled above. ASC_MAX_SG_LIST is | ||
11169 | * already inflated by 1 to account for this. For example it | ||
11170 | * may be 50 which is 1 + 7 queues * 7 SG elements. | ||
11171 | */ | ||
11172 | sg_entry_cnt = ASC_MAX_SG_LIST - 1; | ||
11173 | |||
11174 | /* | ||
11175 | * Keep track of remaining number of SG elements that will | ||
11176 | * need to be handled from a_isr.c. | ||
11177 | */ | ||
11178 | scsiq->remain_sg_entry_cnt = sg_head->entry_cnt - ASC_MAX_SG_LIST; | ||
11179 | } else | ||
11180 | { | ||
11181 | #endif /* CC_VERY_LONG_SG_LIST */ | ||
11182 | /* | ||
11183 | * Set sg_entry_cnt to be the number of SG elements that | ||
11184 | * will fit in the allocated SG queues. It is minus 1, because | ||
11185 | * the first SG element is handled above. | ||
11186 | */ | ||
11187 | sg_entry_cnt = sg_head->entry_cnt - 1; | ||
11188 | #if CC_VERY_LONG_SG_LIST | ||
11189 | } | ||
11190 | #endif /* CC_VERY_LONG_SG_LIST */ | ||
11191 | if (sg_entry_cnt != 0) { | ||
11192 | scsiq->q1.cntl |= QC_SG_HEAD; | ||
11193 | q_addr = ASC_QNO_TO_QADDR(q_no); | ||
11194 | sg_index = 1; | ||
11195 | scsiq->q1.sg_queue_cnt = sg_head->queue_cnt; | ||
11196 | scsi_sg_q.sg_head_qp = q_no; | ||
11197 | scsi_sg_q.cntl = QCSG_SG_XFER_LIST; | ||
11198 | for (i = 0; i < sg_head->queue_cnt; i++) { | ||
11199 | scsi_sg_q.seq_no = i + 1; | ||
11200 | if (sg_entry_cnt > ASC_SG_LIST_PER_Q) { | ||
11201 | sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2); | ||
11202 | sg_entry_cnt -= ASC_SG_LIST_PER_Q; | ||
11203 | if (i == 0) { | ||
11204 | scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q; | ||
11205 | scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q; | ||
11206 | } else { | ||
11207 | scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1; | ||
11208 | scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1; | ||
11209 | } | ||
11210 | } else { | ||
11211 | #if CC_VERY_LONG_SG_LIST | ||
11212 | /* | ||
11213 | * This is the last SG queue in the list of | ||
11214 | * allocated SG queues. If there are more | ||
11215 | * SG elements than will fit in the allocated | ||
11216 | * queues, then set the QCSG_SG_XFER_MORE flag. | ||
11217 | */ | ||
11218 | if (sg_head->entry_cnt > ASC_MAX_SG_LIST) | ||
11219 | { | ||
11220 | scsi_sg_q.cntl |= QCSG_SG_XFER_MORE; | ||
11221 | } else | ||
11222 | { | ||
11223 | #endif /* CC_VERY_LONG_SG_LIST */ | ||
11224 | scsi_sg_q.cntl |= QCSG_SG_XFER_END; | ||
11225 | #if CC_VERY_LONG_SG_LIST | ||
11226 | } | ||
11227 | #endif /* CC_VERY_LONG_SG_LIST */ | ||
11228 | sg_list_dwords = sg_entry_cnt << 1; | ||
11229 | if (i == 0) { | ||
11230 | scsi_sg_q.sg_list_cnt = sg_entry_cnt; | ||
11231 | scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt; | ||
11232 | } else { | ||
11233 | scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1; | ||
11234 | scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1; | ||
11235 | } | ||
11236 | sg_entry_cnt = 0; | ||
11237 | } | ||
11238 | next_qp = AscReadLramByte(iop_base, | ||
11239 | (ushort) (q_addr + ASC_SCSIQ_B_FWD)); | ||
11240 | scsi_sg_q.q_no = next_qp; | ||
11241 | q_addr = ASC_QNO_TO_QADDR(next_qp); | ||
11242 | AscMemWordCopyPtrToLram(iop_base, | ||
11243 | q_addr + ASC_SCSIQ_SGHD_CPY_BEG, | ||
11244 | (uchar *) &scsi_sg_q, | ||
11245 | sizeof(ASC_SG_LIST_Q) >> 1); | ||
11246 | AscMemDWordCopyPtrToLram(iop_base, | ||
11247 | q_addr + ASC_SGQ_LIST_BEG, | ||
11248 | (uchar *) &sg_head->sg_list[sg_index], | ||
11249 | sg_list_dwords); | ||
11250 | sg_index += ASC_SG_LIST_PER_Q; | ||
11251 | scsiq->next_sg_index = sg_index; | ||
11252 | } | ||
11253 | } else { | ||
11254 | scsiq->q1.cntl &= ~QC_SG_HEAD; | ||
11255 | } | ||
11256 | sta = AscPutReadyQueue(asc_dvc, scsiq, q_no); | ||
11257 | scsiq->q1.data_addr = saved_data_addr; | ||
11258 | scsiq->q1.data_cnt = saved_data_cnt; | ||
11259 | return (sta); | ||
11260 | } | ||
11261 | |||
11262 | STATIC int | ||
11263 | AscSetRunChipSynRegAtID( | ||
11264 | PortAddr iop_base, | ||
11265 | uchar tid_no, | ||
11266 | uchar sdtr_data | ||
11267 | ) | ||
11268 | { | ||
11269 | int sta = FALSE; | ||
11270 | |||
11271 | if (AscHostReqRiscHalt(iop_base)) { | ||
11272 | sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data); | ||
11273 | AscStartChip(iop_base); | ||
11274 | return (sta); | ||
11275 | } | ||
11276 | return (sta); | ||
11277 | } | ||
11278 | |||
11279 | STATIC int | ||
11280 | AscSetChipSynRegAtID( | ||
11281 | PortAddr iop_base, | ||
11282 | uchar id, | ||
11283 | uchar sdtr_data | ||
11284 | ) | ||
11285 | { | ||
11286 | ASC_SCSI_BIT_ID_TYPE org_id; | ||
11287 | int i; | ||
11288 | int sta = TRUE; | ||
11289 | |||
11290 | AscSetBank(iop_base, 1); | ||
11291 | org_id = AscReadChipDvcID(iop_base); | ||
11292 | for (i = 0; i <= ASC_MAX_TID; i++) { | ||
11293 | if (org_id == (0x01 << i)) | ||
11294 | break; | ||
11295 | } | ||
11296 | org_id = (ASC_SCSI_BIT_ID_TYPE) i; | ||
11297 | AscWriteChipDvcID(iop_base, id); | ||
11298 | if (AscReadChipDvcID(iop_base) == (0x01 << id)) { | ||
11299 | AscSetBank(iop_base, 0); | ||
11300 | AscSetChipSyn(iop_base, sdtr_data); | ||
11301 | if (AscGetChipSyn(iop_base) != sdtr_data) { | ||
11302 | sta = FALSE; | ||
11303 | } | ||
11304 | } else { | ||
11305 | sta = FALSE; | ||
11306 | } | ||
11307 | AscSetBank(iop_base, 1); | ||
11308 | AscWriteChipDvcID(iop_base, org_id); | ||
11309 | AscSetBank(iop_base, 0); | ||
11310 | return (sta); | ||
11311 | } | ||
11312 | |||
11313 | STATIC ushort | ||
11314 | AscInitLram( | ||
11315 | ASC_DVC_VAR *asc_dvc | ||
11316 | ) | ||
11317 | { | ||
11318 | uchar i; | ||
11319 | ushort s_addr; | ||
11320 | PortAddr iop_base; | ||
11321 | ushort warn_code; | ||
11322 | |||
11323 | iop_base = asc_dvc->iop_base; | ||
11324 | warn_code = 0; | ||
11325 | AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0, | ||
11326 | (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1) | ||
11327 | ); | ||
11328 | i = ASC_MIN_ACTIVE_QNO; | ||
11329 | s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE; | ||
11330 | AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD), | ||
11331 | (uchar) (i + 1)); | ||
11332 | AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD), | ||
11333 | (uchar) (asc_dvc->max_total_qng)); | ||
11334 | AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO), | ||
11335 | (uchar) i); | ||
11336 | i++; | ||
11337 | s_addr += ASC_QBLK_SIZE; | ||
11338 | for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) { | ||
11339 | AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD), | ||
11340 | (uchar) (i + 1)); | ||
11341 | AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD), | ||
11342 | (uchar) (i - 1)); | ||
11343 | AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO), | ||
11344 | (uchar) i); | ||
11345 | } | ||
11346 | AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD), | ||
11347 | (uchar) ASC_QLINK_END); | ||
11348 | AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD), | ||
11349 | (uchar) (asc_dvc->max_total_qng - 1)); | ||
11350 | AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO), | ||
11351 | (uchar) asc_dvc->max_total_qng); | ||
11352 | i++; | ||
11353 | s_addr += ASC_QBLK_SIZE; | ||
11354 | for (; i <= (uchar) (asc_dvc->max_total_qng + 3); | ||
11355 | i++, s_addr += ASC_QBLK_SIZE) { | ||
11356 | AscWriteLramByte(iop_base, | ||
11357 | (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i); | ||
11358 | AscWriteLramByte(iop_base, | ||
11359 | (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i); | ||
11360 | AscWriteLramByte(iop_base, | ||
11361 | (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i); | ||
11362 | } | ||
11363 | return (warn_code); | ||
11364 | } | ||
11365 | |||
11366 | STATIC ushort | ||
11367 | AscInitQLinkVar( | ||
11368 | ASC_DVC_VAR *asc_dvc | ||
11369 | ) | ||
11370 | { | ||
11371 | PortAddr iop_base; | ||
11372 | int i; | ||
11373 | ushort lram_addr; | ||
11374 | |||
11375 | iop_base = asc_dvc->iop_base; | ||
11376 | AscPutRiscVarFreeQHead(iop_base, 1); | ||
11377 | AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng); | ||
11378 | AscPutVarFreeQHead(iop_base, 1); | ||
11379 | AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng); | ||
11380 | AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B, | ||
11381 | (uchar) ((int) asc_dvc->max_total_qng + 1)); | ||
11382 | AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B, | ||
11383 | (uchar) ((int) asc_dvc->max_total_qng + 2)); | ||
11384 | AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B, | ||
11385 | asc_dvc->max_total_qng); | ||
11386 | AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0); | ||
11387 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); | ||
11388 | AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0); | ||
11389 | AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0); | ||
11390 | AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0); | ||
11391 | AscPutQDoneInProgress(iop_base, 0); | ||
11392 | lram_addr = ASC_QADR_BEG; | ||
11393 | for (i = 0; i < 32; i++, lram_addr += 2) { | ||
11394 | AscWriteLramWord(iop_base, lram_addr, 0); | ||
11395 | } | ||
11396 | return (0); | ||
11397 | } | ||
11398 | |||
11399 | STATIC int | ||
11400 | AscSetLibErrorCode( | ||
11401 | ASC_DVC_VAR *asc_dvc, | ||
11402 | ushort err_code | ||
11403 | ) | ||
11404 | { | ||
11405 | if (asc_dvc->err_code == 0) { | ||
11406 | asc_dvc->err_code = err_code; | ||
11407 | AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W, | ||
11408 | err_code); | ||
11409 | } | ||
11410 | return (err_code); | ||
11411 | } | ||
11412 | |||
11413 | |||
11414 | STATIC uchar | ||
11415 | AscMsgOutSDTR( | ||
11416 | ASC_DVC_VAR *asc_dvc, | ||
11417 | uchar sdtr_period, | ||
11418 | uchar sdtr_offset | ||
11419 | ) | ||
11420 | { | ||
11421 | EXT_MSG sdtr_buf; | ||
11422 | uchar sdtr_period_index; | ||
11423 | PortAddr iop_base; | ||
11424 | |||
11425 | iop_base = asc_dvc->iop_base; | ||
11426 | sdtr_buf.msg_type = MS_EXTEND; | ||
11427 | sdtr_buf.msg_len = MS_SDTR_LEN; | ||
11428 | sdtr_buf.msg_req = MS_SDTR_CODE; | ||
11429 | sdtr_buf.xfer_period = sdtr_period; | ||
11430 | sdtr_offset &= ASC_SYN_MAX_OFFSET; | ||
11431 | sdtr_buf.req_ack_offset = sdtr_offset; | ||
11432 | if ((sdtr_period_index = | ||
11433 | AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <= | ||
11434 | asc_dvc->max_sdtr_index) { | ||
11435 | AscMemWordCopyPtrToLram(iop_base, | ||
11436 | ASCV_MSGOUT_BEG, | ||
11437 | (uchar *) &sdtr_buf, | ||
11438 | sizeof (EXT_MSG) >> 1); | ||
11439 | return ((sdtr_period_index << 4) | sdtr_offset); | ||
11440 | } else { | ||
11441 | |||
11442 | sdtr_buf.req_ack_offset = 0; | ||
11443 | AscMemWordCopyPtrToLram(iop_base, | ||
11444 | ASCV_MSGOUT_BEG, | ||
11445 | (uchar *) &sdtr_buf, | ||
11446 | sizeof (EXT_MSG) >> 1); | ||
11447 | return (0); | ||
11448 | } | ||
11449 | } | ||
11450 | |||
11451 | STATIC uchar | ||
11452 | AscCalSDTRData( | ||
11453 | ASC_DVC_VAR *asc_dvc, | ||
11454 | uchar sdtr_period, | ||
11455 | uchar syn_offset | ||
11456 | ) | ||
11457 | { | ||
11458 | uchar byte; | ||
11459 | uchar sdtr_period_ix; | ||
11460 | |||
11461 | sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period); | ||
11462 | if ( | ||
11463 | (sdtr_period_ix > asc_dvc->max_sdtr_index) | ||
11464 | ) { | ||
11465 | return (0xFF); | ||
11466 | } | ||
11467 | byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET); | ||
11468 | return (byte); | ||
11469 | } | ||
11470 | |||
11471 | STATIC void | ||
11472 | AscSetChipSDTR( | ||
11473 | PortAddr iop_base, | ||
11474 | uchar sdtr_data, | ||
11475 | uchar tid_no | ||
11476 | ) | ||
11477 | { | ||
11478 | AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data); | ||
11479 | AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data); | ||
11480 | return; | ||
11481 | } | ||
11482 | |||
11483 | STATIC uchar | ||
11484 | AscGetSynPeriodIndex( | ||
11485 | ASC_DVC_VAR *asc_dvc, | ||
11486 | uchar syn_time | ||
11487 | ) | ||
11488 | { | ||
11489 | uchar *period_table; | ||
11490 | int max_index; | ||
11491 | int min_index; | ||
11492 | int i; | ||
11493 | |||
11494 | period_table = asc_dvc->sdtr_period_tbl; | ||
11495 | max_index = (int) asc_dvc->max_sdtr_index; | ||
11496 | min_index = (int)asc_dvc->host_init_sdtr_index; | ||
11497 | if ((syn_time <= period_table[max_index])) { | ||
11498 | for (i = min_index; i < (max_index - 1); i++) { | ||
11499 | if (syn_time <= period_table[i]) { | ||
11500 | return ((uchar) i); | ||
11501 | } | ||
11502 | } | ||
11503 | return ((uchar) max_index); | ||
11504 | } else { | ||
11505 | return ((uchar) (max_index + 1)); | ||
11506 | } | ||
11507 | } | ||
11508 | |||
11509 | STATIC uchar | ||
11510 | AscAllocFreeQueue( | ||
11511 | PortAddr iop_base, | ||
11512 | uchar free_q_head | ||
11513 | ) | ||
11514 | { | ||
11515 | ushort q_addr; | ||
11516 | uchar next_qp; | ||
11517 | uchar q_status; | ||
11518 | |||
11519 | q_addr = ASC_QNO_TO_QADDR(free_q_head); | ||
11520 | q_status = (uchar) AscReadLramByte(iop_base, | ||
11521 | (ushort) (q_addr + ASC_SCSIQ_B_STATUS)); | ||
11522 | next_qp = AscReadLramByte(iop_base, | ||
11523 | (ushort) (q_addr + ASC_SCSIQ_B_FWD)); | ||
11524 | if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) { | ||
11525 | return (next_qp); | ||
11526 | } | ||
11527 | return (ASC_QLINK_END); | ||
11528 | } | ||
11529 | |||
11530 | STATIC uchar | ||
11531 | AscAllocMultipleFreeQueue( | ||
11532 | PortAddr iop_base, | ||
11533 | uchar free_q_head, | ||
11534 | uchar n_free_q | ||
11535 | ) | ||
11536 | { | ||
11537 | uchar i; | ||
11538 | |||
11539 | for (i = 0; i < n_free_q; i++) { | ||
11540 | if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head)) | ||
11541 | == ASC_QLINK_END) { | ||
11542 | return (ASC_QLINK_END); | ||
11543 | } | ||
11544 | } | ||
11545 | return (free_q_head); | ||
11546 | } | ||
11547 | |||
11548 | STATIC int | ||
11549 | AscHostReqRiscHalt( | ||
11550 | PortAddr iop_base | ||
11551 | ) | ||
11552 | { | ||
11553 | int count = 0; | ||
11554 | int sta = 0; | ||
11555 | uchar saved_stop_code; | ||
11556 | |||
11557 | if (AscIsChipHalted(iop_base)) | ||
11558 | return (1); | ||
11559 | saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B); | ||
11560 | AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, | ||
11561 | ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP | ||
11562 | ); | ||
11563 | do { | ||
11564 | if (AscIsChipHalted(iop_base)) { | ||
11565 | sta = 1; | ||
11566 | break; | ||
11567 | } | ||
11568 | DvcSleepMilliSecond(100); | ||
11569 | } while (count++ < 20); | ||
11570 | AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code); | ||
11571 | return (sta); | ||
11572 | } | ||
11573 | |||
11574 | STATIC int | ||
11575 | AscStopQueueExe( | ||
11576 | PortAddr iop_base | ||
11577 | ) | ||
11578 | { | ||
11579 | int count = 0; | ||
11580 | |||
11581 | if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) { | ||
11582 | AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, | ||
11583 | ASC_STOP_REQ_RISC_STOP); | ||
11584 | do { | ||
11585 | if ( | ||
11586 | AscReadLramByte(iop_base, ASCV_STOP_CODE_B) & | ||
11587 | ASC_STOP_ACK_RISC_STOP) { | ||
11588 | return (1); | ||
11589 | } | ||
11590 | DvcSleepMilliSecond(100); | ||
11591 | } while (count++ < 20); | ||
11592 | } | ||
11593 | return (0); | ||
11594 | } | ||
11595 | |||
11596 | STATIC void | ||
11597 | DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec) | ||
11598 | { | ||
11599 | udelay(micro_sec); | ||
11600 | } | ||
11601 | |||
11602 | STATIC void | ||
11603 | DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec) | ||
11604 | { | ||
11605 | udelay((nano_sec + 999)/1000); | ||
11606 | } | ||
11607 | |||
11608 | #ifdef CONFIG_ISA | ||
11609 | STATIC ASC_DCNT __init | ||
11610 | AscGetEisaProductID( | ||
11611 | PortAddr iop_base) | ||
11612 | { | ||
11613 | PortAddr eisa_iop; | ||
11614 | ushort product_id_high, product_id_low; | ||
11615 | ASC_DCNT product_id; | ||
11616 | |||
11617 | eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK; | ||
11618 | product_id_low = inpw(eisa_iop); | ||
11619 | product_id_high = inpw(eisa_iop + 2); | ||
11620 | product_id = ((ASC_DCNT) product_id_high << 16) | | ||
11621 | (ASC_DCNT) product_id_low; | ||
11622 | return (product_id); | ||
11623 | } | ||
11624 | |||
11625 | STATIC PortAddr __init | ||
11626 | AscSearchIOPortAddrEISA( | ||
11627 | PortAddr iop_base) | ||
11628 | { | ||
11629 | ASC_DCNT eisa_product_id; | ||
11630 | |||
11631 | if (iop_base == 0) { | ||
11632 | iop_base = ASC_EISA_MIN_IOP_ADDR; | ||
11633 | } else { | ||
11634 | if (iop_base == ASC_EISA_MAX_IOP_ADDR) | ||
11635 | return (0); | ||
11636 | if ((iop_base & 0x0050) == 0x0050) { | ||
11637 | iop_base += ASC_EISA_BIG_IOP_GAP; | ||
11638 | } else { | ||
11639 | iop_base += ASC_EISA_SMALL_IOP_GAP; | ||
11640 | } | ||
11641 | } | ||
11642 | while (iop_base <= ASC_EISA_MAX_IOP_ADDR) { | ||
11643 | eisa_product_id = AscGetEisaProductID(iop_base); | ||
11644 | if ((eisa_product_id == ASC_EISA_ID_740) || | ||
11645 | (eisa_product_id == ASC_EISA_ID_750)) { | ||
11646 | if (AscFindSignature(iop_base)) { | ||
11647 | inpw(iop_base + 4); | ||
11648 | return (iop_base); | ||
11649 | } | ||
11650 | } | ||
11651 | if (iop_base == ASC_EISA_MAX_IOP_ADDR) | ||
11652 | return (0); | ||
11653 | if ((iop_base & 0x0050) == 0x0050) { | ||
11654 | iop_base += ASC_EISA_BIG_IOP_GAP; | ||
11655 | } else { | ||
11656 | iop_base += ASC_EISA_SMALL_IOP_GAP; | ||
11657 | } | ||
11658 | } | ||
11659 | return (0); | ||
11660 | } | ||
11661 | #endif /* CONFIG_ISA */ | ||
11662 | |||
11663 | STATIC int | ||
11664 | AscStartChip( | ||
11665 | PortAddr iop_base | ||
11666 | ) | ||
11667 | { | ||
11668 | AscSetChipControl(iop_base, 0); | ||
11669 | if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) { | ||
11670 | return (0); | ||
11671 | } | ||
11672 | return (1); | ||
11673 | } | ||
11674 | |||
11675 | STATIC int | ||
11676 | AscStopChip( | ||
11677 | PortAddr iop_base | ||
11678 | ) | ||
11679 | { | ||
11680 | uchar cc_val; | ||
11681 | |||
11682 | cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG)); | ||
11683 | AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT)); | ||
11684 | AscSetChipIH(iop_base, INS_HALT); | ||
11685 | AscSetChipIH(iop_base, INS_RFLAG_WTM); | ||
11686 | if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) { | ||
11687 | return (0); | ||
11688 | } | ||
11689 | return (1); | ||
11690 | } | ||
11691 | |||
11692 | STATIC int | ||
11693 | AscIsChipHalted( | ||
11694 | PortAddr iop_base | ||
11695 | ) | ||
11696 | { | ||
11697 | if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) { | ||
11698 | if ((AscGetChipControl(iop_base) & CC_HALT) != 0) { | ||
11699 | return (1); | ||
11700 | } | ||
11701 | } | ||
11702 | return (0); | ||
11703 | } | ||
11704 | |||
11705 | STATIC void | ||
11706 | AscSetChipIH( | ||
11707 | PortAddr iop_base, | ||
11708 | ushort ins_code | ||
11709 | ) | ||
11710 | { | ||
11711 | AscSetBank(iop_base, 1); | ||
11712 | AscWriteChipIH(iop_base, ins_code); | ||
11713 | AscSetBank(iop_base, 0); | ||
11714 | return; | ||
11715 | } | ||
11716 | |||
11717 | STATIC void | ||
11718 | AscAckInterrupt( | ||
11719 | PortAddr iop_base | ||
11720 | ) | ||
11721 | { | ||
11722 | uchar host_flag; | ||
11723 | uchar risc_flag; | ||
11724 | ushort loop; | ||
11725 | |||
11726 | loop = 0; | ||
11727 | do { | ||
11728 | risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B); | ||
11729 | if (loop++ > 0x7FFF) { | ||
11730 | break; | ||
11731 | } | ||
11732 | } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0); | ||
11733 | host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT); | ||
11734 | AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, | ||
11735 | (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT)); | ||
11736 | AscSetChipStatus(iop_base, CIW_INT_ACK); | ||
11737 | loop = 0; | ||
11738 | while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) { | ||
11739 | AscSetChipStatus(iop_base, CIW_INT_ACK); | ||
11740 | if (loop++ > 3) { | ||
11741 | break; | ||
11742 | } | ||
11743 | } | ||
11744 | AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag); | ||
11745 | return; | ||
11746 | } | ||
11747 | |||
11748 | STATIC void | ||
11749 | AscDisableInterrupt( | ||
11750 | PortAddr iop_base | ||
11751 | ) | ||
11752 | { | ||
11753 | ushort cfg; | ||
11754 | |||
11755 | cfg = AscGetChipCfgLsw(iop_base); | ||
11756 | AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON)); | ||
11757 | return; | ||
11758 | } | ||
11759 | |||
11760 | STATIC void | ||
11761 | AscEnableInterrupt( | ||
11762 | PortAddr iop_base | ||
11763 | ) | ||
11764 | { | ||
11765 | ushort cfg; | ||
11766 | |||
11767 | cfg = AscGetChipCfgLsw(iop_base); | ||
11768 | AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON); | ||
11769 | return; | ||
11770 | } | ||
11771 | |||
11772 | |||
11773 | |||
11774 | STATIC void | ||
11775 | AscSetBank( | ||
11776 | PortAddr iop_base, | ||
11777 | uchar bank | ||
11778 | ) | ||
11779 | { | ||
11780 | uchar val; | ||
11781 | |||
11782 | val = AscGetChipControl(iop_base) & | ||
11783 | (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET)); | ||
11784 | if (bank == 1) { | ||
11785 | val |= CC_BANK_ONE; | ||
11786 | } else if (bank == 2) { | ||
11787 | val |= CC_DIAG | CC_BANK_ONE; | ||
11788 | } else { | ||
11789 | val &= ~CC_BANK_ONE; | ||
11790 | } | ||
11791 | AscSetChipControl(iop_base, val); | ||
11792 | return; | ||
11793 | } | ||
11794 | |||
11795 | STATIC int | ||
11796 | AscResetChipAndScsiBus( | ||
11797 | ASC_DVC_VAR *asc_dvc | ||
11798 | ) | ||
11799 | { | ||
11800 | PortAddr iop_base; | ||
11801 | int i = 10; | ||
11802 | |||
11803 | iop_base = asc_dvc->iop_base; | ||
11804 | while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) | ||
11805 | { | ||
11806 | DvcSleepMilliSecond(100); | ||
11807 | } | ||
11808 | AscStopChip(iop_base); | ||
11809 | AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT); | ||
11810 | DvcDelayNanoSecond(asc_dvc, 60000); | ||
11811 | AscSetChipIH(iop_base, INS_RFLAG_WTM); | ||
11812 | AscSetChipIH(iop_base, INS_HALT); | ||
11813 | AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT); | ||
11814 | AscSetChipControl(iop_base, CC_HALT); | ||
11815 | DvcSleepMilliSecond(200); | ||
11816 | AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT); | ||
11817 | AscSetChipStatus(iop_base, 0); | ||
11818 | return (AscIsChipHalted(iop_base)); | ||
11819 | } | ||
11820 | |||
11821 | STATIC ASC_DCNT __init | ||
11822 | AscGetMaxDmaCount( | ||
11823 | ushort bus_type) | ||
11824 | { | ||
11825 | if (bus_type & ASC_IS_ISA) | ||
11826 | return (ASC_MAX_ISA_DMA_COUNT); | ||
11827 | else if (bus_type & (ASC_IS_EISA | ASC_IS_VL)) | ||
11828 | return (ASC_MAX_VL_DMA_COUNT); | ||
11829 | return (ASC_MAX_PCI_DMA_COUNT); | ||
11830 | } | ||
11831 | |||
11832 | #ifdef CONFIG_ISA | ||
11833 | STATIC ushort __init | ||
11834 | AscGetIsaDmaChannel( | ||
11835 | PortAddr iop_base) | ||
11836 | { | ||
11837 | ushort channel; | ||
11838 | |||
11839 | channel = AscGetChipCfgLsw(iop_base) & 0x0003; | ||
11840 | if (channel == 0x03) | ||
11841 | return (0); | ||
11842 | else if (channel == 0x00) | ||
11843 | return (7); | ||
11844 | return (channel + 4); | ||
11845 | } | ||
11846 | |||
11847 | STATIC ushort __init | ||
11848 | AscSetIsaDmaChannel( | ||
11849 | PortAddr iop_base, | ||
11850 | ushort dma_channel) | ||
11851 | { | ||
11852 | ushort cfg_lsw; | ||
11853 | uchar value; | ||
11854 | |||
11855 | if ((dma_channel >= 5) && (dma_channel <= 7)) { | ||
11856 | if (dma_channel == 7) | ||
11857 | value = 0x00; | ||
11858 | else | ||
11859 | value = dma_channel - 4; | ||
11860 | cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC; | ||
11861 | cfg_lsw |= value; | ||
11862 | AscSetChipCfgLsw(iop_base, cfg_lsw); | ||
11863 | return (AscGetIsaDmaChannel(iop_base)); | ||
11864 | } | ||
11865 | return (0); | ||
11866 | } | ||
11867 | |||
11868 | STATIC uchar __init | ||
11869 | AscSetIsaDmaSpeed( | ||
11870 | PortAddr iop_base, | ||
11871 | uchar speed_value) | ||
11872 | { | ||
11873 | speed_value &= 0x07; | ||
11874 | AscSetBank(iop_base, 1); | ||
11875 | AscWriteChipDmaSpeed(iop_base, speed_value); | ||
11876 | AscSetBank(iop_base, 0); | ||
11877 | return (AscGetIsaDmaSpeed(iop_base)); | ||
11878 | } | ||
11879 | |||
11880 | STATIC uchar __init | ||
11881 | AscGetIsaDmaSpeed( | ||
11882 | PortAddr iop_base | ||
11883 | ) | ||
11884 | { | ||
11885 | uchar speed_value; | ||
11886 | |||
11887 | AscSetBank(iop_base, 1); | ||
11888 | speed_value = AscReadChipDmaSpeed(iop_base); | ||
11889 | speed_value &= 0x07; | ||
11890 | AscSetBank(iop_base, 0); | ||
11891 | return (speed_value); | ||
11892 | } | ||
11893 | #endif /* CONFIG_ISA */ | ||
11894 | |||
11895 | STATIC ushort __init | ||
11896 | AscReadPCIConfigWord( | ||
11897 | ASC_DVC_VAR *asc_dvc, | ||
11898 | ushort pci_config_offset) | ||
11899 | { | ||
11900 | uchar lsb, msb; | ||
11901 | |||
11902 | lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset); | ||
11903 | msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1); | ||
11904 | return ((ushort) ((msb << 8) | lsb)); | ||
11905 | } | ||
11906 | |||
11907 | STATIC ushort __init | ||
11908 | AscInitGetConfig( | ||
11909 | ASC_DVC_VAR *asc_dvc | ||
11910 | ) | ||
11911 | { | ||
11912 | ushort warn_code; | ||
11913 | PortAddr iop_base; | ||
11914 | ushort PCIDeviceID; | ||
11915 | ushort PCIVendorID; | ||
11916 | uchar PCIRevisionID; | ||
11917 | uchar prevCmdRegBits; | ||
11918 | |||
11919 | warn_code = 0; | ||
11920 | iop_base = asc_dvc->iop_base; | ||
11921 | asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG; | ||
11922 | if (asc_dvc->err_code != 0) { | ||
11923 | return (UW_ERR); | ||
11924 | } | ||
11925 | if (asc_dvc->bus_type == ASC_IS_PCI) { | ||
11926 | PCIVendorID = AscReadPCIConfigWord(asc_dvc, | ||
11927 | AscPCIConfigVendorIDRegister); | ||
11928 | |||
11929 | PCIDeviceID = AscReadPCIConfigWord(asc_dvc, | ||
11930 | AscPCIConfigDeviceIDRegister); | ||
11931 | |||
11932 | PCIRevisionID = DvcReadPCIConfigByte(asc_dvc, | ||
11933 | AscPCIConfigRevisionIDRegister); | ||
11934 | |||
11935 | if (PCIVendorID != ASC_PCI_VENDORID) { | ||
11936 | warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; | ||
11937 | } | ||
11938 | prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc, | ||
11939 | AscPCIConfigCommandRegister); | ||
11940 | |||
11941 | if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) != | ||
11942 | AscPCICmdRegBits_IOMemBusMaster) { | ||
11943 | DvcWritePCIConfigByte(asc_dvc, | ||
11944 | AscPCIConfigCommandRegister, | ||
11945 | (prevCmdRegBits | | ||
11946 | AscPCICmdRegBits_IOMemBusMaster)); | ||
11947 | |||
11948 | if ((DvcReadPCIConfigByte(asc_dvc, | ||
11949 | AscPCIConfigCommandRegister) | ||
11950 | & AscPCICmdRegBits_IOMemBusMaster) | ||
11951 | != AscPCICmdRegBits_IOMemBusMaster) { | ||
11952 | warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; | ||
11953 | } | ||
11954 | } | ||
11955 | if ((PCIDeviceID == ASC_PCI_DEVICEID_1200A) || | ||
11956 | (PCIDeviceID == ASC_PCI_DEVICEID_1200B)) { | ||
11957 | DvcWritePCIConfigByte(asc_dvc, | ||
11958 | AscPCIConfigLatencyTimer, 0x00); | ||
11959 | if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) | ||
11960 | != 0x00) { | ||
11961 | warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; | ||
11962 | } | ||
11963 | } else if (PCIDeviceID == ASC_PCI_DEVICEID_ULTRA) { | ||
11964 | if (DvcReadPCIConfigByte(asc_dvc, | ||
11965 | AscPCIConfigLatencyTimer) < 0x20) { | ||
11966 | DvcWritePCIConfigByte(asc_dvc, | ||
11967 | AscPCIConfigLatencyTimer, 0x20); | ||
11968 | |||
11969 | if (DvcReadPCIConfigByte(asc_dvc, | ||
11970 | AscPCIConfigLatencyTimer) < 0x20) { | ||
11971 | warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; | ||
11972 | } | ||
11973 | } | ||
11974 | } | ||
11975 | } | ||
11976 | |||
11977 | if (AscFindSignature(iop_base)) { | ||
11978 | warn_code |= AscInitAscDvcVar(asc_dvc); | ||
11979 | warn_code |= AscInitFromEEP(asc_dvc); | ||
11980 | asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG; | ||
11981 | if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) { | ||
11982 | asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT; | ||
11983 | } | ||
11984 | } else { | ||
11985 | asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; | ||
11986 | } | ||
11987 | return(warn_code); | ||
11988 | } | ||
11989 | |||
11990 | STATIC ushort __init | ||
11991 | AscInitSetConfig( | ||
11992 | ASC_DVC_VAR *asc_dvc | ||
11993 | ) | ||
11994 | { | ||
11995 | ushort warn_code = 0; | ||
11996 | |||
11997 | asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG; | ||
11998 | if (asc_dvc->err_code != 0) | ||
11999 | return (UW_ERR); | ||
12000 | if (AscFindSignature(asc_dvc->iop_base)) { | ||
12001 | warn_code |= AscInitFromAscDvcVar(asc_dvc); | ||
12002 | asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG; | ||
12003 | } else { | ||
12004 | asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; | ||
12005 | } | ||
12006 | return (warn_code); | ||
12007 | } | ||
12008 | |||
12009 | STATIC ushort __init | ||
12010 | AscInitFromAscDvcVar( | ||
12011 | ASC_DVC_VAR *asc_dvc | ||
12012 | ) | ||
12013 | { | ||
12014 | PortAddr iop_base; | ||
12015 | ushort cfg_msw; | ||
12016 | ushort warn_code; | ||
12017 | ushort pci_device_id = 0; | ||
12018 | |||
12019 | iop_base = asc_dvc->iop_base; | ||
12020 | #ifdef CONFIG_PCI | ||
12021 | if (asc_dvc->cfg->dev) | ||
12022 | pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device; | ||
12023 | #endif | ||
12024 | warn_code = 0; | ||
12025 | cfg_msw = AscGetChipCfgMsw(iop_base); | ||
12026 | if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { | ||
12027 | cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK)); | ||
12028 | warn_code |= ASC_WARN_CFG_MSW_RECOVER; | ||
12029 | AscSetChipCfgMsw(iop_base, cfg_msw); | ||
12030 | } | ||
12031 | if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) != | ||
12032 | asc_dvc->cfg->cmd_qng_enabled) { | ||
12033 | asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled; | ||
12034 | warn_code |= ASC_WARN_CMD_QNG_CONFLICT; | ||
12035 | } | ||
12036 | if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) { | ||
12037 | warn_code |= ASC_WARN_AUTO_CONFIG; | ||
12038 | } | ||
12039 | if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) { | ||
12040 | if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type) | ||
12041 | != asc_dvc->irq_no) { | ||
12042 | asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO; | ||
12043 | } | ||
12044 | } | ||
12045 | if (asc_dvc->bus_type & ASC_IS_PCI) { | ||
12046 | cfg_msw &= 0xFFC0; | ||
12047 | AscSetChipCfgMsw(iop_base, cfg_msw); | ||
12048 | if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) { | ||
12049 | } else { | ||
12050 | if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A) || | ||
12051 | (pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) { | ||
12052 | asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB; | ||
12053 | asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN; | ||
12054 | } | ||
12055 | } | ||
12056 | } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) { | ||
12057 | if (AscGetChipVersion(iop_base, asc_dvc->bus_type) | ||
12058 | == ASC_CHIP_VER_ASYN_BUG) { | ||
12059 | asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN; | ||
12060 | } | ||
12061 | } | ||
12062 | if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) != | ||
12063 | asc_dvc->cfg->chip_scsi_id) { | ||
12064 | asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID; | ||
12065 | } | ||
12066 | #ifdef CONFIG_ISA | ||
12067 | if (asc_dvc->bus_type & ASC_IS_ISA) { | ||
12068 | AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel); | ||
12069 | AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed); | ||
12070 | } | ||
12071 | #endif /* CONFIG_ISA */ | ||
12072 | return (warn_code); | ||
12073 | } | ||
12074 | |||
12075 | STATIC ushort | ||
12076 | AscInitAsc1000Driver( | ||
12077 | ASC_DVC_VAR *asc_dvc | ||
12078 | ) | ||
12079 | { | ||
12080 | ushort warn_code; | ||
12081 | PortAddr iop_base; | ||
12082 | |||
12083 | iop_base = asc_dvc->iop_base; | ||
12084 | warn_code = 0; | ||
12085 | if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) && | ||
12086 | !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) { | ||
12087 | AscResetChipAndScsiBus(asc_dvc); | ||
12088 | DvcSleepMilliSecond((ASC_DCNT) | ||
12089 | ((ushort) asc_dvc->scsi_reset_wait * 1000)); | ||
12090 | } | ||
12091 | asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC; | ||
12092 | if (asc_dvc->err_code != 0) | ||
12093 | return (UW_ERR); | ||
12094 | if (!AscFindSignature(asc_dvc->iop_base)) { | ||
12095 | asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; | ||
12096 | return (warn_code); | ||
12097 | } | ||
12098 | AscDisableInterrupt(iop_base); | ||
12099 | warn_code |= AscInitLram(asc_dvc); | ||
12100 | if (asc_dvc->err_code != 0) | ||
12101 | return (UW_ERR); | ||
12102 | ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n", | ||
12103 | (ulong) _asc_mcode_chksum); | ||
12104 | if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf, | ||
12105 | _asc_mcode_size) != _asc_mcode_chksum) { | ||
12106 | asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; | ||
12107 | return (warn_code); | ||
12108 | } | ||
12109 | warn_code |= AscInitMicroCodeVar(asc_dvc); | ||
12110 | asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC; | ||
12111 | AscEnableInterrupt(iop_base); | ||
12112 | return (warn_code); | ||
12113 | } | ||
12114 | |||
12115 | STATIC ushort __init | ||
12116 | AscInitAscDvcVar( | ||
12117 | ASC_DVC_VAR *asc_dvc) | ||
12118 | { | ||
12119 | int i; | ||
12120 | PortAddr iop_base; | ||
12121 | ushort warn_code; | ||
12122 | uchar chip_version; | ||
12123 | |||
12124 | iop_base = asc_dvc->iop_base; | ||
12125 | warn_code = 0; | ||
12126 | asc_dvc->err_code = 0; | ||
12127 | if ((asc_dvc->bus_type & | ||
12128 | (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) { | ||
12129 | asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE; | ||
12130 | } | ||
12131 | AscSetChipControl(iop_base, CC_HALT); | ||
12132 | AscSetChipStatus(iop_base, 0); | ||
12133 | asc_dvc->bug_fix_cntl = 0; | ||
12134 | asc_dvc->pci_fix_asyn_xfer = 0; | ||
12135 | asc_dvc->pci_fix_asyn_xfer_always = 0; | ||
12136 | /* asc_dvc->init_state initalized in AscInitGetConfig(). */ | ||
12137 | asc_dvc->sdtr_done = 0; | ||
12138 | asc_dvc->cur_total_qng = 0; | ||
12139 | asc_dvc->is_in_int = 0; | ||
12140 | asc_dvc->in_critical_cnt = 0; | ||
12141 | asc_dvc->last_q_shortage = 0; | ||
12142 | asc_dvc->use_tagged_qng = 0; | ||
12143 | asc_dvc->no_scam = 0; | ||
12144 | asc_dvc->unit_not_ready = 0; | ||
12145 | asc_dvc->queue_full_or_busy = 0; | ||
12146 | asc_dvc->redo_scam = 0; | ||
12147 | asc_dvc->res2 = 0; | ||
12148 | asc_dvc->host_init_sdtr_index = 0; | ||
12149 | asc_dvc->cfg->can_tagged_qng = 0; | ||
12150 | asc_dvc->cfg->cmd_qng_enabled = 0; | ||
12151 | asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL; | ||
12152 | asc_dvc->init_sdtr = 0; | ||
12153 | asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG; | ||
12154 | asc_dvc->scsi_reset_wait = 3; | ||
12155 | asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET; | ||
12156 | asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type); | ||
12157 | asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET; | ||
12158 | asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET; | ||
12159 | asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID; | ||
12160 | asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER; | ||
12161 | asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) | | ||
12162 | ASC_LIB_VERSION_MINOR; | ||
12163 | chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type); | ||
12164 | asc_dvc->cfg->chip_version = chip_version; | ||
12165 | asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0; | ||
12166 | asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1; | ||
12167 | asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2; | ||
12168 | asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3; | ||
12169 | asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4; | ||
12170 | asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5; | ||
12171 | asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6; | ||
12172 | asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7; | ||
12173 | asc_dvc->max_sdtr_index = 7; | ||
12174 | if ((asc_dvc->bus_type & ASC_IS_PCI) && | ||
12175 | (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) { | ||
12176 | asc_dvc->bus_type = ASC_IS_PCI_ULTRA; | ||
12177 | asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0; | ||
12178 | asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1; | ||
12179 | asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2; | ||
12180 | asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3; | ||
12181 | asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4; | ||
12182 | asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5; | ||
12183 | asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6; | ||
12184 | asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7; | ||
12185 | asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8; | ||
12186 | asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9; | ||
12187 | asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10; | ||
12188 | asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11; | ||
12189 | asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12; | ||
12190 | asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13; | ||
12191 | asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14; | ||
12192 | asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15; | ||
12193 | asc_dvc->max_sdtr_index = 15; | ||
12194 | if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) | ||
12195 | { | ||
12196 | AscSetExtraControl(iop_base, | ||
12197 | (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE)); | ||
12198 | } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) { | ||
12199 | AscSetExtraControl(iop_base, | ||
12200 | (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER)); | ||
12201 | } | ||
12202 | } | ||
12203 | if (asc_dvc->bus_type == ASC_IS_PCI) { | ||
12204 | AscSetExtraControl(iop_base, (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE)); | ||
12205 | } | ||
12206 | |||
12207 | asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED; | ||
12208 | if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) { | ||
12209 | AscSetChipIFC(iop_base, IFC_INIT_DEFAULT); | ||
12210 | asc_dvc->bus_type = ASC_IS_ISAPNP; | ||
12211 | } | ||
12212 | #ifdef CONFIG_ISA | ||
12213 | if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) { | ||
12214 | asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base); | ||
12215 | } | ||
12216 | #endif /* CONFIG_ISA */ | ||
12217 | for (i = 0; i <= ASC_MAX_TID; i++) { | ||
12218 | asc_dvc->cur_dvc_qng[i] = 0; | ||
12219 | asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG; | ||
12220 | asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *) 0L; | ||
12221 | asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *) 0L; | ||
12222 | asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG; | ||
12223 | } | ||
12224 | return (warn_code); | ||
12225 | } | ||
12226 | |||
12227 | STATIC ushort __init | ||
12228 | AscInitFromEEP(ASC_DVC_VAR *asc_dvc) | ||
12229 | { | ||
12230 | ASCEEP_CONFIG eep_config_buf; | ||
12231 | ASCEEP_CONFIG *eep_config; | ||
12232 | PortAddr iop_base; | ||
12233 | ushort chksum; | ||
12234 | ushort warn_code; | ||
12235 | ushort cfg_msw, cfg_lsw; | ||
12236 | int i; | ||
12237 | int write_eep = 0; | ||
12238 | |||
12239 | iop_base = asc_dvc->iop_base; | ||
12240 | warn_code = 0; | ||
12241 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE); | ||
12242 | AscStopQueueExe(iop_base); | ||
12243 | if ((AscStopChip(iop_base) == FALSE) || | ||
12244 | (AscGetChipScsiCtrl(iop_base) != 0)) { | ||
12245 | asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE; | ||
12246 | AscResetChipAndScsiBus(asc_dvc); | ||
12247 | DvcSleepMilliSecond((ASC_DCNT) | ||
12248 | ((ushort) asc_dvc->scsi_reset_wait * 1000)); | ||
12249 | } | ||
12250 | if (AscIsChipHalted(iop_base) == FALSE) { | ||
12251 | asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; | ||
12252 | return (warn_code); | ||
12253 | } | ||
12254 | AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); | ||
12255 | if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { | ||
12256 | asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR; | ||
12257 | return (warn_code); | ||
12258 | } | ||
12259 | eep_config = (ASCEEP_CONFIG *) &eep_config_buf; | ||
12260 | cfg_msw = AscGetChipCfgMsw(iop_base); | ||
12261 | cfg_lsw = AscGetChipCfgLsw(iop_base); | ||
12262 | if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { | ||
12263 | cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK)); | ||
12264 | warn_code |= ASC_WARN_CFG_MSW_RECOVER; | ||
12265 | AscSetChipCfgMsw(iop_base, cfg_msw); | ||
12266 | } | ||
12267 | chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type); | ||
12268 | ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum); | ||
12269 | if (chksum == 0) { | ||
12270 | chksum = 0xaa55; | ||
12271 | } | ||
12272 | if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) { | ||
12273 | warn_code |= ASC_WARN_AUTO_CONFIG; | ||
12274 | if (asc_dvc->cfg->chip_version == 3) { | ||
12275 | if (eep_config->cfg_lsw != cfg_lsw) { | ||
12276 | warn_code |= ASC_WARN_EEPROM_RECOVER; | ||
12277 | eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base); | ||
12278 | } | ||
12279 | if (eep_config->cfg_msw != cfg_msw) { | ||
12280 | warn_code |= ASC_WARN_EEPROM_RECOVER; | ||
12281 | eep_config->cfg_msw = AscGetChipCfgMsw(iop_base); | ||
12282 | } | ||
12283 | } | ||
12284 | } | ||
12285 | eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK; | ||
12286 | eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON; | ||
12287 | ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n", | ||
12288 | eep_config->chksum); | ||
12289 | if (chksum != eep_config->chksum) { | ||
12290 | if (AscGetChipVersion(iop_base, asc_dvc->bus_type) == | ||
12291 | ASC_CHIP_VER_PCI_ULTRA_3050 ) | ||
12292 | { | ||
12293 | ASC_DBG(1, | ||
12294 | "AscInitFromEEP: chksum error ignored; EEPROM-less board\n"); | ||
12295 | eep_config->init_sdtr = 0xFF; | ||
12296 | eep_config->disc_enable = 0xFF; | ||
12297 | eep_config->start_motor = 0xFF; | ||
12298 | eep_config->use_cmd_qng = 0; | ||
12299 | eep_config->max_total_qng = 0xF0; | ||
12300 | eep_config->max_tag_qng = 0x20; | ||
12301 | eep_config->cntl = 0xBFFF; | ||
12302 | ASC_EEP_SET_CHIP_ID(eep_config, 7); | ||
12303 | eep_config->no_scam = 0; | ||
12304 | eep_config->adapter_info[0] = 0; | ||
12305 | eep_config->adapter_info[1] = 0; | ||
12306 | eep_config->adapter_info[2] = 0; | ||
12307 | eep_config->adapter_info[3] = 0; | ||
12308 | eep_config->adapter_info[4] = 0; | ||
12309 | /* Indicate EEPROM-less board. */ | ||
12310 | eep_config->adapter_info[5] = 0xBB; | ||
12311 | } else { | ||
12312 | ASC_PRINT( | ||
12313 | "AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n"); | ||
12314 | write_eep = 1; | ||
12315 | warn_code |= ASC_WARN_EEPROM_CHKSUM; | ||
12316 | } | ||
12317 | } | ||
12318 | asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr; | ||
12319 | asc_dvc->cfg->disc_enable = eep_config->disc_enable; | ||
12320 | asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng; | ||
12321 | asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config); | ||
12322 | asc_dvc->start_motor = eep_config->start_motor; | ||
12323 | asc_dvc->dvc_cntl = eep_config->cntl; | ||
12324 | asc_dvc->no_scam = eep_config->no_scam; | ||
12325 | asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0]; | ||
12326 | asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1]; | ||
12327 | asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2]; | ||
12328 | asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3]; | ||
12329 | asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4]; | ||
12330 | asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5]; | ||
12331 | if (!AscTestExternalLram(asc_dvc)) { | ||
12332 | if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) { | ||
12333 | eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG; | ||
12334 | eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG; | ||
12335 | } else { | ||
12336 | eep_config->cfg_msw |= 0x0800; | ||
12337 | cfg_msw |= 0x0800; | ||
12338 | AscSetChipCfgMsw(iop_base, cfg_msw); | ||
12339 | eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG; | ||
12340 | eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG; | ||
12341 | } | ||
12342 | } else { | ||
12343 | } | ||
12344 | if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) { | ||
12345 | eep_config->max_total_qng = ASC_MIN_TOTAL_QNG; | ||
12346 | } | ||
12347 | if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) { | ||
12348 | eep_config->max_total_qng = ASC_MAX_TOTAL_QNG; | ||
12349 | } | ||
12350 | if (eep_config->max_tag_qng > eep_config->max_total_qng) { | ||
12351 | eep_config->max_tag_qng = eep_config->max_total_qng; | ||
12352 | } | ||
12353 | if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) { | ||
12354 | eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC; | ||
12355 | } | ||
12356 | asc_dvc->max_total_qng = eep_config->max_total_qng; | ||
12357 | if ((eep_config->use_cmd_qng & eep_config->disc_enable) != | ||
12358 | eep_config->use_cmd_qng) { | ||
12359 | eep_config->disc_enable = eep_config->use_cmd_qng; | ||
12360 | warn_code |= ASC_WARN_CMD_QNG_CONFLICT; | ||
12361 | } | ||
12362 | if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) { | ||
12363 | asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type); | ||
12364 | } | ||
12365 | ASC_EEP_SET_CHIP_ID(eep_config, ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID); | ||
12366 | asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config); | ||
12367 | if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) && | ||
12368 | !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) { | ||
12369 | asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX; | ||
12370 | } | ||
12371 | |||
12372 | for (i = 0; i <= ASC_MAX_TID; i++) { | ||
12373 | asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i]; | ||
12374 | asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng; | ||
12375 | asc_dvc->cfg->sdtr_period_offset[i] = | ||
12376 | (uchar) (ASC_DEF_SDTR_OFFSET | | ||
12377 | (asc_dvc->host_init_sdtr_index << 4)); | ||
12378 | } | ||
12379 | eep_config->cfg_msw = AscGetChipCfgMsw(iop_base); | ||
12380 | if (write_eep) { | ||
12381 | if ((i = AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type)) != | ||
12382 | 0) { | ||
12383 | ASC_PRINT1( | ||
12384 | "AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n", i); | ||
12385 | } else { | ||
12386 | ASC_PRINT("AscInitFromEEP: Succesfully re-wrote EEPROM."); | ||
12387 | } | ||
12388 | } | ||
12389 | return (warn_code); | ||
12390 | } | ||
12391 | |||
12392 | STATIC ushort | ||
12393 | AscInitMicroCodeVar( | ||
12394 | ASC_DVC_VAR *asc_dvc | ||
12395 | ) | ||
12396 | { | ||
12397 | int i; | ||
12398 | ushort warn_code; | ||
12399 | PortAddr iop_base; | ||
12400 | ASC_PADDR phy_addr; | ||
12401 | ASC_DCNT phy_size; | ||
12402 | |||
12403 | iop_base = asc_dvc->iop_base; | ||
12404 | warn_code = 0; | ||
12405 | for (i = 0; i <= ASC_MAX_TID; i++) { | ||
12406 | AscPutMCodeInitSDTRAtID(iop_base, i, | ||
12407 | asc_dvc->cfg->sdtr_period_offset[i] | ||
12408 | ); | ||
12409 | } | ||
12410 | |||
12411 | AscInitQLinkVar(asc_dvc); | ||
12412 | AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B, | ||
12413 | asc_dvc->cfg->disc_enable); | ||
12414 | AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B, | ||
12415 | ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id)); | ||
12416 | |||
12417 | /* Align overrun buffer on an 8 byte boundary. */ | ||
12418 | phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf); | ||
12419 | phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7); | ||
12420 | AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D, | ||
12421 | (uchar *) &phy_addr, 1); | ||
12422 | phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8); | ||
12423 | AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D, | ||
12424 | (uchar *) &phy_size, 1); | ||
12425 | |||
12426 | asc_dvc->cfg->mcode_date = | ||
12427 | AscReadLramWord(iop_base, (ushort) ASCV_MC_DATE_W); | ||
12428 | asc_dvc->cfg->mcode_version = | ||
12429 | AscReadLramWord(iop_base, (ushort) ASCV_MC_VER_W); | ||
12430 | |||
12431 | AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); | ||
12432 | if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { | ||
12433 | asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR; | ||
12434 | return (warn_code); | ||
12435 | } | ||
12436 | if (AscStartChip(iop_base) != 1) { | ||
12437 | asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; | ||
12438 | return (warn_code); | ||
12439 | } | ||
12440 | |||
12441 | return (warn_code); | ||
12442 | } | ||
12443 | |||
12444 | STATIC int __init | ||
12445 | AscTestExternalLram( | ||
12446 | ASC_DVC_VAR *asc_dvc) | ||
12447 | { | ||
12448 | PortAddr iop_base; | ||
12449 | ushort q_addr; | ||
12450 | ushort saved_word; | ||
12451 | int sta; | ||
12452 | |||
12453 | iop_base = asc_dvc->iop_base; | ||
12454 | sta = 0; | ||
12455 | q_addr = ASC_QNO_TO_QADDR(241); | ||
12456 | saved_word = AscReadLramWord(iop_base, q_addr); | ||
12457 | AscSetChipLramAddr(iop_base, q_addr); | ||
12458 | AscSetChipLramData(iop_base, 0x55AA); | ||
12459 | DvcSleepMilliSecond(10); | ||
12460 | AscSetChipLramAddr(iop_base, q_addr); | ||
12461 | if (AscGetChipLramData(iop_base) == 0x55AA) { | ||
12462 | sta = 1; | ||
12463 | AscWriteLramWord(iop_base, q_addr, saved_word); | ||
12464 | } | ||
12465 | return (sta); | ||
12466 | } | ||
12467 | |||
12468 | STATIC int __init | ||
12469 | AscWriteEEPCmdReg( | ||
12470 | PortAddr iop_base, | ||
12471 | uchar cmd_reg | ||
12472 | ) | ||
12473 | { | ||
12474 | uchar read_back; | ||
12475 | int retry; | ||
12476 | |||
12477 | retry = 0; | ||
12478 | while (TRUE) { | ||
12479 | AscSetChipEEPCmd(iop_base, cmd_reg); | ||
12480 | DvcSleepMilliSecond(1); | ||
12481 | read_back = AscGetChipEEPCmd(iop_base); | ||
12482 | if (read_back == cmd_reg) { | ||
12483 | return (1); | ||
12484 | } | ||
12485 | if (retry++ > ASC_EEP_MAX_RETRY) { | ||
12486 | return (0); | ||
12487 | } | ||
12488 | } | ||
12489 | } | ||
12490 | |||
12491 | STATIC int __init | ||
12492 | AscWriteEEPDataReg( | ||
12493 | PortAddr iop_base, | ||
12494 | ushort data_reg | ||
12495 | ) | ||
12496 | { | ||
12497 | ushort read_back; | ||
12498 | int retry; | ||
12499 | |||
12500 | retry = 0; | ||
12501 | while (TRUE) { | ||
12502 | AscSetChipEEPData(iop_base, data_reg); | ||
12503 | DvcSleepMilliSecond(1); | ||
12504 | read_back = AscGetChipEEPData(iop_base); | ||
12505 | if (read_back == data_reg) { | ||
12506 | return (1); | ||
12507 | } | ||
12508 | if (retry++ > ASC_EEP_MAX_RETRY) { | ||
12509 | return (0); | ||
12510 | } | ||
12511 | } | ||
12512 | } | ||
12513 | |||
12514 | STATIC void __init | ||
12515 | AscWaitEEPRead(void) | ||
12516 | { | ||
12517 | DvcSleepMilliSecond(1); | ||
12518 | return; | ||
12519 | } | ||
12520 | |||
12521 | STATIC void __init | ||
12522 | AscWaitEEPWrite(void) | ||
12523 | { | ||
12524 | DvcSleepMilliSecond(20); | ||
12525 | return; | ||
12526 | } | ||
12527 | |||
12528 | STATIC ushort __init | ||
12529 | AscReadEEPWord( | ||
12530 | PortAddr iop_base, | ||
12531 | uchar addr) | ||
12532 | { | ||
12533 | ushort read_wval; | ||
12534 | uchar cmd_reg; | ||
12535 | |||
12536 | AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE); | ||
12537 | AscWaitEEPRead(); | ||
12538 | cmd_reg = addr | ASC_EEP_CMD_READ; | ||
12539 | AscWriteEEPCmdReg(iop_base, cmd_reg); | ||
12540 | AscWaitEEPRead(); | ||
12541 | read_wval = AscGetChipEEPData(iop_base); | ||
12542 | AscWaitEEPRead(); | ||
12543 | return (read_wval); | ||
12544 | } | ||
12545 | |||
12546 | STATIC ushort __init | ||
12547 | AscWriteEEPWord( | ||
12548 | PortAddr iop_base, | ||
12549 | uchar addr, | ||
12550 | ushort word_val) | ||
12551 | { | ||
12552 | ushort read_wval; | ||
12553 | |||
12554 | read_wval = AscReadEEPWord(iop_base, addr); | ||
12555 | if (read_wval != word_val) { | ||
12556 | AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE); | ||
12557 | AscWaitEEPRead(); | ||
12558 | AscWriteEEPDataReg(iop_base, word_val); | ||
12559 | AscWaitEEPRead(); | ||
12560 | AscWriteEEPCmdReg(iop_base, | ||
12561 | (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr)); | ||
12562 | AscWaitEEPWrite(); | ||
12563 | AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE); | ||
12564 | AscWaitEEPRead(); | ||
12565 | return (AscReadEEPWord(iop_base, addr)); | ||
12566 | } | ||
12567 | return (read_wval); | ||
12568 | } | ||
12569 | |||
12570 | STATIC ushort __init | ||
12571 | AscGetEEPConfig( | ||
12572 | PortAddr iop_base, | ||
12573 | ASCEEP_CONFIG * cfg_buf, ushort bus_type) | ||
12574 | { | ||
12575 | ushort wval; | ||
12576 | ushort sum; | ||
12577 | ushort *wbuf; | ||
12578 | int cfg_beg; | ||
12579 | int cfg_end; | ||
12580 | int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2; | ||
12581 | int s_addr; | ||
12582 | |||
12583 | wbuf = (ushort *) cfg_buf; | ||
12584 | sum = 0; | ||
12585 | /* Read two config words; Byte-swapping done by AscReadEEPWord(). */ | ||
12586 | for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) { | ||
12587 | *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr); | ||
12588 | sum += *wbuf; | ||
12589 | } | ||
12590 | if (bus_type & ASC_IS_VL) { | ||
12591 | cfg_beg = ASC_EEP_DVC_CFG_BEG_VL; | ||
12592 | cfg_end = ASC_EEP_MAX_DVC_ADDR_VL; | ||
12593 | } else { | ||
12594 | cfg_beg = ASC_EEP_DVC_CFG_BEG; | ||
12595 | cfg_end = ASC_EEP_MAX_DVC_ADDR; | ||
12596 | } | ||
12597 | for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) { | ||
12598 | wval = AscReadEEPWord( iop_base, ( uchar )s_addr ) ; | ||
12599 | if (s_addr <= uchar_end_in_config) { | ||
12600 | /* | ||
12601 | * Swap all char fields - must unswap bytes already swapped | ||
12602 | * by AscReadEEPWord(). | ||
12603 | */ | ||
12604 | *wbuf = le16_to_cpu(wval); | ||
12605 | } else { | ||
12606 | /* Don't swap word field at the end - cntl field. */ | ||
12607 | *wbuf = wval; | ||
12608 | } | ||
12609 | sum += wval; /* Checksum treats all EEPROM data as words. */ | ||
12610 | } | ||
12611 | /* | ||
12612 | * Read the checksum word which will be compared against 'sum' | ||
12613 | * by the caller. Word field already swapped. | ||
12614 | */ | ||
12615 | *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr); | ||
12616 | return (sum); | ||
12617 | } | ||
12618 | |||
12619 | STATIC int __init | ||
12620 | AscSetEEPConfigOnce( | ||
12621 | PortAddr iop_base, | ||
12622 | ASCEEP_CONFIG * cfg_buf, ushort bus_type) | ||
12623 | { | ||
12624 | int n_error; | ||
12625 | ushort *wbuf; | ||
12626 | ushort word; | ||
12627 | ushort sum; | ||
12628 | int s_addr; | ||
12629 | int cfg_beg; | ||
12630 | int cfg_end; | ||
12631 | int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2; | ||
12632 | |||
12633 | |||
12634 | wbuf = (ushort *) cfg_buf; | ||
12635 | n_error = 0; | ||
12636 | sum = 0; | ||
12637 | /* Write two config words; AscWriteEEPWord() will swap bytes. */ | ||
12638 | for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) { | ||
12639 | sum += *wbuf; | ||
12640 | if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) { | ||
12641 | n_error++; | ||
12642 | } | ||
12643 | } | ||
12644 | if (bus_type & ASC_IS_VL) { | ||
12645 | cfg_beg = ASC_EEP_DVC_CFG_BEG_VL; | ||
12646 | cfg_end = ASC_EEP_MAX_DVC_ADDR_VL; | ||
12647 | } else { | ||
12648 | cfg_beg = ASC_EEP_DVC_CFG_BEG; | ||
12649 | cfg_end = ASC_EEP_MAX_DVC_ADDR; | ||
12650 | } | ||
12651 | for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) { | ||
12652 | if (s_addr <= uchar_end_in_config) { | ||
12653 | /* | ||
12654 | * This is a char field. Swap char fields before they are | ||
12655 | * swapped again by AscWriteEEPWord(). | ||
12656 | */ | ||
12657 | word = cpu_to_le16(*wbuf); | ||
12658 | if (word != AscWriteEEPWord( iop_base, (uchar) s_addr, word)) { | ||
12659 | n_error++; | ||
12660 | } | ||
12661 | } else { | ||
12662 | /* Don't swap word field at the end - cntl field. */ | ||
12663 | if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) { | ||
12664 | n_error++; | ||
12665 | } | ||
12666 | } | ||
12667 | sum += *wbuf; /* Checksum calculated from word values. */ | ||
12668 | } | ||
12669 | /* Write checksum word. It will be swapped by AscWriteEEPWord(). */ | ||
12670 | *wbuf = sum; | ||
12671 | if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) { | ||
12672 | n_error++; | ||
12673 | } | ||
12674 | |||
12675 | /* Read EEPROM back again. */ | ||
12676 | wbuf = (ushort *) cfg_buf; | ||
12677 | /* | ||
12678 | * Read two config words; Byte-swapping done by AscReadEEPWord(). | ||
12679 | */ | ||
12680 | for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) { | ||
12681 | if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) { | ||
12682 | n_error++; | ||
12683 | } | ||
12684 | } | ||
12685 | if (bus_type & ASC_IS_VL) { | ||
12686 | cfg_beg = ASC_EEP_DVC_CFG_BEG_VL; | ||
12687 | cfg_end = ASC_EEP_MAX_DVC_ADDR_VL; | ||
12688 | } else { | ||
12689 | cfg_beg = ASC_EEP_DVC_CFG_BEG; | ||
12690 | cfg_end = ASC_EEP_MAX_DVC_ADDR; | ||
12691 | } | ||
12692 | for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) { | ||
12693 | if (s_addr <= uchar_end_in_config) { | ||
12694 | /* | ||
12695 | * Swap all char fields. Must unswap bytes already swapped | ||
12696 | * by AscReadEEPWord(). | ||
12697 | */ | ||
12698 | word = le16_to_cpu(AscReadEEPWord(iop_base, (uchar) s_addr)); | ||
12699 | } else { | ||
12700 | /* Don't swap word field at the end - cntl field. */ | ||
12701 | word = AscReadEEPWord(iop_base, (uchar) s_addr); | ||
12702 | } | ||
12703 | if (*wbuf != word) { | ||
12704 | n_error++; | ||
12705 | } | ||
12706 | } | ||
12707 | /* Read checksum; Byte swapping not needed. */ | ||
12708 | if (AscReadEEPWord(iop_base, (uchar) s_addr) != sum) { | ||
12709 | n_error++; | ||
12710 | } | ||
12711 | return (n_error); | ||
12712 | } | ||
12713 | |||
12714 | STATIC int __init | ||
12715 | AscSetEEPConfig( | ||
12716 | PortAddr iop_base, | ||
12717 | ASCEEP_CONFIG * cfg_buf, ushort bus_type | ||
12718 | ) | ||
12719 | { | ||
12720 | int retry; | ||
12721 | int n_error; | ||
12722 | |||
12723 | retry = 0; | ||
12724 | while (TRUE) { | ||
12725 | if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf, | ||
12726 | bus_type)) == 0) { | ||
12727 | break; | ||
12728 | } | ||
12729 | if (++retry > ASC_EEP_MAX_RETRY) { | ||
12730 | break; | ||
12731 | } | ||
12732 | } | ||
12733 | return (n_error); | ||
12734 | } | ||
12735 | |||
12736 | STATIC void | ||
12737 | AscAsyncFix( | ||
12738 | ASC_DVC_VAR *asc_dvc, | ||
12739 | uchar tid_no, | ||
12740 | ASC_SCSI_INQUIRY *inq) | ||
12741 | { | ||
12742 | uchar dvc_type; | ||
12743 | ASC_SCSI_BIT_ID_TYPE tid_bits; | ||
12744 | |||
12745 | dvc_type = ASC_INQ_DVC_TYPE(inq); | ||
12746 | tid_bits = ASC_TIX_TO_TARGET_ID(tid_no); | ||
12747 | |||
12748 | if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) | ||
12749 | { | ||
12750 | if (!(asc_dvc->init_sdtr & tid_bits)) | ||
12751 | { | ||
12752 | if ((dvc_type == TYPE_ROM) && | ||
12753 | (AscCompareString((uchar *) inq->vendor_id, | ||
12754 | (uchar *) "HP ", 3) == 0)) | ||
12755 | { | ||
12756 | asc_dvc->pci_fix_asyn_xfer_always |= tid_bits; | ||
12757 | } | ||
12758 | asc_dvc->pci_fix_asyn_xfer |= tid_bits; | ||
12759 | if ((dvc_type == TYPE_PROCESSOR) || | ||
12760 | (dvc_type == TYPE_SCANNER) || | ||
12761 | (dvc_type == TYPE_ROM) || | ||
12762 | (dvc_type == TYPE_TAPE)) | ||
12763 | { | ||
12764 | asc_dvc->pci_fix_asyn_xfer &= ~tid_bits; | ||
12765 | } | ||
12766 | |||
12767 | if (asc_dvc->pci_fix_asyn_xfer & tid_bits) | ||
12768 | { | ||
12769 | AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no, | ||
12770 | ASYN_SDTR_DATA_FIX_PCI_REV_AB); | ||
12771 | } | ||
12772 | } | ||
12773 | } | ||
12774 | return; | ||
12775 | } | ||
12776 | |||
12777 | STATIC int | ||
12778 | AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq) | ||
12779 | { | ||
12780 | if ((inq->add_len >= 32) && | ||
12781 | (AscCompareString((uchar *) inq->vendor_id, | ||
12782 | (uchar *) "QUANTUM XP34301", 15) == 0) && | ||
12783 | (AscCompareString((uchar *) inq->product_rev_level, | ||
12784 | (uchar *) "1071", 4) == 0)) | ||
12785 | { | ||
12786 | return 0; | ||
12787 | } | ||
12788 | return 1; | ||
12789 | } | ||
12790 | |||
12791 | STATIC void | ||
12792 | AscInquiryHandling(ASC_DVC_VAR *asc_dvc, | ||
12793 | uchar tid_no, ASC_SCSI_INQUIRY *inq) | ||
12794 | { | ||
12795 | ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no); | ||
12796 | ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng; | ||
12797 | |||
12798 | orig_init_sdtr = asc_dvc->init_sdtr; | ||
12799 | orig_use_tagged_qng = asc_dvc->use_tagged_qng; | ||
12800 | |||
12801 | asc_dvc->init_sdtr &= ~tid_bit; | ||
12802 | asc_dvc->cfg->can_tagged_qng &= ~tid_bit; | ||
12803 | asc_dvc->use_tagged_qng &= ~tid_bit; | ||
12804 | |||
12805 | if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) { | ||
12806 | if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) { | ||
12807 | asc_dvc->init_sdtr |= tid_bit; | ||
12808 | } | ||
12809 | if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) && | ||
12810 | ASC_INQ_CMD_QUEUE(inq)) { | ||
12811 | if (AscTagQueuingSafe(inq)) { | ||
12812 | asc_dvc->use_tagged_qng |= tid_bit; | ||
12813 | asc_dvc->cfg->can_tagged_qng |= tid_bit; | ||
12814 | } | ||
12815 | } | ||
12816 | } | ||
12817 | if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) { | ||
12818 | AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B, | ||
12819 | asc_dvc->cfg->disc_enable); | ||
12820 | AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B, | ||
12821 | asc_dvc->use_tagged_qng); | ||
12822 | AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B, | ||
12823 | asc_dvc->cfg->can_tagged_qng); | ||
12824 | |||
12825 | asc_dvc->max_dvc_qng[tid_no] = | ||
12826 | asc_dvc->cfg->max_tag_qng[tid_no]; | ||
12827 | AscWriteLramByte(asc_dvc->iop_base, | ||
12828 | (ushort) (ASCV_MAX_DVC_QNG_BEG + tid_no), | ||
12829 | asc_dvc->max_dvc_qng[tid_no]); | ||
12830 | } | ||
12831 | if (orig_init_sdtr != asc_dvc->init_sdtr) { | ||
12832 | AscAsyncFix(asc_dvc, tid_no, inq); | ||
12833 | } | ||
12834 | return; | ||
12835 | } | ||
12836 | |||
12837 | STATIC int | ||
12838 | AscCompareString( | ||
12839 | uchar *str1, | ||
12840 | uchar *str2, | ||
12841 | int len | ||
12842 | ) | ||
12843 | { | ||
12844 | int i; | ||
12845 | int diff; | ||
12846 | |||
12847 | for (i = 0; i < len; i++) { | ||
12848 | diff = (int) (str1[i] - str2[i]); | ||
12849 | if (diff != 0) | ||
12850 | return (diff); | ||
12851 | } | ||
12852 | return (0); | ||
12853 | } | ||
12854 | |||
12855 | STATIC uchar | ||
12856 | AscReadLramByte( | ||
12857 | PortAddr iop_base, | ||
12858 | ushort addr | ||
12859 | ) | ||
12860 | { | ||
12861 | uchar byte_data; | ||
12862 | ushort word_data; | ||
12863 | |||
12864 | if (isodd_word(addr)) { | ||
12865 | AscSetChipLramAddr(iop_base, addr - 1); | ||
12866 | word_data = AscGetChipLramData(iop_base); | ||
12867 | byte_data = (uchar) ((word_data >> 8) & 0xFF); | ||
12868 | } else { | ||
12869 | AscSetChipLramAddr(iop_base, addr); | ||
12870 | word_data = AscGetChipLramData(iop_base); | ||
12871 | byte_data = (uchar) (word_data & 0xFF); | ||
12872 | } | ||
12873 | return (byte_data); | ||
12874 | } | ||
12875 | STATIC ushort | ||
12876 | AscReadLramWord( | ||
12877 | PortAddr iop_base, | ||
12878 | ushort addr | ||
12879 | ) | ||
12880 | { | ||
12881 | ushort word_data; | ||
12882 | |||
12883 | AscSetChipLramAddr(iop_base, addr); | ||
12884 | word_data = AscGetChipLramData(iop_base); | ||
12885 | return (word_data); | ||
12886 | } | ||
12887 | |||
12888 | #if CC_VERY_LONG_SG_LIST | ||
12889 | STATIC ASC_DCNT | ||
12890 | AscReadLramDWord( | ||
12891 | PortAddr iop_base, | ||
12892 | ushort addr | ||
12893 | ) | ||
12894 | { | ||
12895 | ushort val_low, val_high; | ||
12896 | ASC_DCNT dword_data; | ||
12897 | |||
12898 | AscSetChipLramAddr(iop_base, addr); | ||
12899 | val_low = AscGetChipLramData(iop_base); | ||
12900 | val_high = AscGetChipLramData(iop_base); | ||
12901 | dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low; | ||
12902 | return (dword_data); | ||
12903 | } | ||
12904 | #endif /* CC_VERY_LONG_SG_LIST */ | ||
12905 | |||
12906 | STATIC void | ||
12907 | AscWriteLramWord( | ||
12908 | PortAddr iop_base, | ||
12909 | ushort addr, | ||
12910 | ushort word_val | ||
12911 | ) | ||
12912 | { | ||
12913 | AscSetChipLramAddr(iop_base, addr); | ||
12914 | AscSetChipLramData(iop_base, word_val); | ||
12915 | return; | ||
12916 | } | ||
12917 | |||
12918 | STATIC void | ||
12919 | AscWriteLramByte( | ||
12920 | PortAddr iop_base, | ||
12921 | ushort addr, | ||
12922 | uchar byte_val | ||
12923 | ) | ||
12924 | { | ||
12925 | ushort word_data; | ||
12926 | |||
12927 | if (isodd_word(addr)) { | ||
12928 | addr--; | ||
12929 | word_data = AscReadLramWord(iop_base, addr); | ||
12930 | word_data &= 0x00FF; | ||
12931 | word_data |= (((ushort) byte_val << 8) & 0xFF00); | ||
12932 | } else { | ||
12933 | word_data = AscReadLramWord(iop_base, addr); | ||
12934 | word_data &= 0xFF00; | ||
12935 | word_data |= ((ushort) byte_val & 0x00FF); | ||
12936 | } | ||
12937 | AscWriteLramWord(iop_base, addr, word_data); | ||
12938 | return; | ||
12939 | } | ||
12940 | |||
12941 | /* | ||
12942 | * Copy 2 bytes to LRAM. | ||
12943 | * | ||
12944 | * The source data is assumed to be in little-endian order in memory | ||
12945 | * and is maintained in little-endian order when written to LRAM. | ||
12946 | */ | ||
12947 | STATIC void | ||
12948 | AscMemWordCopyPtrToLram( | ||
12949 | PortAddr iop_base, | ||
12950 | ushort s_addr, | ||
12951 | uchar *s_buffer, | ||
12952 | int words | ||
12953 | ) | ||
12954 | { | ||
12955 | int i; | ||
12956 | |||
12957 | AscSetChipLramAddr(iop_base, s_addr); | ||
12958 | for (i = 0; i < 2 * words; i += 2) { | ||
12959 | /* | ||
12960 | * On a little-endian system the second argument below | ||
12961 | * produces a little-endian ushort which is written to | ||
12962 | * LRAM in little-endian order. On a big-endian system | ||
12963 | * the second argument produces a big-endian ushort which | ||
12964 | * is "transparently" byte-swapped by outpw() and written | ||
12965 | * in little-endian order to LRAM. | ||
12966 | */ | ||
12967 | outpw(iop_base + IOP_RAM_DATA, | ||
12968 | ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]); | ||
12969 | } | ||
12970 | return; | ||
12971 | } | ||
12972 | |||
12973 | /* | ||
12974 | * Copy 4 bytes to LRAM. | ||
12975 | * | ||
12976 | * The source data is assumed to be in little-endian order in memory | ||
12977 | * and is maintained in little-endian order when writen to LRAM. | ||
12978 | */ | ||
12979 | STATIC void | ||
12980 | AscMemDWordCopyPtrToLram( | ||
12981 | PortAddr iop_base, | ||
12982 | ushort s_addr, | ||
12983 | uchar *s_buffer, | ||
12984 | int dwords | ||
12985 | ) | ||
12986 | { | ||
12987 | int i; | ||
12988 | |||
12989 | AscSetChipLramAddr(iop_base, s_addr); | ||
12990 | for (i = 0; i < 4 * dwords; i += 4) { | ||
12991 | outpw(iop_base + IOP_RAM_DATA, | ||
12992 | ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */ | ||
12993 | outpw(iop_base + IOP_RAM_DATA, | ||
12994 | ((ushort) s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */ | ||
12995 | } | ||
12996 | return; | ||
12997 | } | ||
12998 | |||
12999 | /* | ||
13000 | * Copy 2 bytes from LRAM. | ||
13001 | * | ||
13002 | * The source data is assumed to be in little-endian order in LRAM | ||
13003 | * and is maintained in little-endian order when written to memory. | ||
13004 | */ | ||
13005 | STATIC void | ||
13006 | AscMemWordCopyPtrFromLram( | ||
13007 | PortAddr iop_base, | ||
13008 | ushort s_addr, | ||
13009 | uchar *d_buffer, | ||
13010 | int words | ||
13011 | ) | ||
13012 | { | ||
13013 | int i; | ||
13014 | ushort word; | ||
13015 | |||
13016 | AscSetChipLramAddr(iop_base, s_addr); | ||
13017 | for (i = 0; i < 2 * words; i += 2) { | ||
13018 | word = inpw(iop_base + IOP_RAM_DATA); | ||
13019 | d_buffer[i] = word & 0xff; | ||
13020 | d_buffer[i + 1] = (word >> 8) & 0xff; | ||
13021 | } | ||
13022 | return; | ||
13023 | } | ||
13024 | |||
13025 | STATIC ASC_DCNT | ||
13026 | AscMemSumLramWord( | ||
13027 | PortAddr iop_base, | ||
13028 | ushort s_addr, | ||
13029 | int words | ||
13030 | ) | ||
13031 | { | ||
13032 | ASC_DCNT sum; | ||
13033 | int i; | ||
13034 | |||
13035 | sum = 0L; | ||
13036 | for (i = 0; i < words; i++, s_addr += 2) { | ||
13037 | sum += AscReadLramWord(iop_base, s_addr); | ||
13038 | } | ||
13039 | return (sum); | ||
13040 | } | ||
13041 | |||
13042 | STATIC void | ||
13043 | AscMemWordSetLram( | ||
13044 | PortAddr iop_base, | ||
13045 | ushort s_addr, | ||
13046 | ushort set_wval, | ||
13047 | int words | ||
13048 | ) | ||
13049 | { | ||
13050 | int i; | ||
13051 | |||
13052 | AscSetChipLramAddr(iop_base, s_addr); | ||
13053 | for (i = 0; i < words; i++) { | ||
13054 | AscSetChipLramData(iop_base, set_wval); | ||
13055 | } | ||
13056 | return; | ||
13057 | } | ||
13058 | |||
13059 | |||
13060 | /* | ||
13061 | * --- Adv Library Functions | ||
13062 | */ | ||
13063 | |||
13064 | /* a_mcode.h */ | ||
13065 | |||
13066 | /* Microcode buffer is kept after initialization for error recovery. */ | ||
13067 | STATIC unsigned char _adv_asc3550_buf[] = { | ||
13068 | 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc, 0x01, 0x00, 0x48, 0xe4, | ||
13069 | 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, | ||
13070 | 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6, | ||
13071 | 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00, 0x00, 0xec, 0x85, 0xf0, | ||
13072 | 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, | ||
13073 | 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80, | ||
13074 | 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, | ||
13075 | 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, | ||
13076 | 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54, | ||
13077 | 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00, 0x3e, 0x00, 0x80, 0x00, | ||
13078 | 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, | ||
13079 | 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55, | ||
13080 | 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0, 0x03, 0xf7, 0x06, 0xf7, | ||
13081 | 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, | ||
13082 | 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0, | ||
13083 | 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, | ||
13084 | 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, | ||
13085 | 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0, | ||
13086 | 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, | ||
13087 | 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, | ||
13088 | 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15, | ||
13089 | 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, | ||
13090 | 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, | ||
13091 | 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, | ||
13092 | 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00, 0x9e, 0x00, 0xa8, 0x00, | ||
13093 | 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, | ||
13094 | 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08, | ||
13095 | 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x06, 0x12, | ||
13096 | 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, | ||
13097 | 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47, | ||
13098 | 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55, 0x14, 0x56, 0x77, 0x57, | ||
13099 | 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, | ||
13100 | 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff, | ||
13101 | 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24, | ||
13102 | 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, | ||
13103 | 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f, | ||
13104 | 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xcf, | ||
13105 | 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, | ||
13106 | 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, | ||
13107 | 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b, 0x02, 0xfe, 0xd4, 0x0c, | ||
13108 | 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, | ||
13109 | 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02, | ||
13110 | 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02, 0xfe, 0x46, 0xf0, 0xfe, | ||
13111 | 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, | ||
13112 | 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18, | ||
13113 | 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, | ||
13114 | 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, | ||
13115 | 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd, | ||
13116 | 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x17, 0x06, | ||
13117 | 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, | ||
13118 | 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f, | ||
13119 | 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe, 0x69, 0x10, 0x17, 0x06, | ||
13120 | 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, | ||
13121 | 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40, | ||
13122 | 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0x99, 0x01, | ||
13123 | 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, | ||
13124 | 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b, | ||
13125 | 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0, 0xfe, 0x56, 0x03, 0xfe, | ||
13126 | 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, | ||
13127 | 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04, | ||
13128 | 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40, 0x01, 0x0e, 0xac, 0x75, | ||
13129 | 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, | ||
13130 | 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4, | ||
13131 | 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe, 0x0a, 0xf0, 0xfe, 0x7a, | ||
13132 | 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, | ||
13133 | 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c, | ||
13134 | 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3, 0x0a, 0xca, 0x01, 0x0e, | ||
13135 | 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, | ||
13136 | 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f, | ||
13137 | 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2b, 0xff, 0x02, | ||
13138 | 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, | ||
13139 | 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64, | ||
13140 | 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d, 0xfe, 0x2a, 0x13, 0x2f, | ||
13141 | 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, | ||
13142 | 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12, | ||
13143 | 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, | ||
13144 | 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, | ||
13145 | 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, | ||
13146 | 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a, 0xfe, 0x70, 0x12, 0x49, | ||
13147 | 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, | ||
13148 | 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12, | ||
13149 | 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05, 0x11, 0xfe, 0xe3, 0x00, | ||
13150 | 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, | ||
13151 | 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08, | ||
13152 | 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01, 0x86, 0x24, 0x06, 0x12, | ||
13153 | 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, | ||
13154 | 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe, | ||
13155 | 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13, 0x47, 0x01, 0xa7, 0x26, | ||
13156 | 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, | ||
13157 | 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c, | ||
13158 | 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x14, | ||
13159 | 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, | ||
13160 | 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04, | ||
13161 | 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68, 0x06, 0x11, 0x9a, 0x01, | ||
13162 | 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, | ||
13163 | 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe, | ||
13164 | 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07, 0x8d, 0x81, 0x02, 0x22, | ||
13165 | 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, | ||
13166 | 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32, | ||
13167 | 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15, 0xfe, 0x1b, 0x00, 0x01, | ||
13168 | 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, | ||
13169 | 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d, | ||
13170 | 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, | ||
13171 | 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, | ||
13172 | 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02, | ||
13173 | 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x77, 0xfe, 0xca, | ||
13174 | 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, | ||
13175 | 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1, | ||
13176 | 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f, 0x40, 0x12, 0x58, 0x01, | ||
13177 | 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, | ||
13178 | 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, | ||
13179 | 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a, 0xfe, 0x2a, 0x12, 0xfe, | ||
13180 | 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, | ||
13181 | 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe, | ||
13182 | 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x39, 0x18, 0x3a, | ||
13183 | 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, | ||
13184 | 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80, | ||
13185 | 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x7a, 0x08, 0x8d, | ||
13186 | 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, | ||
13187 | 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c, | ||
13188 | 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe, 0x52, 0x12, 0xfe, 0x2c, | ||
13189 | 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, | ||
13190 | 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe, | ||
13191 | 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xb5, 0xfe, | ||
13192 | 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, | ||
13193 | 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33, | ||
13194 | 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a, 0xfe, 0x74, 0x18, 0x1c, | ||
13195 | 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, | ||
13196 | 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe, | ||
13197 | 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc, 0xfe, 0x83, 0x80, 0xfe, | ||
13198 | 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, | ||
13199 | 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf, | ||
13200 | 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e, 0x79, 0x56, 0x68, 0x57, | ||
13201 | 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, | ||
13202 | 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39, | ||
13203 | 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x10, 0x58, 0xfe, | ||
13204 | 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, | ||
13205 | 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe, | ||
13206 | 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08, 0x11, 0x9b, 0x09, 0x04, | ||
13207 | 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, | ||
13208 | 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12, | ||
13209 | 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9, 0x14, 0x7a, 0x01, 0x33, | ||
13210 | 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, | ||
13211 | 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10, | ||
13212 | 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x84, 0x05, 0xcb, 0x1c, | ||
13213 | 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, | ||
13214 | 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca, | ||
13215 | 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe, 0x22, 0x00, 0x02, 0x5a, | ||
13216 | 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, | ||
13217 | 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10, | ||
13218 | 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00, 0x2a, 0x13, 0xfe, 0x4e, | ||
13219 | 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, | ||
13220 | 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48, | ||
13221 | 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xdb, 0x10, 0x11, 0xfe, | ||
13222 | 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, | ||
13223 | 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42, | ||
13224 | 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c, 0x09, 0x04, 0x0b, 0xfe, | ||
13225 | 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, | ||
13226 | 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, | ||
13227 | 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x02, 0x29, | ||
13228 | 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, | ||
13229 | 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe, | ||
13230 | 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01, 0xe8, 0x59, 0x11, 0x2d, | ||
13231 | 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, | ||
13232 | 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe, | ||
13233 | 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, | ||
13234 | 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, | ||
13235 | 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00, | ||
13236 | 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa, 0xab, 0x70, 0x05, 0x6b, | ||
13237 | 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, | ||
13238 | 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01, | ||
13239 | 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e, 0x1d, 0xfe, 0xce, 0x45, | ||
13240 | 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, | ||
13241 | 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d, | ||
13242 | 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, | ||
13243 | 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, | ||
13244 | 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e, | ||
13245 | 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12, 0xce, 0x1e, 0x2d, 0x47, | ||
13246 | 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, | ||
13247 | 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02, | ||
13248 | 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, | ||
13249 | 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, | ||
13250 | 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01, | ||
13251 | 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, | ||
13252 | 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, | ||
13253 | 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24, | ||
13254 | 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, | ||
13255 | 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, | ||
13256 | 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04, | ||
13257 | 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xe1, | ||
13258 | 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, | ||
13259 | 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d, | ||
13260 | 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01, 0xe8, 0x11, 0xfe, 0xe9, | ||
13261 | 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, | ||
13262 | 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe, | ||
13263 | 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80, 0x40, 0x12, 0x20, 0x63, | ||
13264 | 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, | ||
13265 | 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe, | ||
13266 | 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x24, 0x69, 0x12, 0xc9, | ||
13267 | 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, | ||
13268 | 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe, | ||
13269 | 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c, 0x46, 0x1e, 0x20, 0xed, | ||
13270 | 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, | ||
13271 | 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d, | ||
13272 | 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46, 0xfa, 0xef, 0xfe, 0x42, | ||
13273 | 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, | ||
13274 | 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, | ||
13275 | 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e, 0x10, 0x07, 0x7e, 0x45, | ||
13276 | 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, | ||
13277 | 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe, | ||
13278 | 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b, 0xfe, 0x48, 0x12, 0x07, | ||
13279 | 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, | ||
13280 | 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe, | ||
13281 | 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b, 0x01, 0x08, 0x8c, 0x43, | ||
13282 | 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, | ||
13283 | 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04, | ||
13284 | 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe, 0xc6, 0x10, 0x1e, 0x58, | ||
13285 | 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, | ||
13286 | 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1, | ||
13287 | 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0xfe, | ||
13288 | 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, | ||
13289 | 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1, | ||
13290 | 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e, 0x58, 0xfe, 0x1f, 0x40, | ||
13291 | 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, | ||
13292 | 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39, | ||
13293 | 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06, 0x12, 0xcd, 0x02, 0x5b, | ||
13294 | 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, | ||
13295 | 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe, | ||
13296 | 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, | ||
13297 | 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, | ||
13298 | 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01, | ||
13299 | 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44, 0x01, 0x08, 0x1f, 0xa2, | ||
13300 | 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, | ||
13301 | 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda, | ||
13302 | 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1, 0x05, 0xc6, 0x28, 0x84, | ||
13303 | 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, | ||
13304 | 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02, | ||
13305 | 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06, 0x21, 0x44, 0x01, 0xfe, | ||
13306 | 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, | ||
13307 | 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05, | ||
13308 | 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xd8, 0x14, 0x02, 0x5c, | ||
13309 | 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, | ||
13310 | 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01, | ||
13311 | 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0xfe, 0xff, 0x7f, | ||
13312 | 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, | ||
13313 | 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, | ||
13314 | 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58, 0x03, 0x0a, 0x50, 0x01, | ||
13315 | 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, | ||
13316 | 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27, | ||
13317 | 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, | ||
13318 | 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, | ||
13319 | 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, | ||
13320 | 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe, 0xcc, 0x12, 0x49, 0x04, | ||
13321 | 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, | ||
13322 | 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83, | ||
13323 | 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c, 0x13, 0x06, 0xfe, 0x56, | ||
13324 | 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, | ||
13325 | 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4, | ||
13326 | 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90, 0x01, 0xba, 0xfe, 0x4e, | ||
13327 | 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, | ||
13328 | 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c, | ||
13329 | 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba, 0xfe, 0x9c, 0x14, 0xb7, | ||
13330 | 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, | ||
13331 | 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe, | ||
13332 | 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x0b, 0x01, | ||
13333 | 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, | ||
13334 | 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08, | ||
13335 | 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89, 0x4a, 0x01, 0x08, 0x03, | ||
13336 | 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, | ||
13337 | 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe, | ||
13338 | 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd, 0x01, 0x43, 0x1e, 0xcd, | ||
13339 | 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, | ||
13340 | 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88, | ||
13341 | 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3, 0x88, 0x03, 0x0a, 0x42, | ||
13342 | 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, | ||
13343 | 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17, | ||
13344 | 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, | ||
13345 | 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, | ||
13346 | 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10, | ||
13347 | 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58, 0x05, 0xfe, 0x66, 0x01, | ||
13348 | 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, | ||
13349 | 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6, | ||
13350 | 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17, 0x10, 0x71, 0xfe, 0x83, | ||
13351 | 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, | ||
13352 | 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, | ||
13353 | 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71, 0xfe, 0x30, 0xbc, 0xfe, | ||
13354 | 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, | ||
13355 | 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02, | ||
13356 | 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc, 0xfe, 0x1d, 0xf7, 0x4f, | ||
13357 | 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, | ||
13358 | 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63, | ||
13359 | 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14, 0x06, 0x37, 0x95, 0xa9, | ||
13360 | 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, | ||
13361 | 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c, | ||
13362 | 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x3c, 0x8a, 0x0a, | ||
13363 | 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, | ||
13364 | 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f, | ||
13365 | 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xf6, 0xfe, 0xd6, 0xf0, | ||
13366 | 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, | ||
13367 | 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f, | ||
13368 | 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68, 0xc8, 0xfe, 0x48, 0x55, | ||
13369 | 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, | ||
13370 | 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42, | ||
13371 | 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01, 0x0e, 0x73, 0x75, 0x03, | ||
13372 | 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, | ||
13373 | 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b, | ||
13374 | 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05, 0xfe, 0x94, 0x00, 0xfe, | ||
13375 | 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, | ||
13376 | 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe, | ||
13377 | 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1b, 0xfe, 0x5a, | ||
13378 | 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, | ||
13379 | 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14, | ||
13380 | 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9, 0x03, 0x25, 0xfe, 0xca, | ||
13381 | 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00, | ||
13382 | }; | ||
13383 | |||
13384 | STATIC unsigned short _adv_asc3550_size = | ||
13385 | sizeof(_adv_asc3550_buf); /* 0x13AD */ | ||
13386 | STATIC ADV_DCNT _adv_asc3550_chksum = | ||
13387 | 0x04D52DDDUL; /* Expanded little-endian checksum. */ | ||
13388 | |||
13389 | /* Microcode buffer is kept after initialization for error recovery. */ | ||
13390 | STATIC unsigned char _adv_asc38C0800_buf[] = { | ||
13391 | 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4, 0x01, 0x00, 0x48, 0xe4, | ||
13392 | 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, | ||
13393 | 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, | ||
13394 | 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0, 0x18, 0xf4, 0x08, 0x00, | ||
13395 | 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, | ||
13396 | 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00, | ||
13397 | 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13, 0xba, 0x13, 0x18, 0x40, | ||
13398 | 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, | ||
13399 | 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01, | ||
13400 | 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12, 0x08, 0x12, 0x02, 0x4a, | ||
13401 | 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, | ||
13402 | 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, | ||
13403 | 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d, 0x06, 0x13, 0x4c, 0x1c, | ||
13404 | 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, | ||
13405 | 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, | ||
13406 | 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa, 0x05, 0x00, 0x34, 0x00, | ||
13407 | 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, | ||
13408 | 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54, | ||
13409 | 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, | ||
13410 | 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, | ||
13411 | 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03, | ||
13412 | 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13, 0x12, 0x13, 0x24, 0x14, | ||
13413 | 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, | ||
13414 | 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55, | ||
13415 | 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0, 0x04, 0xf8, | ||
13416 | 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, | ||
13417 | 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01, | ||
13418 | 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08, 0x68, 0x08, 0x69, 0x08, | ||
13419 | 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, | ||
13420 | 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14, | ||
13421 | 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18, 0xca, 0x18, 0xe6, 0x19, | ||
13422 | 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, | ||
13423 | 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff, | ||
13424 | 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24, | ||
13425 | 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, | ||
13426 | 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11, | ||
13427 | 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xd6, | ||
13428 | 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, | ||
13429 | 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, | ||
13430 | 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d, 0x02, 0xfe, 0xc8, 0x0d, | ||
13431 | 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, | ||
13432 | 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02, | ||
13433 | 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02, 0xfe, 0x46, 0xf0, 0xfe, | ||
13434 | 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, | ||
13435 | 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14, | ||
13436 | 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, | ||
13437 | 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, | ||
13438 | 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd, | ||
13439 | 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x18, 0x06, | ||
13440 | 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, | ||
13441 | 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, | ||
13442 | 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe, 0x69, 0x10, 0x18, 0x06, | ||
13443 | 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, | ||
13444 | 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, | ||
13445 | 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x09, | ||
13446 | 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, | ||
13447 | 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, | ||
13448 | 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x40, 0x1c, 0x1c, | ||
13449 | 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, | ||
13450 | 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02, | ||
13451 | 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13, 0x21, 0x22, 0xa3, 0xb7, | ||
13452 | 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, | ||
13453 | 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27, | ||
13454 | 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe, 0x06, 0xf0, 0xfe, 0xc8, | ||
13455 | 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, | ||
13456 | 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19, | ||
13457 | 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x74, 0x01, 0xaf, 0x8c, | ||
13458 | 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, | ||
13459 | 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, | ||
13460 | 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d, 0xfe, 0x3c, 0x04, 0x3b, | ||
13461 | 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, | ||
13462 | 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe, | ||
13463 | 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0x4f, 0x79, 0x2a, | ||
13464 | 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, | ||
13465 | 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe, | ||
13466 | 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x08, 0x13, 0x32, 0x07, | ||
13467 | 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, | ||
13468 | 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6, | ||
13469 | 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36, 0x02, 0x2b, 0xfe, 0x42, | ||
13470 | 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, | ||
13471 | 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c, | ||
13472 | 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28, 0x17, 0xfe, 0x90, 0x05, | ||
13473 | 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, | ||
13474 | 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48, | ||
13475 | 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0x12, 0xfe, 0xe3, 0x00, | ||
13476 | 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, | ||
13477 | 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02, | ||
13478 | 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2, 0x08, 0x53, 0x05, 0xcb, | ||
13479 | 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, | ||
13480 | 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, | ||
13481 | 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb, 0x03, 0x5c, 0x28, 0xfe, | ||
13482 | 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, | ||
13483 | 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, | ||
13484 | 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62, 0x12, 0x03, 0x45, 0x28, | ||
13485 | 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, | ||
13486 | 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2, | ||
13487 | 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01, 0xfe, 0xcc, 0x15, 0x1d, | ||
13488 | 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, | ||
13489 | 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb, | ||
13490 | 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, | ||
13491 | 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, | ||
13492 | 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01, | ||
13493 | 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38, 0x12, 0x08, 0x05, 0x1a, | ||
13494 | 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, | ||
13495 | 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe, | ||
13496 | 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b, 0xfe, 0x09, 0x6f, 0xba, | ||
13497 | 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, | ||
13498 | 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01, | ||
13499 | 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe, 0x2c, 0x90, 0xfe, 0xae, | ||
13500 | 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, | ||
13501 | 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe, | ||
13502 | 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b, 0x37, 0x01, 0xb3, 0xb8, | ||
13503 | 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, | ||
13504 | 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c, | ||
13505 | 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d, 0x14, 0x3e, 0xfe, 0x4a, | ||
13506 | 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, | ||
13507 | 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe, | ||
13508 | 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, | ||
13509 | 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, | ||
13510 | 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e, | ||
13511 | 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe, 0x9a, 0x08, 0xc6, 0xfe, | ||
13512 | 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, | ||
13513 | 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12, | ||
13514 | 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e, 0x1c, 0x02, 0xfe, 0x18, | ||
13515 | 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, | ||
13516 | 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7, | ||
13517 | 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18, 0xfe, 0xf1, 0x18, 0xfe, | ||
13518 | 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, | ||
13519 | 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5, | ||
13520 | 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18, 0x0b, 0xb6, 0xfe, 0xbf, | ||
13521 | 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, | ||
13522 | 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5, | ||
13523 | 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15, 0x9d, 0x01, 0x36, 0x10, | ||
13524 | 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, | ||
13525 | 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe, | ||
13526 | 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0x08, 0x05, | ||
13527 | 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, | ||
13528 | 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49, | ||
13529 | 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18, 0x8f, 0xfe, 0xe3, 0x54, | ||
13530 | 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, | ||
13531 | 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b, | ||
13532 | 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00, 0xad, 0xfe, 0x01, 0x59, | ||
13533 | 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, | ||
13534 | 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b, | ||
13535 | 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63, 0x02, 0x4a, 0x08, 0x05, | ||
13536 | 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, | ||
13537 | 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a, | ||
13538 | 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29, 0x61, 0x0c, 0x7f, 0x14, | ||
13539 | 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, | ||
13540 | 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef, | ||
13541 | 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40, 0xe4, 0x08, 0x05, 0x1f, | ||
13542 | 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, | ||
13543 | 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05, | ||
13544 | 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19, 0x81, 0x50, 0xfe, 0x10, | ||
13545 | 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, | ||
13546 | 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c, | ||
13547 | 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7, 0x08, 0x05, 0x0a, 0xfe, | ||
13548 | 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, | ||
13549 | 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed, | ||
13550 | 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe, 0x00, 0xff, 0x35, 0xfe, | ||
13551 | 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, | ||
13552 | 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe, | ||
13553 | 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, | ||
13554 | 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, | ||
13555 | 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0, | ||
13556 | 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea, 0x0b, 0x10, 0x58, 0xfe, | ||
13557 | 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, | ||
13558 | 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34, | ||
13559 | 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20, 0x0c, 0x1c, 0x34, 0x94, | ||
13560 | 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, | ||
13561 | 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33, | ||
13562 | 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24, 0x33, 0x31, 0xdf, 0xbc, | ||
13563 | 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, | ||
13564 | 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28, | ||
13565 | 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x44, 0xfe, 0x28, 0x00, | ||
13566 | 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, | ||
13567 | 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10, | ||
13568 | 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xac, | ||
13569 | 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, | ||
13570 | 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08, | ||
13571 | 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05, 0x1a, 0xfe, 0x58, 0x12, | ||
13572 | 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, | ||
13573 | 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10, | ||
13574 | 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10, 0xfe, 0x13, 0x00, 0xfe, | ||
13575 | 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, | ||
13576 | 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe, | ||
13577 | 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0, 0xb4, 0x15, 0xfe, 0x31, | ||
13578 | 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, | ||
13579 | 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75, | ||
13580 | 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x44, 0x48, | ||
13581 | 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, | ||
13582 | 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d, | ||
13583 | 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0xce, 0x47, 0xfe, 0xad, | ||
13584 | 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, | ||
13585 | 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06, | ||
13586 | 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe, 0x3a, 0x01, 0x56, 0xfe, | ||
13587 | 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, | ||
13588 | 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, | ||
13589 | 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13, 0x15, 0x1a, 0x39, 0xa0, | ||
13590 | 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, | ||
13591 | 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12, | ||
13592 | 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12, 0x22, 0x9f, 0xb7, 0x13, | ||
13593 | 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, | ||
13594 | 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc, | ||
13595 | 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21, 0xfe, 0x00, 0xcc, 0x04, | ||
13596 | 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, | ||
13597 | 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe, | ||
13598 | 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x0a, 0xfe, 0x3c, 0x50, | ||
13599 | 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, | ||
13600 | 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01, | ||
13601 | 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, | ||
13602 | 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, | ||
13603 | 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79, | ||
13604 | 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, | ||
13605 | |||
13606 | 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, | ||
13607 | 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52, | ||
13608 | 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc, 0x0f, 0x44, 0x11, 0x0f, | ||
13609 | 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, | ||
13610 | 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, | ||
13611 | 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x04, 0x42, | ||
13612 | 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, | ||
13613 | 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f, | ||
13614 | 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, | ||
13615 | 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, | ||
13616 | 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14, | ||
13617 | 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d, 0xfe, 0x01, 0xec, 0xa2, | ||
13618 | 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, | ||
13619 | 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07, | ||
13620 | 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17, 0xfe, 0x32, 0x12, 0x07, | ||
13621 | 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, | ||
13622 | 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d, | ||
13623 | 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d, 0x32, 0x07, 0xa6, 0xfe, | ||
13624 | 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, | ||
13625 | 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03, | ||
13626 | 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21, 0x0c, 0x7f, 0x0c, 0x80, | ||
13627 | 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, | ||
13628 | 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f, | ||
13629 | 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40, 0x88, 0x9b, 0x2e, 0x9c, | ||
13630 | 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, | ||
13631 | 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61, | ||
13632 | 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50, | ||
13633 | 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, | ||
13634 | 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d, | ||
13635 | 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23, 0x72, 0x01, 0xaf, 0x1e, | ||
13636 | 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, | ||
13637 | 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19, | ||
13638 | 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, | ||
13639 | 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, | ||
13640 | 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8, | ||
13641 | 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53, 0x05, 0x1f, 0x35, 0xa9, | ||
13642 | 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, | ||
13643 | 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35, | ||
13644 | 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x03, 0x5c, 0xc1, 0x0c, | ||
13645 | 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, | ||
13646 | 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1, | ||
13647 | 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a, 0xf4, 0x06, 0xea, 0x32, | ||
13648 | 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, | ||
13649 | 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13, | ||
13650 | 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0, 0x13, 0x1c, 0xfe, 0xd0, | ||
13651 | 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, | ||
13652 | 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f, | ||
13653 | 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, | ||
13654 | 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, | ||
13655 | 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03, | ||
13656 | 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52, 0xfe, 0x00, 0x7d, 0xfe, | ||
13657 | 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, | ||
13658 | 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01, | ||
13659 | 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, | ||
13660 | 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, | ||
13661 | 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee, | ||
13662 | 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c, 0x30, 0xfe, 0x78, 0x10, | ||
13663 | 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, | ||
13664 | 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00, | ||
13665 | 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28, 0x10, 0x69, 0x06, 0xfe, | ||
13666 | 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, | ||
13667 | 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe, | ||
13668 | 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4, 0x9e, 0xfe, 0xf3, 0x10, | ||
13669 | 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, | ||
13670 | 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, | ||
13671 | 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d, 0xf4, 0x00, 0xe9, 0x91, | ||
13672 | 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, | ||
13673 | 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76, | ||
13674 | 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x19, 0x01, 0x0b, | ||
13675 | 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, | ||
13676 | 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8, | ||
13677 | 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, | ||
13678 | 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, | ||
13679 | 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06, | ||
13680 | 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e, 0x07, 0x11, 0xae, 0x09, | ||
13681 | 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, | ||
13682 | 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e, | ||
13683 | 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x4c, | ||
13684 | 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, | ||
13685 | 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, | ||
13686 | 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4, 0x17, 0xad, 0x9a, 0x1b, | ||
13687 | 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, | ||
13688 | 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe, | ||
13689 | 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, | ||
13690 | 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, | ||
13691 | 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75, | ||
13692 | 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x2e, 0x97, 0xfe, 0x5a, | ||
13693 | 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, | ||
13694 | 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe, | ||
13695 | 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0xcb, 0x97, 0xfe, 0x92, | ||
13696 | 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, | ||
13697 | 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d, | ||
13698 | 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x9a, 0x5b, 0x41, 0xfe, | ||
13699 | 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, | ||
13700 | 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39, | ||
13701 | 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04, 0xfe, 0x7e, 0x18, 0x1e, | ||
13702 | 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, | ||
13703 | 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09, | ||
13704 | 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, | ||
13705 | 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, | ||
13706 | 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14, | ||
13707 | 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c, 0xe7, 0x0a, 0x10, 0xfe, | ||
13708 | 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, | ||
13709 | 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b, | ||
13710 | 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77, 0x13, 0xa3, 0x04, 0x09, | ||
13711 | 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, | ||
13712 | 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09, | ||
13713 | 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe, 0x1c, 0x19, 0x03, 0xfe, | ||
13714 | 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, | ||
13715 | 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b, | ||
13716 | 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe, 0x08, 0x10, 0x03, 0xfe, | ||
13717 | 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, | ||
13718 | 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00, | ||
13719 | 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19, 0x04, 0x07, 0x7e, 0xfe, | ||
13720 | 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, | ||
13721 | 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07, | ||
13722 | 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59, 0xa9, 0xb8, 0x04, 0x15, | ||
13723 | 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, | ||
13724 | 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0, | ||
13725 | 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00, | ||
13726 | }; | ||
13727 | |||
13728 | STATIC unsigned short _adv_asc38C0800_size = | ||
13729 | sizeof(_adv_asc38C0800_buf); /* 0x14E1 */ | ||
13730 | STATIC ADV_DCNT _adv_asc38C0800_chksum = | ||
13731 | 0x050D3FD8UL; /* Expanded little-endian checksum. */ | ||
13732 | |||
13733 | /* Microcode buffer is kept after initialization for error recovery. */ | ||
13734 | STATIC unsigned char _adv_asc38C1600_buf[] = { | ||
13735 | 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0, 0x18, 0xe4, 0x01, 0x00, | ||
13736 | 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, | ||
13737 | 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0, | ||
13738 | 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00, 0x98, 0x57, 0x01, 0xe6, | ||
13739 | 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, | ||
13740 | 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0, | ||
13741 | 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01, 0x06, 0x13, 0x0c, 0x1c, | ||
13742 | 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, | ||
13743 | 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea, | ||
13744 | 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x04, 0x13, 0xbb, 0x55, | ||
13745 | 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, | ||
13746 | 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c, | ||
13747 | 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, | ||
13748 | 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, | ||
13749 | 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48, | ||
13750 | 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x06, 0x00, | ||
13751 | 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, | ||
13752 | 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0, | ||
13753 | 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, | ||
13754 | 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, | ||
13755 | 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16, | ||
13756 | 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, | ||
13757 | 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, | ||
13758 | 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c, | ||
13759 | 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x42, 0x1d, 0x08, 0x44, | ||
13760 | 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, | ||
13761 | 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, | ||
13762 | 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0xa8, 0x00, 0xaa, 0x00, | ||
13763 | 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, | ||
13764 | 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d, | ||
13765 | 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10, 0xf3, 0x10, 0x06, 0x12, | ||
13766 | 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, | ||
13767 | 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff, | ||
13768 | 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24, | ||
13769 | 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, | ||
13770 | 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13, | ||
13771 | 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xe8, | ||
13772 | 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, | ||
13773 | 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, | ||
13774 | 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d, 0x05, 0xfe, 0x08, 0x0f, | ||
13775 | 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, | ||
13776 | 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90, | ||
13777 | 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8, 0x02, 0xfe, 0x46, 0xf0, | ||
13778 | 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, | ||
13779 | 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07, | ||
13780 | 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02, 0x1c, 0xf5, 0xfe, 0x1e, | ||
13781 | 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, | ||
13782 | 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe, | ||
13783 | 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x1c, | ||
13784 | 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, | ||
13785 | 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01, | ||
13786 | 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09, 0x1a, 0x31, 0xfe, 0x69, | ||
13787 | 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, | ||
13788 | 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51, | ||
13789 | 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, | ||
13790 | 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, | ||
13791 | 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30, | ||
13792 | 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0, 0xfe, 0xe4, 0x01, 0xfe, | ||
13793 | 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, | ||
13794 | 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f, | ||
13795 | 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05, 0x70, 0x37, 0xfe, 0x48, | ||
13796 | 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, | ||
13797 | 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe, | ||
13798 | 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32, 0x15, 0xfe, 0xe4, 0x00, | ||
13799 | 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, | ||
13800 | 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b, | ||
13801 | 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xfe, 0x46, 0x1c, | ||
13802 | 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, | ||
13803 | 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77, | ||
13804 | 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, | ||
13805 | 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, | ||
13806 | 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01, | ||
13807 | 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25, 0xee, 0xfe, 0x4c, 0x44, | ||
13808 | 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, | ||
13809 | 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe, | ||
13810 | 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10, 0x13, 0x34, 0xfe, 0x4c, | ||
13811 | 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, | ||
13812 | 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f, | ||
13813 | 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f, 0xfe, 0xa4, 0x0e, 0x05, | ||
13814 | 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, | ||
13815 | 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46, | ||
13816 | 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04, 0xfe, 0x87, 0x83, 0xfe, | ||
13817 | 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, | ||
13818 | 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06, | ||
13819 | 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda, 0x05, 0xd0, 0x54, 0x01, | ||
13820 | 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, | ||
13821 | 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, | ||
13822 | 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01, 0x38, 0xfe, 0x4a, 0xf0, | ||
13823 | 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, | ||
13824 | 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0, | ||
13825 | 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe, 0x1c, 0x00, 0x4d, 0x01, | ||
13826 | 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, | ||
13827 | 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, | ||
13828 | 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13, 0x03, 0xb6, 0x1e, 0xfe, | ||
13829 | 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, | ||
13830 | 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68, | ||
13831 | 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x03, 0x9a, 0x1e, 0xfe, | ||
13832 | 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, | ||
13833 | 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00, | ||
13834 | 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17, 0xfe, 0xea, 0x06, 0x01, | ||
13835 | 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, | ||
13836 | 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae, | ||
13837 | 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a, 0x1e, 0xfe, 0x1a, 0x12, | ||
13838 | 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, | ||
13839 | 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6, | ||
13840 | 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x17, 0xfe, | ||
13841 | 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, | ||
13842 | 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05, | ||
13843 | 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0x9c, 0x32, 0x5f, | ||
13844 | 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, | ||
13845 | 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29, | ||
13846 | 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, | ||
13847 | 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, | ||
13848 | 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13, | ||
13849 | 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, | ||
13850 | 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, | ||
13851 | 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c, | ||
13852 | 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x53, 0x63, 0x4e, | ||
13853 | 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, | ||
13854 | 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c, | ||
13855 | 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe, 0x1e, 0xfe, 0x99, 0x58, | ||
13856 | 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, | ||
13857 | 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a, | ||
13858 | 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40, 0x01, 0x0c, 0x61, 0x65, | ||
13859 | 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, | ||
13860 | 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e, | ||
13861 | 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e, 0x01, 0xfe, 0xfe, 0x1e, | ||
13862 | 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, | ||
13863 | 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b, | ||
13864 | 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04, 0xfe, 0x9f, 0x83, 0x33, | ||
13865 | 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, | ||
13866 | 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e, | ||
13867 | 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90, 0x04, 0xfe, 0xc0, 0x93, | ||
13868 | 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, | ||
13869 | 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, | ||
13870 | 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5, | ||
13871 | 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, | ||
13872 | 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41, | ||
13873 | 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07, 0xfe, 0x14, 0x12, 0x01, | ||
13874 | 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, | ||
13875 | 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe, | ||
13876 | 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe, 0x92, 0x10, 0xc4, 0xf6, | ||
13877 | 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, | ||
13878 | 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0, | ||
13879 | 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07, 0x1b, 0xbf, 0xd4, 0x5b, | ||
13880 | 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, | ||
13881 | 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74, | ||
13882 | 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78, 0x0f, 0x4d, 0x01, 0xfe, | ||
13883 | 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, | ||
13884 | 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21, | ||
13885 | 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe, 0x83, 0x83, 0xfe, 0xc9, | ||
13886 | 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, | ||
13887 | 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b, | ||
13888 | 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0x10, | ||
13889 | 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, | ||
13890 | 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64, | ||
13891 | 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97, 0x10, 0x98, 0x91, 0x6c, | ||
13892 | 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, | ||
13893 | 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, | ||
13894 | 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x01, 0x0c, | ||
13895 | 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, | ||
13896 | 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe, | ||
13897 | 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb, 0x01, 0x0c, 0x06, 0x0d, | ||
13898 | 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, | ||
13899 | 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e, | ||
13900 | 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, | ||
13901 | 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, | ||
13902 | 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51, | ||
13903 | 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe, 0x76, 0x10, 0xac, 0xfe, | ||
13904 | 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, | ||
13905 | 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92, | ||
13906 | 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2, 0x0c, 0xfe, 0x3e, 0x10, | ||
13907 | 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, | ||
13908 | 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94, | ||
13909 | 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3, 0xfe, 0xcc, 0xf0, 0xef, | ||
13910 | 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, | ||
13911 | 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5, | ||
13912 | 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32, 0x2f, 0xfe, 0x3e, 0x0d, | ||
13913 | 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, | ||
13914 | 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99, | ||
13915 | 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8, 0x9c, 0x2f, 0xfe, 0x8c, | ||
13916 | 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, | ||
13917 | 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13, | ||
13918 | 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b, 0xfe, 0xda, 0x0e, 0x0a, | ||
13919 | 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, | ||
13920 | 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85, | ||
13921 | 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe, 0xcc, 0x10, 0x01, 0xa7, | ||
13922 | 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, | ||
13923 | 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2, | ||
13924 | 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x40, 0x15, | ||
13925 | 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, | ||
13926 | 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe, | ||
13927 | 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, | ||
13928 | 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, | ||
13929 | 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19, | ||
13930 | 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19, 0xfe, 0x41, 0x00, 0xa2, | ||
13931 | 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, | ||
13932 | 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c, | ||
13933 | 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01, 0xfe, 0xd4, 0x11, 0x05, | ||
13934 | 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, | ||
13935 | 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56, | ||
13936 | 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01, 0x0c, 0x06, 0x28, 0xfe, | ||
13937 | 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, | ||
13938 | 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe, | ||
13939 | 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x05, | ||
13940 | 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, | ||
13941 | 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b, | ||
13942 | 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe, 0xf0, 0x1a, 0x03, 0xfe, | ||
13943 | 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, | ||
13944 | 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b, | ||
13945 | 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02, 0xea, 0xe7, 0x53, 0x92, | ||
13946 | 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, | ||
13947 | 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e, | ||
13948 | 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02, 0x26, 0x02, 0x21, 0x96, | ||
13949 | 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, | ||
13950 | 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe, | ||
13951 | 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe, 0x00, 0xcc, 0x02, 0xfe, | ||
13952 | 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, | ||
13953 | 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80, | ||
13954 | 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe, 0x1d, 0x80, 0x04, 0xfe, | ||
13955 | 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, | ||
13956 | 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, | ||
13957 | 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09, 0x56, 0xfb, 0x01, 0xfe, | ||
13958 | 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, | ||
13959 | 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e, | ||
13960 | 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe, 0x96, 0x90, 0x04, 0xfe, | ||
13961 | 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, | ||
13962 | 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01, | ||
13963 | 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40, 0x21, 0x2c, 0xfe, 0x00, | ||
13964 | 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, | ||
13965 | 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, | ||
13966 | 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10, 0x66, 0x10, 0x55, 0x10, | ||
13967 | 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, | ||
13968 | 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, | ||
13969 | 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, | ||
13970 | 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, | ||
13971 | 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47, | ||
13972 | 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01, 0xa7, 0x90, 0x34, 0x60, | ||
13973 | 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, | ||
13974 | 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, | ||
13975 | 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, | ||
13976 | 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, | ||
13977 | 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e, | ||
13978 | 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01, 0xf4, 0xfe, 0xdd, 0x10, | ||
13979 | 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, | ||
13980 | 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23, | ||
13981 | 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09, 0x24, 0xfe, 0x12, 0x12, | ||
13982 | 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, | ||
13983 | 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43, | ||
13984 | 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80, 0x13, 0x01, 0x0c, 0x06, | ||
13985 | 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, | ||
13986 | 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10, | ||
13987 | 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49, 0x88, 0x20, 0x6e, 0x01, | ||
13988 | 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, | ||
13989 | 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe, | ||
13990 | 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe, 0xe5, | ||
13991 | 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, | ||
13992 | 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50, | ||
13993 | 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x68, 0x3b, | ||
13994 | 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, | ||
13995 | 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25, | ||
13996 | 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01, 0xa6, 0x23, 0x3f, 0x1b, | ||
13997 | 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, | ||
13998 | 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01, | ||
13999 | 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, | ||
14000 | 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, | ||
14001 | 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08, | ||
14002 | 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03, 0xb6, 0x1e, 0x83, 0x01, | ||
14003 | 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, | ||
14004 | 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82, | ||
14005 | 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e, 0x05, 0x72, 0xfe, 0xc0, | ||
14006 | 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, | ||
14007 | 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd, | ||
14008 | 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe, 0xe8, 0x14, 0x01, 0xa6, | ||
14009 | 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, | ||
14010 | 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, | ||
14011 | 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd, 0x09, | ||
14012 | 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, | ||
14013 | 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72, | ||
14014 | 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0xc0, 0x19, 0x05, | ||
14015 | 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, | ||
14016 | 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32, | ||
14017 | 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0xfe, 0xff, | ||
14018 | 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, | ||
14019 | 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, | ||
14020 | 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e, 0x02, 0x13, 0x58, 0xff, | ||
14021 | 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, | ||
14022 | 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54, | ||
14023 | 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07, 0x7c, 0x3a, 0x0b, 0x0e, | ||
14024 | 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, | ||
14025 | 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe, | ||
14026 | 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77, 0x02, 0x01, 0xc6, 0xfe, | ||
14027 | 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, | ||
14028 | 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe, | ||
14029 | 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12, 0x48, 0xfe, 0x08, 0x17, | ||
14030 | 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, | ||
14031 | 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55, | ||
14032 | 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x1c, 0x63, 0x13, | ||
14033 | 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, | ||
14034 | 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60, | ||
14035 | 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8, 0x00, 0x1c, 0x95, 0x13, | ||
14036 | 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, | ||
14037 | 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b, | ||
14038 | 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x49, | ||
14039 | 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, | ||
14040 | 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13, | ||
14041 | 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xbe, 0xfe, 0x03, | ||
14042 | 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, | ||
14043 | 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9, | ||
14044 | 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, | ||
14045 | 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, | ||
14046 | 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e, | ||
14047 | 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10, 0xfe, 0x40, 0x5a, 0x23, | ||
14048 | 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, | ||
14049 | 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe, | ||
14050 | 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe, 0x43, 0x48, 0x2d, 0x93, | ||
14051 | 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, | ||
14052 | 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0, | ||
14053 | 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa, 0x18, 0x45, 0xfe, 0x1c, | ||
14054 | 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, | ||
14055 | 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01, | ||
14056 | 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe, 0x7e, 0x01, 0xfe, 0xc8, | ||
14057 | 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, | ||
14058 | 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14, | ||
14059 | 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, | ||
14060 | 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, | ||
14061 | 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1, | ||
14062 | 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01, 0x08, 0x02, 0x50, 0x02, | ||
14063 | 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, | ||
14064 | 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe, | ||
14065 | 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17, 0x74, 0x5f, 0xcc, 0x01, | ||
14066 | 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, | ||
14067 | 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, | ||
14068 | 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13, 0x16, 0xfe, 0x64, 0x1a, | ||
14069 | 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, | ||
14070 | 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, | ||
14071 | 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa, 0xfe, 0x80, 0xe7, 0x1a, | ||
14072 | 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, | ||
14073 | 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80, | ||
14074 | 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x0a, | ||
14075 | 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, | ||
14076 | 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3, | ||
14077 | 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe, 0xf4, 0x1a, 0xfe, 0xfa, | ||
14078 | 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, | ||
14079 | 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07, | ||
14080 | 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x24, 0xb1, 0xfe, | ||
14081 | 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, | ||
14082 | 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1, | ||
14083 | 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe, 0xaf, 0x19, 0xfe, 0x98, | ||
14084 | 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, | ||
14085 | 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04, | ||
14086 | 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a, 0x7c, 0x12, 0xfe, 0x0f, | ||
14087 | 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, | ||
14088 | 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe, | ||
14089 | 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee, 0x1b, 0xfe, 0x36, 0x14, | ||
14090 | 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, | ||
14091 | 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45, | ||
14092 | 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe, 0x39, 0xf0, 0x75, 0x26, | ||
14093 | 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, | ||
14094 | 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13, | ||
14095 | 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, | ||
14096 | 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, | ||
14097 | 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01, | ||
14098 | 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14, 0x56, | ||
14099 | 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, | ||
14100 | 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80, | ||
14101 | 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, | ||
14102 | 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, | ||
14103 | 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44, | ||
14104 | 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09, 0x1a, 0xa4, 0x0a, 0x67, | ||
14105 | 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, | ||
14106 | 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b, | ||
14107 | 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10, 0xfe, 0x4e, 0xe4, 0xfe, | ||
14108 | 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, | ||
14109 | 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1, | ||
14110 | 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, | ||
14111 | 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, | ||
14112 | 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8, | ||
14113 | 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe, 0x1a, 0x10, 0x09, 0x0d, | ||
14114 | 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, | ||
14115 | 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08, | ||
14116 | 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e, 0xfe, 0x82, 0xf0, 0xfe, | ||
14117 | 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, | ||
14118 | 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82, | ||
14119 | 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86, 0x83, 0x33, 0x0b, 0x0e, | ||
14120 | 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, | ||
14121 | 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80, | ||
14122 | 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04, 0xfe, 0x99, 0x83, 0xfe, | ||
14123 | 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, | ||
14124 | 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, | ||
14125 | 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x08, 0x90, 0x04, | ||
14126 | 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, | ||
14127 | 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, | ||
14128 | 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x3c, 0x90, 0x04, | ||
14129 | 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, | ||
14130 | 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00, | ||
14131 | }; | ||
14132 | |||
14133 | STATIC unsigned short _adv_asc38C1600_size = | ||
14134 | sizeof(_adv_asc38C1600_buf); /* 0x1673 */ | ||
14135 | STATIC ADV_DCNT _adv_asc38C1600_chksum = | ||
14136 | 0x0604EF77UL; /* Expanded little-endian checksum. */ | ||
14137 | |||
14138 | /* a_init.c */ | ||
14139 | /* | ||
14140 | * EEPROM Configuration. | ||
14141 | * | ||
14142 | * All drivers should use this structure to set the default EEPROM | ||
14143 | * configuration. The BIOS now uses this structure when it is built. | ||
14144 | * Additional structure information can be found in a_condor.h where | ||
14145 | * the structure is defined. | ||
14146 | * | ||
14147 | * The *_Field_IsChar structs are needed to correct for endianness. | ||
14148 | * These values are read from the board 16 bits at a time directly | ||
14149 | * into the structs. Because some fields are char, the values will be | ||
14150 | * in the wrong order. The *_Field_IsChar tells when to flip the | ||
14151 | * bytes. Data read and written to PCI memory is automatically swapped | ||
14152 | * on big-endian platforms so char fields read as words are actually being | ||
14153 | * unswapped on big-endian platforms. | ||
14154 | */ | ||
14155 | STATIC ADVEEP_3550_CONFIG | ||
14156 | Default_3550_EEPROM_Config __initdata = { | ||
14157 | ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */ | ||
14158 | 0x0000, /* cfg_msw */ | ||
14159 | 0xFFFF, /* disc_enable */ | ||
14160 | 0xFFFF, /* wdtr_able */ | ||
14161 | 0xFFFF, /* sdtr_able */ | ||
14162 | 0xFFFF, /* start_motor */ | ||
14163 | 0xFFFF, /* tagqng_able */ | ||
14164 | 0xFFFF, /* bios_scan */ | ||
14165 | 0, /* scam_tolerant */ | ||
14166 | 7, /* adapter_scsi_id */ | ||
14167 | 0, /* bios_boot_delay */ | ||
14168 | 3, /* scsi_reset_delay */ | ||
14169 | 0, /* bios_id_lun */ | ||
14170 | 0, /* termination */ | ||
14171 | 0, /* reserved1 */ | ||
14172 | 0xFFE7, /* bios_ctrl */ | ||
14173 | 0xFFFF, /* ultra_able */ | ||
14174 | 0, /* reserved2 */ | ||
14175 | ASC_DEF_MAX_HOST_QNG, /* max_host_qng */ | ||
14176 | ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */ | ||
14177 | 0, /* dvc_cntl */ | ||
14178 | 0, /* bug_fix */ | ||
14179 | 0, /* serial_number_word1 */ | ||
14180 | 0, /* serial_number_word2 */ | ||
14181 | 0, /* serial_number_word3 */ | ||
14182 | 0, /* check_sum */ | ||
14183 | { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */ | ||
14184 | 0, /* dvc_err_code */ | ||
14185 | 0, /* adv_err_code */ | ||
14186 | 0, /* adv_err_addr */ | ||
14187 | 0, /* saved_dvc_err_code */ | ||
14188 | 0, /* saved_adv_err_code */ | ||
14189 | 0, /* saved_adv_err_addr */ | ||
14190 | 0 /* num_of_err */ | ||
14191 | }; | ||
14192 | |||
14193 | STATIC ADVEEP_3550_CONFIG | ||
14194 | ADVEEP_3550_Config_Field_IsChar __initdata = { | ||
14195 | 0, /* cfg_lsw */ | ||
14196 | 0, /* cfg_msw */ | ||
14197 | 0, /* -disc_enable */ | ||
14198 | 0, /* wdtr_able */ | ||
14199 | 0, /* sdtr_able */ | ||
14200 | 0, /* start_motor */ | ||
14201 | 0, /* tagqng_able */ | ||
14202 | 0, /* bios_scan */ | ||
14203 | 0, /* scam_tolerant */ | ||
14204 | 1, /* adapter_scsi_id */ | ||
14205 | 1, /* bios_boot_delay */ | ||
14206 | 1, /* scsi_reset_delay */ | ||
14207 | 1, /* bios_id_lun */ | ||
14208 | 1, /* termination */ | ||
14209 | 1, /* reserved1 */ | ||
14210 | 0, /* bios_ctrl */ | ||
14211 | 0, /* ultra_able */ | ||
14212 | 0, /* reserved2 */ | ||
14213 | 1, /* max_host_qng */ | ||
14214 | 1, /* max_dvc_qng */ | ||
14215 | 0, /* dvc_cntl */ | ||
14216 | 0, /* bug_fix */ | ||
14217 | 0, /* serial_number_word1 */ | ||
14218 | 0, /* serial_number_word2 */ | ||
14219 | 0, /* serial_number_word3 */ | ||
14220 | 0, /* check_sum */ | ||
14221 | { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* oem_name[16] */ | ||
14222 | 0, /* dvc_err_code */ | ||
14223 | 0, /* adv_err_code */ | ||
14224 | 0, /* adv_err_addr */ | ||
14225 | 0, /* saved_dvc_err_code */ | ||
14226 | 0, /* saved_adv_err_code */ | ||
14227 | 0, /* saved_adv_err_addr */ | ||
14228 | 0 /* num_of_err */ | ||
14229 | }; | ||
14230 | |||
14231 | STATIC ADVEEP_38C0800_CONFIG | ||
14232 | Default_38C0800_EEPROM_Config __initdata = { | ||
14233 | ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ | ||
14234 | 0x0000, /* 01 cfg_msw */ | ||
14235 | 0xFFFF, /* 02 disc_enable */ | ||
14236 | 0xFFFF, /* 03 wdtr_able */ | ||
14237 | 0x4444, /* 04 sdtr_speed1 */ | ||
14238 | 0xFFFF, /* 05 start_motor */ | ||
14239 | 0xFFFF, /* 06 tagqng_able */ | ||
14240 | 0xFFFF, /* 07 bios_scan */ | ||
14241 | 0, /* 08 scam_tolerant */ | ||
14242 | 7, /* 09 adapter_scsi_id */ | ||
14243 | 0, /* bios_boot_delay */ | ||
14244 | 3, /* 10 scsi_reset_delay */ | ||
14245 | 0, /* bios_id_lun */ | ||
14246 | 0, /* 11 termination_se */ | ||
14247 | 0, /* termination_lvd */ | ||
14248 | 0xFFE7, /* 12 bios_ctrl */ | ||
14249 | 0x4444, /* 13 sdtr_speed2 */ | ||
14250 | 0x4444, /* 14 sdtr_speed3 */ | ||
14251 | ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */ | ||
14252 | ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */ | ||
14253 | 0, /* 16 dvc_cntl */ | ||
14254 | 0x4444, /* 17 sdtr_speed4 */ | ||
14255 | 0, /* 18 serial_number_word1 */ | ||
14256 | 0, /* 19 serial_number_word2 */ | ||
14257 | 0, /* 20 serial_number_word3 */ | ||
14258 | 0, /* 21 check_sum */ | ||
14259 | { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */ | ||
14260 | 0, /* 30 dvc_err_code */ | ||
14261 | 0, /* 31 adv_err_code */ | ||
14262 | 0, /* 32 adv_err_addr */ | ||
14263 | 0, /* 33 saved_dvc_err_code */ | ||
14264 | 0, /* 34 saved_adv_err_code */ | ||
14265 | 0, /* 35 saved_adv_err_addr */ | ||
14266 | 0, /* 36 reserved */ | ||
14267 | 0, /* 37 reserved */ | ||
14268 | 0, /* 38 reserved */ | ||
14269 | 0, /* 39 reserved */ | ||
14270 | 0, /* 40 reserved */ | ||
14271 | 0, /* 41 reserved */ | ||
14272 | 0, /* 42 reserved */ | ||
14273 | 0, /* 43 reserved */ | ||
14274 | 0, /* 44 reserved */ | ||
14275 | 0, /* 45 reserved */ | ||
14276 | 0, /* 46 reserved */ | ||
14277 | 0, /* 47 reserved */ | ||
14278 | 0, /* 48 reserved */ | ||
14279 | 0, /* 49 reserved */ | ||
14280 | 0, /* 50 reserved */ | ||
14281 | 0, /* 51 reserved */ | ||
14282 | 0, /* 52 reserved */ | ||
14283 | 0, /* 53 reserved */ | ||
14284 | 0, /* 54 reserved */ | ||
14285 | 0, /* 55 reserved */ | ||
14286 | 0, /* 56 cisptr_lsw */ | ||
14287 | 0, /* 57 cisprt_msw */ | ||
14288 | ADV_PCI_VENDOR_ID, /* 58 subsysvid */ | ||
14289 | ADV_PCI_DEVID_38C0800_REV1, /* 59 subsysid */ | ||
14290 | 0, /* 60 reserved */ | ||
14291 | 0, /* 61 reserved */ | ||
14292 | 0, /* 62 reserved */ | ||
14293 | 0 /* 63 reserved */ | ||
14294 | }; | ||
14295 | |||
14296 | STATIC ADVEEP_38C0800_CONFIG | ||
14297 | ADVEEP_38C0800_Config_Field_IsChar __initdata = { | ||
14298 | 0, /* 00 cfg_lsw */ | ||
14299 | 0, /* 01 cfg_msw */ | ||
14300 | 0, /* 02 disc_enable */ | ||
14301 | 0, /* 03 wdtr_able */ | ||
14302 | 0, /* 04 sdtr_speed1 */ | ||
14303 | 0, /* 05 start_motor */ | ||
14304 | 0, /* 06 tagqng_able */ | ||
14305 | 0, /* 07 bios_scan */ | ||
14306 | 0, /* 08 scam_tolerant */ | ||
14307 | 1, /* 09 adapter_scsi_id */ | ||
14308 | 1, /* bios_boot_delay */ | ||
14309 | 1, /* 10 scsi_reset_delay */ | ||
14310 | 1, /* bios_id_lun */ | ||
14311 | 1, /* 11 termination_se */ | ||
14312 | 1, /* termination_lvd */ | ||
14313 | 0, /* 12 bios_ctrl */ | ||
14314 | 0, /* 13 sdtr_speed2 */ | ||
14315 | 0, /* 14 sdtr_speed3 */ | ||
14316 | 1, /* 15 max_host_qng */ | ||
14317 | 1, /* max_dvc_qng */ | ||
14318 | 0, /* 16 dvc_cntl */ | ||
14319 | 0, /* 17 sdtr_speed4 */ | ||
14320 | 0, /* 18 serial_number_word1 */ | ||
14321 | 0, /* 19 serial_number_word2 */ | ||
14322 | 0, /* 20 serial_number_word3 */ | ||
14323 | 0, /* 21 check_sum */ | ||
14324 | { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */ | ||
14325 | 0, /* 30 dvc_err_code */ | ||
14326 | 0, /* 31 adv_err_code */ | ||
14327 | 0, /* 32 adv_err_addr */ | ||
14328 | 0, /* 33 saved_dvc_err_code */ | ||
14329 | 0, /* 34 saved_adv_err_code */ | ||
14330 | 0, /* 35 saved_adv_err_addr */ | ||
14331 | 0, /* 36 reserved */ | ||
14332 | 0, /* 37 reserved */ | ||
14333 | 0, /* 38 reserved */ | ||
14334 | 0, /* 39 reserved */ | ||
14335 | 0, /* 40 reserved */ | ||
14336 | 0, /* 41 reserved */ | ||
14337 | 0, /* 42 reserved */ | ||
14338 | 0, /* 43 reserved */ | ||
14339 | 0, /* 44 reserved */ | ||
14340 | 0, /* 45 reserved */ | ||
14341 | 0, /* 46 reserved */ | ||
14342 | 0, /* 47 reserved */ | ||
14343 | 0, /* 48 reserved */ | ||
14344 | 0, /* 49 reserved */ | ||
14345 | 0, /* 50 reserved */ | ||
14346 | 0, /* 51 reserved */ | ||
14347 | 0, /* 52 reserved */ | ||
14348 | 0, /* 53 reserved */ | ||
14349 | 0, /* 54 reserved */ | ||
14350 | 0, /* 55 reserved */ | ||
14351 | 0, /* 56 cisptr_lsw */ | ||
14352 | 0, /* 57 cisprt_msw */ | ||
14353 | 0, /* 58 subsysvid */ | ||
14354 | 0, /* 59 subsysid */ | ||
14355 | 0, /* 60 reserved */ | ||
14356 | 0, /* 61 reserved */ | ||
14357 | 0, /* 62 reserved */ | ||
14358 | 0 /* 63 reserved */ | ||
14359 | }; | ||
14360 | |||
14361 | STATIC ADVEEP_38C1600_CONFIG | ||
14362 | Default_38C1600_EEPROM_Config __initdata = { | ||
14363 | ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ | ||
14364 | 0x0000, /* 01 cfg_msw */ | ||
14365 | 0xFFFF, /* 02 disc_enable */ | ||
14366 | 0xFFFF, /* 03 wdtr_able */ | ||
14367 | 0x5555, /* 04 sdtr_speed1 */ | ||
14368 | 0xFFFF, /* 05 start_motor */ | ||
14369 | 0xFFFF, /* 06 tagqng_able */ | ||
14370 | 0xFFFF, /* 07 bios_scan */ | ||
14371 | 0, /* 08 scam_tolerant */ | ||
14372 | 7, /* 09 adapter_scsi_id */ | ||
14373 | 0, /* bios_boot_delay */ | ||
14374 | 3, /* 10 scsi_reset_delay */ | ||
14375 | 0, /* bios_id_lun */ | ||
14376 | 0, /* 11 termination_se */ | ||
14377 | 0, /* termination_lvd */ | ||
14378 | 0xFFE7, /* 12 bios_ctrl */ | ||
14379 | 0x5555, /* 13 sdtr_speed2 */ | ||
14380 | 0x5555, /* 14 sdtr_speed3 */ | ||
14381 | ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */ | ||
14382 | ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */ | ||
14383 | 0, /* 16 dvc_cntl */ | ||
14384 | 0x5555, /* 17 sdtr_speed4 */ | ||
14385 | 0, /* 18 serial_number_word1 */ | ||
14386 | 0, /* 19 serial_number_word2 */ | ||
14387 | 0, /* 20 serial_number_word3 */ | ||
14388 | 0, /* 21 check_sum */ | ||
14389 | { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */ | ||
14390 | 0, /* 30 dvc_err_code */ | ||
14391 | 0, /* 31 adv_err_code */ | ||
14392 | 0, /* 32 adv_err_addr */ | ||
14393 | 0, /* 33 saved_dvc_err_code */ | ||
14394 | 0, /* 34 saved_adv_err_code */ | ||
14395 | 0, /* 35 saved_adv_err_addr */ | ||
14396 | 0, /* 36 reserved */ | ||
14397 | 0, /* 37 reserved */ | ||
14398 | 0, /* 38 reserved */ | ||
14399 | 0, /* 39 reserved */ | ||
14400 | 0, /* 40 reserved */ | ||
14401 | 0, /* 41 reserved */ | ||
14402 | 0, /* 42 reserved */ | ||
14403 | 0, /* 43 reserved */ | ||
14404 | 0, /* 44 reserved */ | ||
14405 | 0, /* 45 reserved */ | ||
14406 | 0, /* 46 reserved */ | ||
14407 | 0, /* 47 reserved */ | ||
14408 | 0, /* 48 reserved */ | ||
14409 | 0, /* 49 reserved */ | ||
14410 | 0, /* 50 reserved */ | ||
14411 | 0, /* 51 reserved */ | ||
14412 | 0, /* 52 reserved */ | ||
14413 | 0, /* 53 reserved */ | ||
14414 | 0, /* 54 reserved */ | ||
14415 | 0, /* 55 reserved */ | ||
14416 | 0, /* 56 cisptr_lsw */ | ||
14417 | 0, /* 57 cisprt_msw */ | ||
14418 | ADV_PCI_VENDOR_ID, /* 58 subsysvid */ | ||
14419 | ADV_PCI_DEVID_38C1600_REV1, /* 59 subsysid */ | ||
14420 | 0, /* 60 reserved */ | ||
14421 | 0, /* 61 reserved */ | ||
14422 | 0, /* 62 reserved */ | ||
14423 | 0 /* 63 reserved */ | ||
14424 | }; | ||
14425 | |||
14426 | STATIC ADVEEP_38C1600_CONFIG | ||
14427 | ADVEEP_38C1600_Config_Field_IsChar __initdata = { | ||
14428 | 0, /* 00 cfg_lsw */ | ||
14429 | 0, /* 01 cfg_msw */ | ||
14430 | 0, /* 02 disc_enable */ | ||
14431 | 0, /* 03 wdtr_able */ | ||
14432 | 0, /* 04 sdtr_speed1 */ | ||
14433 | 0, /* 05 start_motor */ | ||
14434 | 0, /* 06 tagqng_able */ | ||
14435 | 0, /* 07 bios_scan */ | ||
14436 | 0, /* 08 scam_tolerant */ | ||
14437 | 1, /* 09 adapter_scsi_id */ | ||
14438 | 1, /* bios_boot_delay */ | ||
14439 | 1, /* 10 scsi_reset_delay */ | ||
14440 | 1, /* bios_id_lun */ | ||
14441 | 1, /* 11 termination_se */ | ||
14442 | 1, /* termination_lvd */ | ||
14443 | 0, /* 12 bios_ctrl */ | ||
14444 | 0, /* 13 sdtr_speed2 */ | ||
14445 | 0, /* 14 sdtr_speed3 */ | ||
14446 | 1, /* 15 max_host_qng */ | ||
14447 | 1, /* max_dvc_qng */ | ||
14448 | 0, /* 16 dvc_cntl */ | ||
14449 | 0, /* 17 sdtr_speed4 */ | ||
14450 | 0, /* 18 serial_number_word1 */ | ||
14451 | 0, /* 19 serial_number_word2 */ | ||
14452 | 0, /* 20 serial_number_word3 */ | ||
14453 | 0, /* 21 check_sum */ | ||
14454 | { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */ | ||
14455 | 0, /* 30 dvc_err_code */ | ||
14456 | 0, /* 31 adv_err_code */ | ||
14457 | 0, /* 32 adv_err_addr */ | ||
14458 | 0, /* 33 saved_dvc_err_code */ | ||
14459 | 0, /* 34 saved_adv_err_code */ | ||
14460 | 0, /* 35 saved_adv_err_addr */ | ||
14461 | 0, /* 36 reserved */ | ||
14462 | 0, /* 37 reserved */ | ||
14463 | 0, /* 38 reserved */ | ||
14464 | 0, /* 39 reserved */ | ||
14465 | 0, /* 40 reserved */ | ||
14466 | 0, /* 41 reserved */ | ||
14467 | 0, /* 42 reserved */ | ||
14468 | 0, /* 43 reserved */ | ||
14469 | 0, /* 44 reserved */ | ||
14470 | 0, /* 45 reserved */ | ||
14471 | 0, /* 46 reserved */ | ||
14472 | 0, /* 47 reserved */ | ||
14473 | 0, /* 48 reserved */ | ||
14474 | 0, /* 49 reserved */ | ||
14475 | 0, /* 50 reserved */ | ||
14476 | 0, /* 51 reserved */ | ||
14477 | 0, /* 52 reserved */ | ||
14478 | 0, /* 53 reserved */ | ||
14479 | 0, /* 54 reserved */ | ||
14480 | 0, /* 55 reserved */ | ||
14481 | 0, /* 56 cisptr_lsw */ | ||
14482 | 0, /* 57 cisprt_msw */ | ||
14483 | 0, /* 58 subsysvid */ | ||
14484 | 0, /* 59 subsysid */ | ||
14485 | 0, /* 60 reserved */ | ||
14486 | 0, /* 61 reserved */ | ||
14487 | 0, /* 62 reserved */ | ||
14488 | 0 /* 63 reserved */ | ||
14489 | }; | ||
14490 | |||
14491 | /* | ||
14492 | * Initialize the ADV_DVC_VAR structure. | ||
14493 | * | ||
14494 | * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. | ||
14495 | * | ||
14496 | * For a non-fatal error return a warning code. If there are no warnings | ||
14497 | * then 0 is returned. | ||
14498 | */ | ||
14499 | STATIC int __init | ||
14500 | AdvInitGetConfig(ADV_DVC_VAR *asc_dvc) | ||
14501 | { | ||
14502 | ushort warn_code; | ||
14503 | AdvPortAddr iop_base; | ||
14504 | uchar pci_cmd_reg; | ||
14505 | int status; | ||
14506 | |||
14507 | warn_code = 0; | ||
14508 | asc_dvc->err_code = 0; | ||
14509 | iop_base = asc_dvc->iop_base; | ||
14510 | |||
14511 | /* | ||
14512 | * PCI Command Register | ||
14513 | * | ||
14514 | * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes | ||
14515 | * I/O Space Control, Memory Space Control and Bus Master Control bits. | ||
14516 | */ | ||
14517 | |||
14518 | if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc, | ||
14519 | AscPCIConfigCommandRegister)) | ||
14520 | & AscPCICmdRegBits_BusMastering) | ||
14521 | != AscPCICmdRegBits_BusMastering) | ||
14522 | { | ||
14523 | pci_cmd_reg |= AscPCICmdRegBits_BusMastering; | ||
14524 | |||
14525 | DvcAdvWritePCIConfigByte(asc_dvc, | ||
14526 | AscPCIConfigCommandRegister, pci_cmd_reg); | ||
14527 | |||
14528 | if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)) | ||
14529 | & AscPCICmdRegBits_BusMastering) | ||
14530 | != AscPCICmdRegBits_BusMastering) | ||
14531 | { | ||
14532 | warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; | ||
14533 | } | ||
14534 | } | ||
14535 | |||
14536 | /* | ||
14537 | * PCI Latency Timer | ||
14538 | * | ||
14539 | * If the "latency timer" register is 0x20 or above, then we don't need | ||
14540 | * to change it. Otherwise, set it to 0x20 (i.e. set it to 0x20 if it | ||
14541 | * comes up less than 0x20). | ||
14542 | */ | ||
14543 | if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) { | ||
14544 | DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, 0x20); | ||
14545 | if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) | ||
14546 | { | ||
14547 | warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; | ||
14548 | } | ||
14549 | } | ||
14550 | |||
14551 | /* | ||
14552 | * Save the state of the PCI Configuration Command Register | ||
14553 | * "Parity Error Response Control" Bit. If the bit is clear (0), | ||
14554 | * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore | ||
14555 | * DMA parity errors. | ||
14556 | */ | ||
14557 | asc_dvc->cfg->control_flag = 0; | ||
14558 | if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister) | ||
14559 | & AscPCICmdRegBits_ParErrRespCtrl)) == 0) | ||
14560 | { | ||
14561 | asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR; | ||
14562 | } | ||
14563 | |||
14564 | asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) | | ||
14565 | ADV_LIB_VERSION_MINOR; | ||
14566 | asc_dvc->cfg->chip_version = | ||
14567 | AdvGetChipVersion(iop_base, asc_dvc->bus_type); | ||
14568 | |||
14569 | ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n", | ||
14570 | (ushort) AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1), | ||
14571 | (ushort) ADV_CHIP_ID_BYTE); | ||
14572 | |||
14573 | ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n", | ||
14574 | (ushort) AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0), | ||
14575 | (ushort) ADV_CHIP_ID_WORD); | ||
14576 | |||
14577 | /* | ||
14578 | * Reset the chip to start and allow register writes. | ||
14579 | */ | ||
14580 | if (AdvFindSignature(iop_base) == 0) | ||
14581 | { | ||
14582 | asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; | ||
14583 | return ADV_ERROR; | ||
14584 | } | ||
14585 | else { | ||
14586 | /* | ||
14587 | * The caller must set 'chip_type' to a valid setting. | ||
14588 | */ | ||
14589 | if (asc_dvc->chip_type != ADV_CHIP_ASC3550 && | ||
14590 | asc_dvc->chip_type != ADV_CHIP_ASC38C0800 && | ||
14591 | asc_dvc->chip_type != ADV_CHIP_ASC38C1600) | ||
14592 | { | ||
14593 | asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE; | ||
14594 | return ADV_ERROR; | ||
14595 | } | ||
14596 | |||
14597 | /* | ||
14598 | * Reset Chip. | ||
14599 | */ | ||
14600 | AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, | ||
14601 | ADV_CTRL_REG_CMD_RESET); | ||
14602 | DvcSleepMilliSecond(100); | ||
14603 | AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, | ||
14604 | ADV_CTRL_REG_CMD_WR_IO_REG); | ||
14605 | |||
14606 | if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) | ||
14607 | { | ||
14608 | if ((status = AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR) | ||
14609 | { | ||
14610 | return ADV_ERROR; | ||
14611 | } | ||
14612 | } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) | ||
14613 | { | ||
14614 | if ((status = AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR) | ||
14615 | { | ||
14616 | return ADV_ERROR; | ||
14617 | } | ||
14618 | } else | ||
14619 | { | ||
14620 | if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR) | ||
14621 | { | ||
14622 | return ADV_ERROR; | ||
14623 | } | ||
14624 | } | ||
14625 | warn_code |= status; | ||
14626 | } | ||
14627 | |||
14628 | return warn_code; | ||
14629 | } | ||
14630 | |||
14631 | /* | ||
14632 | * Initialize the ASC-3550. | ||
14633 | * | ||
14634 | * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. | ||
14635 | * | ||
14636 | * For a non-fatal error return a warning code. If there are no warnings | ||
14637 | * then 0 is returned. | ||
14638 | * | ||
14639 | * Needed after initialization for error recovery. | ||
14640 | */ | ||
14641 | STATIC int | ||
14642 | AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) | ||
14643 | { | ||
14644 | AdvPortAddr iop_base; | ||
14645 | ushort warn_code; | ||
14646 | ADV_DCNT sum; | ||
14647 | int begin_addr; | ||
14648 | int end_addr; | ||
14649 | ushort code_sum; | ||
14650 | int word; | ||
14651 | int j; | ||
14652 | int adv_asc3550_expanded_size; | ||
14653 | ADV_CARR_T *carrp; | ||
14654 | ADV_DCNT contig_len; | ||
14655 | ADV_SDCNT buf_size; | ||
14656 | ADV_PADDR carr_paddr; | ||
14657 | int i; | ||
14658 | ushort scsi_cfg1; | ||
14659 | uchar tid; | ||
14660 | ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */ | ||
14661 | ushort wdtr_able = 0, sdtr_able, tagqng_able; | ||
14662 | uchar max_cmd[ADV_MAX_TID + 1]; | ||
14663 | |||
14664 | /* If there is already an error, don't continue. */ | ||
14665 | if (asc_dvc->err_code != 0) | ||
14666 | { | ||
14667 | return ADV_ERROR; | ||
14668 | } | ||
14669 | |||
14670 | /* | ||
14671 | * The caller must set 'chip_type' to ADV_CHIP_ASC3550. | ||
14672 | */ | ||
14673 | if (asc_dvc->chip_type != ADV_CHIP_ASC3550) | ||
14674 | { | ||
14675 | asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE; | ||
14676 | return ADV_ERROR; | ||
14677 | } | ||
14678 | |||
14679 | warn_code = 0; | ||
14680 | iop_base = asc_dvc->iop_base; | ||
14681 | |||
14682 | /* | ||
14683 | * Save the RISC memory BIOS region before writing the microcode. | ||
14684 | * The BIOS may already be loaded and using its RISC LRAM region | ||
14685 | * so its region must be saved and restored. | ||
14686 | * | ||
14687 | * Note: This code makes the assumption, which is currently true, | ||
14688 | * that a chip reset does not clear RISC LRAM. | ||
14689 | */ | ||
14690 | for (i = 0; i < ASC_MC_BIOSLEN/2; i++) | ||
14691 | { | ||
14692 | AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]); | ||
14693 | } | ||
14694 | |||
14695 | /* | ||
14696 | * Save current per TID negotiated values. | ||
14697 | */ | ||
14698 | if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA) | ||
14699 | { | ||
14700 | ushort bios_version, major, minor; | ||
14701 | |||
14702 | bios_version = bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM)/2]; | ||
14703 | major = (bios_version >> 12) & 0xF; | ||
14704 | minor = (bios_version >> 8) & 0xF; | ||
14705 | if (major < 3 || (major == 3 && minor == 1)) | ||
14706 | { | ||
14707 | /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */ | ||
14708 | AdvReadWordLram(iop_base, 0x120, wdtr_able); | ||
14709 | } else | ||
14710 | { | ||
14711 | AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
14712 | } | ||
14713 | } | ||
14714 | AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
14715 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
14716 | for (tid = 0; tid <= ADV_MAX_TID; tid++) | ||
14717 | { | ||
14718 | AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
14719 | max_cmd[tid]); | ||
14720 | } | ||
14721 | |||
14722 | /* | ||
14723 | * Load the Microcode | ||
14724 | * | ||
14725 | * Write the microcode image to RISC memory starting at address 0. | ||
14726 | */ | ||
14727 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); | ||
14728 | /* Assume the following compressed format of the microcode buffer: | ||
14729 | * | ||
14730 | * 254 word (508 byte) table indexed by byte code followed | ||
14731 | * by the following byte codes: | ||
14732 | * | ||
14733 | * 1-Byte Code: | ||
14734 | * 00: Emit word 0 in table. | ||
14735 | * 01: Emit word 1 in table. | ||
14736 | * . | ||
14737 | * FD: Emit word 253 in table. | ||
14738 | * | ||
14739 | * Multi-Byte Code: | ||
14740 | * FE WW WW: (3 byte code) Word to emit is the next word WW WW. | ||
14741 | * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. | ||
14742 | */ | ||
14743 | word = 0; | ||
14744 | for (i = 253 * 2; i < _adv_asc3550_size; i++) | ||
14745 | { | ||
14746 | if (_adv_asc3550_buf[i] == 0xff) | ||
14747 | { | ||
14748 | for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) | ||
14749 | { | ||
14750 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | ||
14751 | _adv_asc3550_buf[i + 3] << 8) | | ||
14752 | _adv_asc3550_buf[i + 2])); | ||
14753 | word++; | ||
14754 | } | ||
14755 | i += 3; | ||
14756 | } else if (_adv_asc3550_buf[i] == 0xfe) | ||
14757 | { | ||
14758 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | ||
14759 | _adv_asc3550_buf[i + 2] << 8) | | ||
14760 | _adv_asc3550_buf[i + 1])); | ||
14761 | i += 2; | ||
14762 | word++; | ||
14763 | } else | ||
14764 | { | ||
14765 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | ||
14766 | _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | | ||
14767 | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2])); | ||
14768 | word++; | ||
14769 | } | ||
14770 | } | ||
14771 | |||
14772 | /* | ||
14773 | * Set 'word' for later use to clear the rest of memory and save | ||
14774 | * the expanded mcode size. | ||
14775 | */ | ||
14776 | word *= 2; | ||
14777 | adv_asc3550_expanded_size = word; | ||
14778 | |||
14779 | /* | ||
14780 | * Clear the rest of ASC-3550 Internal RAM (8KB). | ||
14781 | */ | ||
14782 | for (; word < ADV_3550_MEMSIZE; word += 2) | ||
14783 | { | ||
14784 | AdvWriteWordAutoIncLram(iop_base, 0); | ||
14785 | } | ||
14786 | |||
14787 | /* | ||
14788 | * Verify the microcode checksum. | ||
14789 | */ | ||
14790 | sum = 0; | ||
14791 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); | ||
14792 | |||
14793 | for (word = 0; word < adv_asc3550_expanded_size; word += 2) | ||
14794 | { | ||
14795 | sum += AdvReadWordAutoIncLram(iop_base); | ||
14796 | } | ||
14797 | |||
14798 | if (sum != _adv_asc3550_chksum) | ||
14799 | { | ||
14800 | asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; | ||
14801 | return ADV_ERROR; | ||
14802 | } | ||
14803 | |||
14804 | /* | ||
14805 | * Restore the RISC memory BIOS region. | ||
14806 | */ | ||
14807 | for (i = 0; i < ASC_MC_BIOSLEN/2; i++) | ||
14808 | { | ||
14809 | AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]); | ||
14810 | } | ||
14811 | |||
14812 | /* | ||
14813 | * Calculate and write the microcode code checksum to the microcode | ||
14814 | * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). | ||
14815 | */ | ||
14816 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr); | ||
14817 | AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr); | ||
14818 | code_sum = 0; | ||
14819 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr); | ||
14820 | for (word = begin_addr; word < end_addr; word += 2) | ||
14821 | { | ||
14822 | code_sum += AdvReadWordAutoIncLram(iop_base); | ||
14823 | } | ||
14824 | AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum); | ||
14825 | |||
14826 | /* | ||
14827 | * Read and save microcode version and date. | ||
14828 | */ | ||
14829 | AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date); | ||
14830 | AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version); | ||
14831 | |||
14832 | /* | ||
14833 | * Set the chip type to indicate the ASC3550. | ||
14834 | */ | ||
14835 | AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550); | ||
14836 | |||
14837 | /* | ||
14838 | * If the PCI Configuration Command Register "Parity Error Response | ||
14839 | * Control" Bit was clear (0), then set the microcode variable | ||
14840 | * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode | ||
14841 | * to ignore DMA parity errors. | ||
14842 | */ | ||
14843 | if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) | ||
14844 | { | ||
14845 | AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
14846 | word |= CONTROL_FLAG_IGNORE_PERR; | ||
14847 | AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
14848 | } | ||
14849 | |||
14850 | /* | ||
14851 | * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO | ||
14852 | * threshold of 128 bytes. This register is only accessible to the host. | ||
14853 | */ | ||
14854 | AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0, | ||
14855 | START_CTL_EMFU | READ_CMD_MRM); | ||
14856 | |||
14857 | /* | ||
14858 | * Microcode operating variables for WDTR, SDTR, and command tag | ||
14859 | * queuing will be set in AdvInquiryHandling() based on what a | ||
14860 | * device reports it is capable of in Inquiry byte 7. | ||
14861 | * | ||
14862 | * If SCSI Bus Resets have been disabled, then directly set | ||
14863 | * SDTR and WDTR from the EEPROM configuration. This will allow | ||
14864 | * the BIOS and warm boot to work without a SCSI bus hang on | ||
14865 | * the Inquiry caused by host and target mismatched DTR values. | ||
14866 | * Without the SCSI Bus Reset, before an Inquiry a device can't | ||
14867 | * be assumed to be in Asynchronous, Narrow mode. | ||
14868 | */ | ||
14869 | if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) | ||
14870 | { | ||
14871 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able); | ||
14872 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able); | ||
14873 | } | ||
14874 | |||
14875 | /* | ||
14876 | * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2, | ||
14877 | * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID | ||
14878 | * bitmask. These values determine the maximum SDTR speed negotiated | ||
14879 | * with a device. | ||
14880 | * | ||
14881 | * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, | ||
14882 | * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them | ||
14883 | * without determining here whether the device supports SDTR. | ||
14884 | * | ||
14885 | * 4-bit speed SDTR speed name | ||
14886 | * =========== =============== | ||
14887 | * 0000b (0x0) SDTR disabled | ||
14888 | * 0001b (0x1) 5 Mhz | ||
14889 | * 0010b (0x2) 10 Mhz | ||
14890 | * 0011b (0x3) 20 Mhz (Ultra) | ||
14891 | * 0100b (0x4) 40 Mhz (LVD/Ultra2) | ||
14892 | * 0101b (0x5) 80 Mhz (LVD2/Ultra3) | ||
14893 | * 0110b (0x6) Undefined | ||
14894 | * . | ||
14895 | * 1111b (0xF) Undefined | ||
14896 | */ | ||
14897 | word = 0; | ||
14898 | for (tid = 0; tid <= ADV_MAX_TID; tid++) | ||
14899 | { | ||
14900 | if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) | ||
14901 | { | ||
14902 | /* Set Ultra speed for TID 'tid'. */ | ||
14903 | word |= (0x3 << (4 * (tid % 4))); | ||
14904 | } else | ||
14905 | { | ||
14906 | /* Set Fast speed for TID 'tid'. */ | ||
14907 | word |= (0x2 << (4 * (tid % 4))); | ||
14908 | } | ||
14909 | if (tid == 3) /* Check if done with sdtr_speed1. */ | ||
14910 | { | ||
14911 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word); | ||
14912 | word = 0; | ||
14913 | } else if (tid == 7) /* Check if done with sdtr_speed2. */ | ||
14914 | { | ||
14915 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word); | ||
14916 | word = 0; | ||
14917 | } else if (tid == 11) /* Check if done with sdtr_speed3. */ | ||
14918 | { | ||
14919 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word); | ||
14920 | word = 0; | ||
14921 | } else if (tid == 15) /* Check if done with sdtr_speed4. */ | ||
14922 | { | ||
14923 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word); | ||
14924 | /* End of loop. */ | ||
14925 | } | ||
14926 | } | ||
14927 | |||
14928 | /* | ||
14929 | * Set microcode operating variable for the disconnect per TID bitmask. | ||
14930 | */ | ||
14931 | AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable); | ||
14932 | |||
14933 | /* | ||
14934 | * Set SCSI_CFG0 Microcode Default Value. | ||
14935 | * | ||
14936 | * The microcode will set the SCSI_CFG0 register using this value | ||
14937 | * after it is started below. | ||
14938 | */ | ||
14939 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0, | ||
14940 | PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN | | ||
14941 | asc_dvc->chip_scsi_id); | ||
14942 | |||
14943 | /* | ||
14944 | * Determine SCSI_CFG1 Microcode Default Value. | ||
14945 | * | ||
14946 | * The microcode will set the SCSI_CFG1 register using this value | ||
14947 | * after it is started below. | ||
14948 | */ | ||
14949 | |||
14950 | /* Read current SCSI_CFG1 Register value. */ | ||
14951 | scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); | ||
14952 | |||
14953 | /* | ||
14954 | * If all three connectors are in use, return an error. | ||
14955 | */ | ||
14956 | if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 || | ||
14957 | (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) | ||
14958 | { | ||
14959 | asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION; | ||
14960 | return ADV_ERROR; | ||
14961 | } | ||
14962 | |||
14963 | /* | ||
14964 | * If the internal narrow cable is reversed all of the SCSI_CTRL | ||
14965 | * register signals will be set. Check for and return an error if | ||
14966 | * this condition is found. | ||
14967 | */ | ||
14968 | if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) | ||
14969 | { | ||
14970 | asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE; | ||
14971 | return ADV_ERROR; | ||
14972 | } | ||
14973 | |||
14974 | /* | ||
14975 | * If this is a differential board and a single-ended device | ||
14976 | * is attached to one of the connectors, return an error. | ||
14977 | */ | ||
14978 | if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) | ||
14979 | { | ||
14980 | asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE; | ||
14981 | return ADV_ERROR; | ||
14982 | } | ||
14983 | |||
14984 | /* | ||
14985 | * If automatic termination control is enabled, then set the | ||
14986 | * termination value based on a table listed in a_condor.h. | ||
14987 | * | ||
14988 | * If manual termination was specified with an EEPROM setting | ||
14989 | * then 'termination' was set-up in AdvInitFrom3550EEPROM() and | ||
14990 | * is ready to be 'ored' into SCSI_CFG1. | ||
14991 | */ | ||
14992 | if (asc_dvc->cfg->termination == 0) | ||
14993 | { | ||
14994 | /* | ||
14995 | * The software always controls termination by setting TERM_CTL_SEL. | ||
14996 | * If TERM_CTL_SEL were set to 0, the hardware would set termination. | ||
14997 | */ | ||
14998 | asc_dvc->cfg->termination |= TERM_CTL_SEL; | ||
14999 | |||
15000 | switch(scsi_cfg1 & CABLE_DETECT) | ||
15001 | { | ||
15002 | /* TERM_CTL_H: on, TERM_CTL_L: on */ | ||
15003 | case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF: | ||
15004 | asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L); | ||
15005 | break; | ||
15006 | |||
15007 | /* TERM_CTL_H: on, TERM_CTL_L: off */ | ||
15008 | case 0x1: case 0x5: case 0x9: case 0xA: case 0xC: | ||
15009 | asc_dvc->cfg->termination |= TERM_CTL_H; | ||
15010 | break; | ||
15011 | |||
15012 | /* TERM_CTL_H: off, TERM_CTL_L: off */ | ||
15013 | case 0x2: case 0x6: | ||
15014 | break; | ||
15015 | } | ||
15016 | } | ||
15017 | |||
15018 | /* | ||
15019 | * Clear any set TERM_CTL_H and TERM_CTL_L bits. | ||
15020 | */ | ||
15021 | scsi_cfg1 &= ~TERM_CTL; | ||
15022 | |||
15023 | /* | ||
15024 | * Invert the TERM_CTL_H and TERM_CTL_L bits and then | ||
15025 | * set 'scsi_cfg1'. The TERM_POL bit does not need to be | ||
15026 | * referenced, because the hardware internally inverts | ||
15027 | * the Termination High and Low bits if TERM_POL is set. | ||
15028 | */ | ||
15029 | scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL)); | ||
15030 | |||
15031 | /* | ||
15032 | * Set SCSI_CFG1 Microcode Default Value | ||
15033 | * | ||
15034 | * Set filter value and possibly modified termination control | ||
15035 | * bits in the Microcode SCSI_CFG1 Register Value. | ||
15036 | * | ||
15037 | * The microcode will set the SCSI_CFG1 register using this value | ||
15038 | * after it is started below. | ||
15039 | */ | ||
15040 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, | ||
15041 | FLTR_DISABLE | scsi_cfg1); | ||
15042 | |||
15043 | /* | ||
15044 | * Set MEM_CFG Microcode Default Value | ||
15045 | * | ||
15046 | * The microcode will set the MEM_CFG register using this value | ||
15047 | * after it is started below. | ||
15048 | * | ||
15049 | * MEM_CFG may be accessed as a word or byte, but only bits 0-7 | ||
15050 | * are defined. | ||
15051 | * | ||
15052 | * ASC-3550 has 8KB internal memory. | ||
15053 | */ | ||
15054 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, | ||
15055 | BIOS_EN | RAM_SZ_8KB); | ||
15056 | |||
15057 | /* | ||
15058 | * Set SEL_MASK Microcode Default Value | ||
15059 | * | ||
15060 | * The microcode will set the SEL_MASK register using this value | ||
15061 | * after it is started below. | ||
15062 | */ | ||
15063 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, | ||
15064 | ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); | ||
15065 | |||
15066 | /* | ||
15067 | * Build carrier freelist. | ||
15068 | * | ||
15069 | * Driver must have already allocated memory and set 'carrier_buf'. | ||
15070 | */ | ||
15071 | ASC_ASSERT(asc_dvc->carrier_buf != NULL); | ||
15072 | |||
15073 | carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf); | ||
15074 | asc_dvc->carr_freelist = NULL; | ||
15075 | if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) | ||
15076 | { | ||
15077 | buf_size = ADV_CARRIER_BUFSIZE; | ||
15078 | } else | ||
15079 | { | ||
15080 | buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T); | ||
15081 | } | ||
15082 | |||
15083 | do { | ||
15084 | /* | ||
15085 | * Get physical address of the carrier 'carrp'. | ||
15086 | */ | ||
15087 | contig_len = sizeof(ADV_CARR_T); | ||
15088 | carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp, | ||
15089 | (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG)); | ||
15090 | |||
15091 | buf_size -= sizeof(ADV_CARR_T); | ||
15092 | |||
15093 | /* | ||
15094 | * If the current carrier is not physically contiguous, then | ||
15095 | * maybe there was a page crossing. Try the next carrier aligned | ||
15096 | * start address. | ||
15097 | */ | ||
15098 | if (contig_len < sizeof(ADV_CARR_T)) | ||
15099 | { | ||
15100 | carrp++; | ||
15101 | continue; | ||
15102 | } | ||
15103 | |||
15104 | carrp->carr_pa = carr_paddr; | ||
15105 | carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp)); | ||
15106 | |||
15107 | /* | ||
15108 | * Insert the carrier at the beginning of the freelist. | ||
15109 | */ | ||
15110 | carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); | ||
15111 | asc_dvc->carr_freelist = carrp; | ||
15112 | |||
15113 | carrp++; | ||
15114 | } | ||
15115 | while (buf_size > 0); | ||
15116 | |||
15117 | /* | ||
15118 | * Set-up the Host->RISC Initiator Command Queue (ICQ). | ||
15119 | */ | ||
15120 | |||
15121 | if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) | ||
15122 | { | ||
15123 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
15124 | return ADV_ERROR; | ||
15125 | } | ||
15126 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
15127 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa)); | ||
15128 | |||
15129 | /* | ||
15130 | * The first command issued will be placed in the stopper carrier. | ||
15131 | */ | ||
15132 | asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
15133 | |||
15134 | /* | ||
15135 | * Set RISC ICQ physical address start value. | ||
15136 | */ | ||
15137 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa); | ||
15138 | |||
15139 | /* | ||
15140 | * Set-up the RISC->Host Initiator Response Queue (IRQ). | ||
15141 | */ | ||
15142 | if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) | ||
15143 | { | ||
15144 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
15145 | return ADV_ERROR; | ||
15146 | } | ||
15147 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
15148 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa)); | ||
15149 | |||
15150 | /* | ||
15151 | * The first command completed by the RISC will be placed in | ||
15152 | * the stopper. | ||
15153 | * | ||
15154 | * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is | ||
15155 | * completed the RISC will set the ASC_RQ_STOPPER bit. | ||
15156 | */ | ||
15157 | asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
15158 | |||
15159 | /* | ||
15160 | * Set RISC IRQ physical address start value. | ||
15161 | */ | ||
15162 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa); | ||
15163 | asc_dvc->carr_pending_cnt = 0; | ||
15164 | |||
15165 | AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES, | ||
15166 | (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR)); | ||
15167 | |||
15168 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word); | ||
15169 | AdvWriteWordRegister(iop_base, IOPW_PC, word); | ||
15170 | |||
15171 | /* finally, finally, gentlemen, start your engine */ | ||
15172 | AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN); | ||
15173 | |||
15174 | /* | ||
15175 | * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus | ||
15176 | * Resets should be performed. The RISC has to be running | ||
15177 | * to issue a SCSI Bus Reset. | ||
15178 | */ | ||
15179 | if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) | ||
15180 | { | ||
15181 | /* | ||
15182 | * If the BIOS Signature is present in memory, restore the | ||
15183 | * BIOS Handshake Configuration Table and do not perform | ||
15184 | * a SCSI Bus Reset. | ||
15185 | */ | ||
15186 | if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA) | ||
15187 | { | ||
15188 | /* | ||
15189 | * Restore per TID negotiated values. | ||
15190 | */ | ||
15191 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
15192 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
15193 | AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
15194 | for (tid = 0; tid <= ADV_MAX_TID; tid++) | ||
15195 | { | ||
15196 | AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
15197 | max_cmd[tid]); | ||
15198 | } | ||
15199 | } else | ||
15200 | { | ||
15201 | if (AdvResetSB(asc_dvc) != ADV_TRUE) | ||
15202 | { | ||
15203 | warn_code = ASC_WARN_BUSRESET_ERROR; | ||
15204 | } | ||
15205 | } | ||
15206 | } | ||
15207 | |||
15208 | return warn_code; | ||
15209 | } | ||
15210 | |||
15211 | /* | ||
15212 | * Initialize the ASC-38C0800. | ||
15213 | * | ||
15214 | * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. | ||
15215 | * | ||
15216 | * For a non-fatal error return a warning code. If there are no warnings | ||
15217 | * then 0 is returned. | ||
15218 | * | ||
15219 | * Needed after initialization for error recovery. | ||
15220 | */ | ||
15221 | STATIC int | ||
15222 | AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) | ||
15223 | { | ||
15224 | AdvPortAddr iop_base; | ||
15225 | ushort warn_code; | ||
15226 | ADV_DCNT sum; | ||
15227 | int begin_addr; | ||
15228 | int end_addr; | ||
15229 | ushort code_sum; | ||
15230 | int word; | ||
15231 | int j; | ||
15232 | int adv_asc38C0800_expanded_size; | ||
15233 | ADV_CARR_T *carrp; | ||
15234 | ADV_DCNT contig_len; | ||
15235 | ADV_SDCNT buf_size; | ||
15236 | ADV_PADDR carr_paddr; | ||
15237 | int i; | ||
15238 | ushort scsi_cfg1; | ||
15239 | uchar byte; | ||
15240 | uchar tid; | ||
15241 | ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */ | ||
15242 | ushort wdtr_able, sdtr_able, tagqng_able; | ||
15243 | uchar max_cmd[ADV_MAX_TID + 1]; | ||
15244 | |||
15245 | /* If there is already an error, don't continue. */ | ||
15246 | if (asc_dvc->err_code != 0) | ||
15247 | { | ||
15248 | return ADV_ERROR; | ||
15249 | } | ||
15250 | |||
15251 | /* | ||
15252 | * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800. | ||
15253 | */ | ||
15254 | if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) | ||
15255 | { | ||
15256 | asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE; | ||
15257 | return ADV_ERROR; | ||
15258 | } | ||
15259 | |||
15260 | warn_code = 0; | ||
15261 | iop_base = asc_dvc->iop_base; | ||
15262 | |||
15263 | /* | ||
15264 | * Save the RISC memory BIOS region before writing the microcode. | ||
15265 | * The BIOS may already be loaded and using its RISC LRAM region | ||
15266 | * so its region must be saved and restored. | ||
15267 | * | ||
15268 | * Note: This code makes the assumption, which is currently true, | ||
15269 | * that a chip reset does not clear RISC LRAM. | ||
15270 | */ | ||
15271 | for (i = 0; i < ASC_MC_BIOSLEN/2; i++) | ||
15272 | { | ||
15273 | AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]); | ||
15274 | } | ||
15275 | |||
15276 | /* | ||
15277 | * Save current per TID negotiated values. | ||
15278 | */ | ||
15279 | AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
15280 | AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
15281 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
15282 | for (tid = 0; tid <= ADV_MAX_TID; tid++) | ||
15283 | { | ||
15284 | AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
15285 | max_cmd[tid]); | ||
15286 | } | ||
15287 | |||
15288 | /* | ||
15289 | * RAM BIST (RAM Built-In Self Test) | ||
15290 | * | ||
15291 | * Address : I/O base + offset 0x38h register (byte). | ||
15292 | * Function: Bit 7-6(RW) : RAM mode | ||
15293 | * Normal Mode : 0x00 | ||
15294 | * Pre-test Mode : 0x40 | ||
15295 | * RAM Test Mode : 0x80 | ||
15296 | * Bit 5 : unused | ||
15297 | * Bit 4(RO) : Done bit | ||
15298 | * Bit 3-0(RO) : Status | ||
15299 | * Host Error : 0x08 | ||
15300 | * Int_RAM Error : 0x04 | ||
15301 | * RISC Error : 0x02 | ||
15302 | * SCSI Error : 0x01 | ||
15303 | * No Error : 0x00 | ||
15304 | * | ||
15305 | * Note: RAM BIST code should be put right here, before loading the | ||
15306 | * microcode and after saving the RISC memory BIOS region. | ||
15307 | */ | ||
15308 | |||
15309 | /* | ||
15310 | * LRAM Pre-test | ||
15311 | * | ||
15312 | * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds. | ||
15313 | * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return | ||
15314 | * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset | ||
15315 | * to NORMAL_MODE, return an error too. | ||
15316 | */ | ||
15317 | for (i = 0; i < 2; i++) | ||
15318 | { | ||
15319 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE); | ||
15320 | DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ | ||
15321 | byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); | ||
15322 | if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE) | ||
15323 | { | ||
15324 | asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; | ||
15325 | return ADV_ERROR; | ||
15326 | } | ||
15327 | |||
15328 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); | ||
15329 | DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ | ||
15330 | if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) | ||
15331 | != NORMAL_VALUE) | ||
15332 | { | ||
15333 | asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; | ||
15334 | return ADV_ERROR; | ||
15335 | } | ||
15336 | } | ||
15337 | |||
15338 | /* | ||
15339 | * LRAM Test - It takes about 1.5 ms to run through the test. | ||
15340 | * | ||
15341 | * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds. | ||
15342 | * If Done bit not set or Status not 0, save register byte, set the | ||
15343 | * err_code, and return an error. | ||
15344 | */ | ||
15345 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE); | ||
15346 | DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */ | ||
15347 | |||
15348 | byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); | ||
15349 | if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) | ||
15350 | { | ||
15351 | /* Get here if Done bit not set or Status not 0. */ | ||
15352 | asc_dvc->bist_err_code = byte; /* for BIOS display message */ | ||
15353 | asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST; | ||
15354 | return ADV_ERROR; | ||
15355 | } | ||
15356 | |||
15357 | /* We need to reset back to normal mode after LRAM test passes. */ | ||
15358 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); | ||
15359 | |||
15360 | /* | ||
15361 | * Load the Microcode | ||
15362 | * | ||
15363 | * Write the microcode image to RISC memory starting at address 0. | ||
15364 | * | ||
15365 | */ | ||
15366 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); | ||
15367 | |||
15368 | /* Assume the following compressed format of the microcode buffer: | ||
15369 | * | ||
15370 | * 254 word (508 byte) table indexed by byte code followed | ||
15371 | * by the following byte codes: | ||
15372 | * | ||
15373 | * 1-Byte Code: | ||
15374 | * 00: Emit word 0 in table. | ||
15375 | * 01: Emit word 1 in table. | ||
15376 | * . | ||
15377 | * FD: Emit word 253 in table. | ||
15378 | * | ||
15379 | * Multi-Byte Code: | ||
15380 | * FE WW WW: (3 byte code) Word to emit is the next word WW WW. | ||
15381 | * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. | ||
15382 | */ | ||
15383 | word = 0; | ||
15384 | for (i = 253 * 2; i < _adv_asc38C0800_size; i++) | ||
15385 | { | ||
15386 | if (_adv_asc38C0800_buf[i] == 0xff) | ||
15387 | { | ||
15388 | for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) | ||
15389 | { | ||
15390 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | ||
15391 | _adv_asc38C0800_buf[i + 3] << 8) | | ||
15392 | _adv_asc38C0800_buf[i + 2])); | ||
15393 | word++; | ||
15394 | } | ||
15395 | i += 3; | ||
15396 | } else if (_adv_asc38C0800_buf[i] == 0xfe) | ||
15397 | { | ||
15398 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | ||
15399 | _adv_asc38C0800_buf[i + 2] << 8) | | ||
15400 | _adv_asc38C0800_buf[i + 1])); | ||
15401 | i += 2; | ||
15402 | word++; | ||
15403 | } else | ||
15404 | { | ||
15405 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | ||
15406 | _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | | ||
15407 | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2])); | ||
15408 | word++; | ||
15409 | } | ||
15410 | } | ||
15411 | |||
15412 | /* | ||
15413 | * Set 'word' for later use to clear the rest of memory and save | ||
15414 | * the expanded mcode size. | ||
15415 | */ | ||
15416 | word *= 2; | ||
15417 | adv_asc38C0800_expanded_size = word; | ||
15418 | |||
15419 | /* | ||
15420 | * Clear the rest of ASC-38C0800 Internal RAM (16KB). | ||
15421 | */ | ||
15422 | for (; word < ADV_38C0800_MEMSIZE; word += 2) | ||
15423 | { | ||
15424 | AdvWriteWordAutoIncLram(iop_base, 0); | ||
15425 | } | ||
15426 | |||
15427 | /* | ||
15428 | * Verify the microcode checksum. | ||
15429 | */ | ||
15430 | sum = 0; | ||
15431 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); | ||
15432 | |||
15433 | for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) | ||
15434 | { | ||
15435 | sum += AdvReadWordAutoIncLram(iop_base); | ||
15436 | } | ||
15437 | ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i); | ||
15438 | |||
15439 | ASC_DBG2(1, | ||
15440 | "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n", | ||
15441 | (ulong) sum, (ulong) _adv_asc38C0800_chksum); | ||
15442 | |||
15443 | if (sum != _adv_asc38C0800_chksum) | ||
15444 | { | ||
15445 | asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; | ||
15446 | return ADV_ERROR; | ||
15447 | } | ||
15448 | |||
15449 | /* | ||
15450 | * Restore the RISC memory BIOS region. | ||
15451 | */ | ||
15452 | for (i = 0; i < ASC_MC_BIOSLEN/2; i++) | ||
15453 | { | ||
15454 | AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]); | ||
15455 | } | ||
15456 | |||
15457 | /* | ||
15458 | * Calculate and write the microcode code checksum to the microcode | ||
15459 | * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). | ||
15460 | */ | ||
15461 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr); | ||
15462 | AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr); | ||
15463 | code_sum = 0; | ||
15464 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr); | ||
15465 | for (word = begin_addr; word < end_addr; word += 2) | ||
15466 | { | ||
15467 | code_sum += AdvReadWordAutoIncLram(iop_base); | ||
15468 | } | ||
15469 | AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum); | ||
15470 | |||
15471 | /* | ||
15472 | * Read microcode version and date. | ||
15473 | */ | ||
15474 | AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date); | ||
15475 | AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version); | ||
15476 | |||
15477 | /* | ||
15478 | * Set the chip type to indicate the ASC38C0800. | ||
15479 | */ | ||
15480 | AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800); | ||
15481 | |||
15482 | /* | ||
15483 | * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register. | ||
15484 | * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current | ||
15485 | * cable detection and then we are able to read C_DET[3:0]. | ||
15486 | * | ||
15487 | * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1 | ||
15488 | * Microcode Default Value' section below. | ||
15489 | */ | ||
15490 | scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); | ||
15491 | AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV); | ||
15492 | |||
15493 | /* | ||
15494 | * If the PCI Configuration Command Register "Parity Error Response | ||
15495 | * Control" Bit was clear (0), then set the microcode variable | ||
15496 | * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode | ||
15497 | * to ignore DMA parity errors. | ||
15498 | */ | ||
15499 | if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) | ||
15500 | { | ||
15501 | AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
15502 | word |= CONTROL_FLAG_IGNORE_PERR; | ||
15503 | AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
15504 | } | ||
15505 | |||
15506 | /* | ||
15507 | * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2] | ||
15508 | * bits for the default FIFO threshold. | ||
15509 | * | ||
15510 | * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes. | ||
15511 | * | ||
15512 | * For DMA Errata #4 set the BC_THRESH_ENB bit. | ||
15513 | */ | ||
15514 | AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0, | ||
15515 | BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM); | ||
15516 | |||
15517 | /* | ||
15518 | * Microcode operating variables for WDTR, SDTR, and command tag | ||
15519 | * queuing will be set in AdvInquiryHandling() based on what a | ||
15520 | * device reports it is capable of in Inquiry byte 7. | ||
15521 | * | ||
15522 | * If SCSI Bus Resets have been disabled, then directly set | ||
15523 | * SDTR and WDTR from the EEPROM configuration. This will allow | ||
15524 | * the BIOS and warm boot to work without a SCSI bus hang on | ||
15525 | * the Inquiry caused by host and target mismatched DTR values. | ||
15526 | * Without the SCSI Bus Reset, before an Inquiry a device can't | ||
15527 | * be assumed to be in Asynchronous, Narrow mode. | ||
15528 | */ | ||
15529 | if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) | ||
15530 | { | ||
15531 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able); | ||
15532 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able); | ||
15533 | } | ||
15534 | |||
15535 | /* | ||
15536 | * Set microcode operating variables for DISC and SDTR_SPEED1, | ||
15537 | * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM | ||
15538 | * configuration values. | ||
15539 | * | ||
15540 | * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, | ||
15541 | * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them | ||
15542 | * without determining here whether the device supports SDTR. | ||
15543 | */ | ||
15544 | AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable); | ||
15545 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1); | ||
15546 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2); | ||
15547 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3); | ||
15548 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4); | ||
15549 | |||
15550 | /* | ||
15551 | * Set SCSI_CFG0 Microcode Default Value. | ||
15552 | * | ||
15553 | * The microcode will set the SCSI_CFG0 register using this value | ||
15554 | * after it is started below. | ||
15555 | */ | ||
15556 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0, | ||
15557 | PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN | | ||
15558 | asc_dvc->chip_scsi_id); | ||
15559 | |||
15560 | /* | ||
15561 | * Determine SCSI_CFG1 Microcode Default Value. | ||
15562 | * | ||
15563 | * The microcode will set the SCSI_CFG1 register using this value | ||
15564 | * after it is started below. | ||
15565 | */ | ||
15566 | |||
15567 | /* Read current SCSI_CFG1 Register value. */ | ||
15568 | scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); | ||
15569 | |||
15570 | /* | ||
15571 | * If the internal narrow cable is reversed all of the SCSI_CTRL | ||
15572 | * register signals will be set. Check for and return an error if | ||
15573 | * this condition is found. | ||
15574 | */ | ||
15575 | if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) | ||
15576 | { | ||
15577 | asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE; | ||
15578 | return ADV_ERROR; | ||
15579 | } | ||
15580 | |||
15581 | /* | ||
15582 | * All kind of combinations of devices attached to one of four connectors | ||
15583 | * are acceptable except HVD device attached. For example, LVD device can | ||
15584 | * be attached to SE connector while SE device attached to LVD connector. | ||
15585 | * If LVD device attached to SE connector, it only runs up to Ultra speed. | ||
15586 | * | ||
15587 | * If an HVD device is attached to one of LVD connectors, return an error. | ||
15588 | * However, there is no way to detect HVD device attached to SE connectors. | ||
15589 | */ | ||
15590 | if (scsi_cfg1 & HVD) | ||
15591 | { | ||
15592 | asc_dvc->err_code |= ASC_IERR_HVD_DEVICE; | ||
15593 | return ADV_ERROR; | ||
15594 | } | ||
15595 | |||
15596 | /* | ||
15597 | * If either SE or LVD automatic termination control is enabled, then | ||
15598 | * set the termination value based on a table listed in a_condor.h. | ||
15599 | * | ||
15600 | * If manual termination was specified with an EEPROM setting then | ||
15601 | * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to | ||
15602 | * be 'ored' into SCSI_CFG1. | ||
15603 | */ | ||
15604 | if ((asc_dvc->cfg->termination & TERM_SE) == 0) | ||
15605 | { | ||
15606 | /* SE automatic termination control is enabled. */ | ||
15607 | switch(scsi_cfg1 & C_DET_SE) | ||
15608 | { | ||
15609 | /* TERM_SE_HI: on, TERM_SE_LO: on */ | ||
15610 | case 0x1: case 0x2: case 0x3: | ||
15611 | asc_dvc->cfg->termination |= TERM_SE; | ||
15612 | break; | ||
15613 | |||
15614 | /* TERM_SE_HI: on, TERM_SE_LO: off */ | ||
15615 | case 0x0: | ||
15616 | asc_dvc->cfg->termination |= TERM_SE_HI; | ||
15617 | break; | ||
15618 | } | ||
15619 | } | ||
15620 | |||
15621 | if ((asc_dvc->cfg->termination & TERM_LVD) == 0) | ||
15622 | { | ||
15623 | /* LVD automatic termination control is enabled. */ | ||
15624 | switch(scsi_cfg1 & C_DET_LVD) | ||
15625 | { | ||
15626 | /* TERM_LVD_HI: on, TERM_LVD_LO: on */ | ||
15627 | case 0x4: case 0x8: case 0xC: | ||
15628 | asc_dvc->cfg->termination |= TERM_LVD; | ||
15629 | break; | ||
15630 | |||
15631 | /* TERM_LVD_HI: off, TERM_LVD_LO: off */ | ||
15632 | case 0x0: | ||
15633 | break; | ||
15634 | } | ||
15635 | } | ||
15636 | |||
15637 | /* | ||
15638 | * Clear any set TERM_SE and TERM_LVD bits. | ||
15639 | */ | ||
15640 | scsi_cfg1 &= (~TERM_SE & ~TERM_LVD); | ||
15641 | |||
15642 | /* | ||
15643 | * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'. | ||
15644 | */ | ||
15645 | scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0); | ||
15646 | |||
15647 | /* | ||
15648 | * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits | ||
15649 | * and set possibly modified termination control bits in the Microcode | ||
15650 | * SCSI_CFG1 Register Value. | ||
15651 | */ | ||
15652 | scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE); | ||
15653 | |||
15654 | /* | ||
15655 | * Set SCSI_CFG1 Microcode Default Value | ||
15656 | * | ||
15657 | * Set possibly modified termination control and reset DIS_TERM_DRV | ||
15658 | * bits in the Microcode SCSI_CFG1 Register Value. | ||
15659 | * | ||
15660 | * The microcode will set the SCSI_CFG1 register using this value | ||
15661 | * after it is started below. | ||
15662 | */ | ||
15663 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1); | ||
15664 | |||
15665 | /* | ||
15666 | * Set MEM_CFG Microcode Default Value | ||
15667 | * | ||
15668 | * The microcode will set the MEM_CFG register using this value | ||
15669 | * after it is started below. | ||
15670 | * | ||
15671 | * MEM_CFG may be accessed as a word or byte, but only bits 0-7 | ||
15672 | * are defined. | ||
15673 | * | ||
15674 | * ASC-38C0800 has 16KB internal memory. | ||
15675 | */ | ||
15676 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, | ||
15677 | BIOS_EN | RAM_SZ_16KB); | ||
15678 | |||
15679 | /* | ||
15680 | * Set SEL_MASK Microcode Default Value | ||
15681 | * | ||
15682 | * The microcode will set the SEL_MASK register using this value | ||
15683 | * after it is started below. | ||
15684 | */ | ||
15685 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, | ||
15686 | ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); | ||
15687 | |||
15688 | /* | ||
15689 | * Build the carrier freelist. | ||
15690 | * | ||
15691 | * Driver must have already allocated memory and set 'carrier_buf'. | ||
15692 | */ | ||
15693 | ASC_ASSERT(asc_dvc->carrier_buf != NULL); | ||
15694 | |||
15695 | carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf); | ||
15696 | asc_dvc->carr_freelist = NULL; | ||
15697 | if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) | ||
15698 | { | ||
15699 | buf_size = ADV_CARRIER_BUFSIZE; | ||
15700 | } else | ||
15701 | { | ||
15702 | buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T); | ||
15703 | } | ||
15704 | |||
15705 | do { | ||
15706 | /* | ||
15707 | * Get physical address for the carrier 'carrp'. | ||
15708 | */ | ||
15709 | contig_len = sizeof(ADV_CARR_T); | ||
15710 | carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp, | ||
15711 | (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG)); | ||
15712 | |||
15713 | buf_size -= sizeof(ADV_CARR_T); | ||
15714 | |||
15715 | /* | ||
15716 | * If the current carrier is not physically contiguous, then | ||
15717 | * maybe there was a page crossing. Try the next carrier aligned | ||
15718 | * start address. | ||
15719 | */ | ||
15720 | if (contig_len < sizeof(ADV_CARR_T)) | ||
15721 | { | ||
15722 | carrp++; | ||
15723 | continue; | ||
15724 | } | ||
15725 | |||
15726 | carrp->carr_pa = carr_paddr; | ||
15727 | carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp)); | ||
15728 | |||
15729 | /* | ||
15730 | * Insert the carrier at the beginning of the freelist. | ||
15731 | */ | ||
15732 | carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); | ||
15733 | asc_dvc->carr_freelist = carrp; | ||
15734 | |||
15735 | carrp++; | ||
15736 | } | ||
15737 | while (buf_size > 0); | ||
15738 | |||
15739 | /* | ||
15740 | * Set-up the Host->RISC Initiator Command Queue (ICQ). | ||
15741 | */ | ||
15742 | |||
15743 | if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) | ||
15744 | { | ||
15745 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
15746 | return ADV_ERROR; | ||
15747 | } | ||
15748 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
15749 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa)); | ||
15750 | |||
15751 | /* | ||
15752 | * The first command issued will be placed in the stopper carrier. | ||
15753 | */ | ||
15754 | asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
15755 | |||
15756 | /* | ||
15757 | * Set RISC ICQ physical address start value. | ||
15758 | * carr_pa is LE, must be native before write | ||
15759 | */ | ||
15760 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa); | ||
15761 | |||
15762 | /* | ||
15763 | * Set-up the RISC->Host Initiator Response Queue (IRQ). | ||
15764 | */ | ||
15765 | if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) | ||
15766 | { | ||
15767 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
15768 | return ADV_ERROR; | ||
15769 | } | ||
15770 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
15771 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa)); | ||
15772 | |||
15773 | /* | ||
15774 | * The first command completed by the RISC will be placed in | ||
15775 | * the stopper. | ||
15776 | * | ||
15777 | * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is | ||
15778 | * completed the RISC will set the ASC_RQ_STOPPER bit. | ||
15779 | */ | ||
15780 | asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
15781 | |||
15782 | /* | ||
15783 | * Set RISC IRQ physical address start value. | ||
15784 | * | ||
15785 | * carr_pa is LE, must be native before write * | ||
15786 | */ | ||
15787 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa); | ||
15788 | asc_dvc->carr_pending_cnt = 0; | ||
15789 | |||
15790 | AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES, | ||
15791 | (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR)); | ||
15792 | |||
15793 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word); | ||
15794 | AdvWriteWordRegister(iop_base, IOPW_PC, word); | ||
15795 | |||
15796 | /* finally, finally, gentlemen, start your engine */ | ||
15797 | AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN); | ||
15798 | |||
15799 | /* | ||
15800 | * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus | ||
15801 | * Resets should be performed. The RISC has to be running | ||
15802 | * to issue a SCSI Bus Reset. | ||
15803 | */ | ||
15804 | if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) | ||
15805 | { | ||
15806 | /* | ||
15807 | * If the BIOS Signature is present in memory, restore the | ||
15808 | * BIOS Handshake Configuration Table and do not perform | ||
15809 | * a SCSI Bus Reset. | ||
15810 | */ | ||
15811 | if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA) | ||
15812 | { | ||
15813 | /* | ||
15814 | * Restore per TID negotiated values. | ||
15815 | */ | ||
15816 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
15817 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
15818 | AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
15819 | for (tid = 0; tid <= ADV_MAX_TID; tid++) | ||
15820 | { | ||
15821 | AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
15822 | max_cmd[tid]); | ||
15823 | } | ||
15824 | } else | ||
15825 | { | ||
15826 | if (AdvResetSB(asc_dvc) != ADV_TRUE) | ||
15827 | { | ||
15828 | warn_code = ASC_WARN_BUSRESET_ERROR; | ||
15829 | } | ||
15830 | } | ||
15831 | } | ||
15832 | |||
15833 | return warn_code; | ||
15834 | } | ||
15835 | |||
15836 | /* | ||
15837 | * Initialize the ASC-38C1600. | ||
15838 | * | ||
15839 | * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR. | ||
15840 | * | ||
15841 | * For a non-fatal error return a warning code. If there are no warnings | ||
15842 | * then 0 is returned. | ||
15843 | * | ||
15844 | * Needed after initialization for error recovery. | ||
15845 | */ | ||
15846 | STATIC int | ||
15847 | AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) | ||
15848 | { | ||
15849 | AdvPortAddr iop_base; | ||
15850 | ushort warn_code; | ||
15851 | ADV_DCNT sum; | ||
15852 | int begin_addr; | ||
15853 | int end_addr; | ||
15854 | ushort code_sum; | ||
15855 | long word; | ||
15856 | int j; | ||
15857 | int adv_asc38C1600_expanded_size; | ||
15858 | ADV_CARR_T *carrp; | ||
15859 | ADV_DCNT contig_len; | ||
15860 | ADV_SDCNT buf_size; | ||
15861 | ADV_PADDR carr_paddr; | ||
15862 | int i; | ||
15863 | ushort scsi_cfg1; | ||
15864 | uchar byte; | ||
15865 | uchar tid; | ||
15866 | ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */ | ||
15867 | ushort wdtr_able, sdtr_able, ppr_able, tagqng_able; | ||
15868 | uchar max_cmd[ASC_MAX_TID + 1]; | ||
15869 | |||
15870 | /* If there is already an error, don't continue. */ | ||
15871 | if (asc_dvc->err_code != 0) | ||
15872 | { | ||
15873 | return ADV_ERROR; | ||
15874 | } | ||
15875 | |||
15876 | /* | ||
15877 | * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600. | ||
15878 | */ | ||
15879 | if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) | ||
15880 | { | ||
15881 | asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE; | ||
15882 | return ADV_ERROR; | ||
15883 | } | ||
15884 | |||
15885 | warn_code = 0; | ||
15886 | iop_base = asc_dvc->iop_base; | ||
15887 | |||
15888 | /* | ||
15889 | * Save the RISC memory BIOS region before writing the microcode. | ||
15890 | * The BIOS may already be loaded and using its RISC LRAM region | ||
15891 | * so its region must be saved and restored. | ||
15892 | * | ||
15893 | * Note: This code makes the assumption, which is currently true, | ||
15894 | * that a chip reset does not clear RISC LRAM. | ||
15895 | */ | ||
15896 | for (i = 0; i < ASC_MC_BIOSLEN/2; i++) | ||
15897 | { | ||
15898 | AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]); | ||
15899 | } | ||
15900 | |||
15901 | /* | ||
15902 | * Save current per TID negotiated values. | ||
15903 | */ | ||
15904 | AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
15905 | AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
15906 | AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); | ||
15907 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
15908 | for (tid = 0; tid <= ASC_MAX_TID; tid++) | ||
15909 | { | ||
15910 | AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
15911 | max_cmd[tid]); | ||
15912 | } | ||
15913 | |||
15914 | /* | ||
15915 | * RAM BIST (Built-In Self Test) | ||
15916 | * | ||
15917 | * Address : I/O base + offset 0x38h register (byte). | ||
15918 | * Function: Bit 7-6(RW) : RAM mode | ||
15919 | * Normal Mode : 0x00 | ||
15920 | * Pre-test Mode : 0x40 | ||
15921 | * RAM Test Mode : 0x80 | ||
15922 | * Bit 5 : unused | ||
15923 | * Bit 4(RO) : Done bit | ||
15924 | * Bit 3-0(RO) : Status | ||
15925 | * Host Error : 0x08 | ||
15926 | * Int_RAM Error : 0x04 | ||
15927 | * RISC Error : 0x02 | ||
15928 | * SCSI Error : 0x01 | ||
15929 | * No Error : 0x00 | ||
15930 | * | ||
15931 | * Note: RAM BIST code should be put right here, before loading the | ||
15932 | * microcode and after saving the RISC memory BIOS region. | ||
15933 | */ | ||
15934 | |||
15935 | /* | ||
15936 | * LRAM Pre-test | ||
15937 | * | ||
15938 | * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds. | ||
15939 | * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return | ||
15940 | * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset | ||
15941 | * to NORMAL_MODE, return an error too. | ||
15942 | */ | ||
15943 | for (i = 0; i < 2; i++) | ||
15944 | { | ||
15945 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE); | ||
15946 | DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ | ||
15947 | byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); | ||
15948 | if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE) | ||
15949 | { | ||
15950 | asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; | ||
15951 | return ADV_ERROR; | ||
15952 | } | ||
15953 | |||
15954 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); | ||
15955 | DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ | ||
15956 | if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) | ||
15957 | != NORMAL_VALUE) | ||
15958 | { | ||
15959 | asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; | ||
15960 | return ADV_ERROR; | ||
15961 | } | ||
15962 | } | ||
15963 | |||
15964 | /* | ||
15965 | * LRAM Test - It takes about 1.5 ms to run through the test. | ||
15966 | * | ||
15967 | * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds. | ||
15968 | * If Done bit not set or Status not 0, save register byte, set the | ||
15969 | * err_code, and return an error. | ||
15970 | */ | ||
15971 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE); | ||
15972 | DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */ | ||
15973 | |||
15974 | byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); | ||
15975 | if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) | ||
15976 | { | ||
15977 | /* Get here if Done bit not set or Status not 0. */ | ||
15978 | asc_dvc->bist_err_code = byte; /* for BIOS display message */ | ||
15979 | asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST; | ||
15980 | return ADV_ERROR; | ||
15981 | } | ||
15982 | |||
15983 | /* We need to reset back to normal mode after LRAM test passes. */ | ||
15984 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); | ||
15985 | |||
15986 | /* | ||
15987 | * Load the Microcode | ||
15988 | * | ||
15989 | * Write the microcode image to RISC memory starting at address 0. | ||
15990 | * | ||
15991 | */ | ||
15992 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); | ||
15993 | |||
15994 | /* | ||
15995 | * Assume the following compressed format of the microcode buffer: | ||
15996 | * | ||
15997 | * 254 word (508 byte) table indexed by byte code followed | ||
15998 | * by the following byte codes: | ||
15999 | * | ||
16000 | * 1-Byte Code: | ||
16001 | * 00: Emit word 0 in table. | ||
16002 | * 01: Emit word 1 in table. | ||
16003 | * . | ||
16004 | * FD: Emit word 253 in table. | ||
16005 | * | ||
16006 | * Multi-Byte Code: | ||
16007 | * FE WW WW: (3 byte code) Word to emit is the next word WW WW. | ||
16008 | * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. | ||
16009 | */ | ||
16010 | word = 0; | ||
16011 | for (i = 253 * 2; i < _adv_asc38C1600_size; i++) | ||
16012 | { | ||
16013 | if (_adv_asc38C1600_buf[i] == 0xff) | ||
16014 | { | ||
16015 | for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) | ||
16016 | { | ||
16017 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | ||
16018 | _adv_asc38C1600_buf[i + 3] << 8) | | ||
16019 | _adv_asc38C1600_buf[i + 2])); | ||
16020 | word++; | ||
16021 | } | ||
16022 | i += 3; | ||
16023 | } else if (_adv_asc38C1600_buf[i] == 0xfe) | ||
16024 | { | ||
16025 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | ||
16026 | _adv_asc38C1600_buf[i + 2] << 8) | | ||
16027 | _adv_asc38C1600_buf[i + 1])); | ||
16028 | i += 2; | ||
16029 | word++; | ||
16030 | } else | ||
16031 | { | ||
16032 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | ||
16033 | _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | | ||
16034 | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2])); | ||
16035 | word++; | ||
16036 | } | ||
16037 | } | ||
16038 | |||
16039 | /* | ||
16040 | * Set 'word' for later use to clear the rest of memory and save | ||
16041 | * the expanded mcode size. | ||
16042 | */ | ||
16043 | word *= 2; | ||
16044 | adv_asc38C1600_expanded_size = word; | ||
16045 | |||
16046 | /* | ||
16047 | * Clear the rest of ASC-38C1600 Internal RAM (32KB). | ||
16048 | */ | ||
16049 | for (; word < ADV_38C1600_MEMSIZE; word += 2) | ||
16050 | { | ||
16051 | AdvWriteWordAutoIncLram(iop_base, 0); | ||
16052 | } | ||
16053 | |||
16054 | /* | ||
16055 | * Verify the microcode checksum. | ||
16056 | */ | ||
16057 | sum = 0; | ||
16058 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); | ||
16059 | |||
16060 | for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) | ||
16061 | { | ||
16062 | sum += AdvReadWordAutoIncLram(iop_base); | ||
16063 | } | ||
16064 | |||
16065 | if (sum != _adv_asc38C1600_chksum) | ||
16066 | { | ||
16067 | asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; | ||
16068 | return ADV_ERROR; | ||
16069 | } | ||
16070 | |||
16071 | /* | ||
16072 | * Restore the RISC memory BIOS region. | ||
16073 | */ | ||
16074 | for (i = 0; i < ASC_MC_BIOSLEN/2; i++) | ||
16075 | { | ||
16076 | AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]); | ||
16077 | } | ||
16078 | |||
16079 | /* | ||
16080 | * Calculate and write the microcode code checksum to the microcode | ||
16081 | * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). | ||
16082 | */ | ||
16083 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr); | ||
16084 | AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr); | ||
16085 | code_sum = 0; | ||
16086 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr); | ||
16087 | for (word = begin_addr; word < end_addr; word += 2) | ||
16088 | { | ||
16089 | code_sum += AdvReadWordAutoIncLram(iop_base); | ||
16090 | } | ||
16091 | AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum); | ||
16092 | |||
16093 | /* | ||
16094 | * Read microcode version and date. | ||
16095 | */ | ||
16096 | AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date); | ||
16097 | AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version); | ||
16098 | |||
16099 | /* | ||
16100 | * Set the chip type to indicate the ASC38C1600. | ||
16101 | */ | ||
16102 | AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600); | ||
16103 | |||
16104 | /* | ||
16105 | * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register. | ||
16106 | * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current | ||
16107 | * cable detection and then we are able to read C_DET[3:0]. | ||
16108 | * | ||
16109 | * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1 | ||
16110 | * Microcode Default Value' section below. | ||
16111 | */ | ||
16112 | scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); | ||
16113 | AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV); | ||
16114 | |||
16115 | /* | ||
16116 | * If the PCI Configuration Command Register "Parity Error Response | ||
16117 | * Control" Bit was clear (0), then set the microcode variable | ||
16118 | * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode | ||
16119 | * to ignore DMA parity errors. | ||
16120 | */ | ||
16121 | if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) | ||
16122 | { | ||
16123 | AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
16124 | word |= CONTROL_FLAG_IGNORE_PERR; | ||
16125 | AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
16126 | } | ||
16127 | |||
16128 | /* | ||
16129 | * If the BIOS control flag AIPP (Asynchronous Information | ||
16130 | * Phase Protection) disable bit is not set, then set the firmware | ||
16131 | * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable | ||
16132 | * AIPP checking and encoding. | ||
16133 | */ | ||
16134 | if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) | ||
16135 | { | ||
16136 | AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
16137 | word |= CONTROL_FLAG_ENABLE_AIPP; | ||
16138 | AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
16139 | } | ||
16140 | |||
16141 | /* | ||
16142 | * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4], | ||
16143 | * and START_CTL_TH [3:2]. | ||
16144 | */ | ||
16145 | AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0, | ||
16146 | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM); | ||
16147 | |||
16148 | /* | ||
16149 | * Microcode operating variables for WDTR, SDTR, and command tag | ||
16150 | * queuing will be set in AdvInquiryHandling() based on what a | ||
16151 | * device reports it is capable of in Inquiry byte 7. | ||
16152 | * | ||
16153 | * If SCSI Bus Resets have been disabled, then directly set | ||
16154 | * SDTR and WDTR from the EEPROM configuration. This will allow | ||
16155 | * the BIOS and warm boot to work without a SCSI bus hang on | ||
16156 | * the Inquiry caused by host and target mismatched DTR values. | ||
16157 | * Without the SCSI Bus Reset, before an Inquiry a device can't | ||
16158 | * be assumed to be in Asynchronous, Narrow mode. | ||
16159 | */ | ||
16160 | if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) | ||
16161 | { | ||
16162 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able); | ||
16163 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able); | ||
16164 | } | ||
16165 | |||
16166 | /* | ||
16167 | * Set microcode operating variables for DISC and SDTR_SPEED1, | ||
16168 | * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM | ||
16169 | * configuration values. | ||
16170 | * | ||
16171 | * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, | ||
16172 | * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them | ||
16173 | * without determining here whether the device supports SDTR. | ||
16174 | */ | ||
16175 | AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable); | ||
16176 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1); | ||
16177 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2); | ||
16178 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3); | ||
16179 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4); | ||
16180 | |||
16181 | /* | ||
16182 | * Set SCSI_CFG0 Microcode Default Value. | ||
16183 | * | ||
16184 | * The microcode will set the SCSI_CFG0 register using this value | ||
16185 | * after it is started below. | ||
16186 | */ | ||
16187 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0, | ||
16188 | PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN | | ||
16189 | asc_dvc->chip_scsi_id); | ||
16190 | |||
16191 | /* | ||
16192 | * Calculate SCSI_CFG1 Microcode Default Value. | ||
16193 | * | ||
16194 | * The microcode will set the SCSI_CFG1 register using this value | ||
16195 | * after it is started below. | ||
16196 | * | ||
16197 | * Each ASC-38C1600 function has only two cable detect bits. | ||
16198 | * The bus mode override bits are in IOPB_SOFT_OVER_WR. | ||
16199 | */ | ||
16200 | scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); | ||
16201 | |||
16202 | /* | ||
16203 | * If the cable is reversed all of the SCSI_CTRL register signals | ||
16204 | * will be set. Check for and return an error if this condition is | ||
16205 | * found. | ||
16206 | */ | ||
16207 | if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) | ||
16208 | { | ||
16209 | asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE; | ||
16210 | return ADV_ERROR; | ||
16211 | } | ||
16212 | |||
16213 | /* | ||
16214 | * Each ASC-38C1600 function has two connectors. Only an HVD device | ||
16215 | * can not be connected to either connector. An LVD device or SE device | ||
16216 | * may be connected to either connecor. If an SE device is connected, | ||
16217 | * then at most Ultra speed (20 Mhz) can be used on both connectors. | ||
16218 | * | ||
16219 | * If an HVD device is attached, return an error. | ||
16220 | */ | ||
16221 | if (scsi_cfg1 & HVD) | ||
16222 | { | ||
16223 | asc_dvc->err_code |= ASC_IERR_HVD_DEVICE; | ||
16224 | return ADV_ERROR; | ||
16225 | } | ||
16226 | |||
16227 | /* | ||
16228 | * Each function in the ASC-38C1600 uses only the SE cable detect and | ||
16229 | * termination because there are two connectors for each function. Each | ||
16230 | * function may use either LVD or SE mode. Corresponding the SE automatic | ||
16231 | * termination control EEPROM bits are used for each function. Each | ||
16232 | * function has its own EEPROM. If SE automatic control is enabled for | ||
16233 | * the function, then set the termination value based on a table listed | ||
16234 | * in a_condor.h. | ||
16235 | * | ||
16236 | * If manual termination is specified in the EEPROM for the function, | ||
16237 | * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is | ||
16238 | * ready to be 'ored' into SCSI_CFG1. | ||
16239 | */ | ||
16240 | if ((asc_dvc->cfg->termination & TERM_SE) == 0) | ||
16241 | { | ||
16242 | /* SE automatic termination control is enabled. */ | ||
16243 | switch(scsi_cfg1 & C_DET_SE) | ||
16244 | { | ||
16245 | /* TERM_SE_HI: on, TERM_SE_LO: on */ | ||
16246 | case 0x1: case 0x2: case 0x3: | ||
16247 | asc_dvc->cfg->termination |= TERM_SE; | ||
16248 | break; | ||
16249 | |||
16250 | case 0x0: | ||
16251 | if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0) | ||
16252 | { | ||
16253 | /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */ | ||
16254 | } | ||
16255 | else | ||
16256 | { | ||
16257 | /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */ | ||
16258 | asc_dvc->cfg->termination |= TERM_SE_HI; | ||
16259 | } | ||
16260 | break; | ||
16261 | } | ||
16262 | } | ||
16263 | |||
16264 | /* | ||
16265 | * Clear any set TERM_SE bits. | ||
16266 | */ | ||
16267 | scsi_cfg1 &= ~TERM_SE; | ||
16268 | |||
16269 | /* | ||
16270 | * Invert the TERM_SE bits and then set 'scsi_cfg1'. | ||
16271 | */ | ||
16272 | scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE); | ||
16273 | |||
16274 | /* | ||
16275 | * Clear Big Endian and Terminator Polarity bits and set possibly | ||
16276 | * modified termination control bits in the Microcode SCSI_CFG1 | ||
16277 | * Register Value. | ||
16278 | * | ||
16279 | * Big Endian bit is not used even on big endian machines. | ||
16280 | */ | ||
16281 | scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL); | ||
16282 | |||
16283 | /* | ||
16284 | * Set SCSI_CFG1 Microcode Default Value | ||
16285 | * | ||
16286 | * Set possibly modified termination control bits in the Microcode | ||
16287 | * SCSI_CFG1 Register Value. | ||
16288 | * | ||
16289 | * The microcode will set the SCSI_CFG1 register using this value | ||
16290 | * after it is started below. | ||
16291 | */ | ||
16292 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1); | ||
16293 | |||
16294 | /* | ||
16295 | * Set MEM_CFG Microcode Default Value | ||
16296 | * | ||
16297 | * The microcode will set the MEM_CFG register using this value | ||
16298 | * after it is started below. | ||
16299 | * | ||
16300 | * MEM_CFG may be accessed as a word or byte, but only bits 0-7 | ||
16301 | * are defined. | ||
16302 | * | ||
16303 | * ASC-38C1600 has 32KB internal memory. | ||
16304 | * | ||
16305 | * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come | ||
16306 | * out a special 16K Adv Library and Microcode version. After the issue | ||
16307 | * resolved, we should turn back to the 32K support. Both a_condor.h and | ||
16308 | * mcode.sas files also need to be updated. | ||
16309 | * | ||
16310 | * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, | ||
16311 | * BIOS_EN | RAM_SZ_32KB); | ||
16312 | */ | ||
16313 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, BIOS_EN | RAM_SZ_16KB); | ||
16314 | |||
16315 | /* | ||
16316 | * Set SEL_MASK Microcode Default Value | ||
16317 | * | ||
16318 | * The microcode will set the SEL_MASK register using this value | ||
16319 | * after it is started below. | ||
16320 | */ | ||
16321 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, | ||
16322 | ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); | ||
16323 | |||
16324 | /* | ||
16325 | * Build the carrier freelist. | ||
16326 | * | ||
16327 | * Driver must have already allocated memory and set 'carrier_buf'. | ||
16328 | */ | ||
16329 | |||
16330 | ASC_ASSERT(asc_dvc->carrier_buf != NULL); | ||
16331 | |||
16332 | carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf); | ||
16333 | asc_dvc->carr_freelist = NULL; | ||
16334 | if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) | ||
16335 | { | ||
16336 | buf_size = ADV_CARRIER_BUFSIZE; | ||
16337 | } else | ||
16338 | { | ||
16339 | buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T); | ||
16340 | } | ||
16341 | |||
16342 | do { | ||
16343 | /* | ||
16344 | * Get physical address for the carrier 'carrp'. | ||
16345 | */ | ||
16346 | contig_len = sizeof(ADV_CARR_T); | ||
16347 | carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp, | ||
16348 | (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG)); | ||
16349 | |||
16350 | buf_size -= sizeof(ADV_CARR_T); | ||
16351 | |||
16352 | /* | ||
16353 | * If the current carrier is not physically contiguous, then | ||
16354 | * maybe there was a page crossing. Try the next carrier aligned | ||
16355 | * start address. | ||
16356 | */ | ||
16357 | if (contig_len < sizeof(ADV_CARR_T)) | ||
16358 | { | ||
16359 | carrp++; | ||
16360 | continue; | ||
16361 | } | ||
16362 | |||
16363 | carrp->carr_pa = carr_paddr; | ||
16364 | carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp)); | ||
16365 | |||
16366 | /* | ||
16367 | * Insert the carrier at the beginning of the freelist. | ||
16368 | */ | ||
16369 | carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); | ||
16370 | asc_dvc->carr_freelist = carrp; | ||
16371 | |||
16372 | carrp++; | ||
16373 | } | ||
16374 | while (buf_size > 0); | ||
16375 | |||
16376 | /* | ||
16377 | * Set-up the Host->RISC Initiator Command Queue (ICQ). | ||
16378 | */ | ||
16379 | if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) | ||
16380 | { | ||
16381 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
16382 | return ADV_ERROR; | ||
16383 | } | ||
16384 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
16385 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa)); | ||
16386 | |||
16387 | /* | ||
16388 | * The first command issued will be placed in the stopper carrier. | ||
16389 | */ | ||
16390 | asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
16391 | |||
16392 | /* | ||
16393 | * Set RISC ICQ physical address start value. Initialize the | ||
16394 | * COMMA register to the same value otherwise the RISC will | ||
16395 | * prematurely detect a command is available. | ||
16396 | */ | ||
16397 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa); | ||
16398 | AdvWriteDWordRegister(iop_base, IOPDW_COMMA, | ||
16399 | le32_to_cpu(asc_dvc->icq_sp->carr_pa)); | ||
16400 | |||
16401 | /* | ||
16402 | * Set-up the RISC->Host Initiator Response Queue (IRQ). | ||
16403 | */ | ||
16404 | if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) | ||
16405 | { | ||
16406 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
16407 | return ADV_ERROR; | ||
16408 | } | ||
16409 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
16410 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa)); | ||
16411 | |||
16412 | /* | ||
16413 | * The first command completed by the RISC will be placed in | ||
16414 | * the stopper. | ||
16415 | * | ||
16416 | * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is | ||
16417 | * completed the RISC will set the ASC_RQ_STOPPER bit. | ||
16418 | */ | ||
16419 | asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
16420 | |||
16421 | /* | ||
16422 | * Set RISC IRQ physical address start value. | ||
16423 | */ | ||
16424 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa); | ||
16425 | asc_dvc->carr_pending_cnt = 0; | ||
16426 | |||
16427 | AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES, | ||
16428 | (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR)); | ||
16429 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word); | ||
16430 | AdvWriteWordRegister(iop_base, IOPW_PC, word); | ||
16431 | |||
16432 | /* finally, finally, gentlemen, start your engine */ | ||
16433 | AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN); | ||
16434 | |||
16435 | /* | ||
16436 | * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus | ||
16437 | * Resets should be performed. The RISC has to be running | ||
16438 | * to issue a SCSI Bus Reset. | ||
16439 | */ | ||
16440 | if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) | ||
16441 | { | ||
16442 | /* | ||
16443 | * If the BIOS Signature is present in memory, restore the | ||
16444 | * per TID microcode operating variables. | ||
16445 | */ | ||
16446 | if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA) | ||
16447 | { | ||
16448 | /* | ||
16449 | * Restore per TID negotiated values. | ||
16450 | */ | ||
16451 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
16452 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
16453 | AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); | ||
16454 | AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
16455 | for (tid = 0; tid <= ASC_MAX_TID; tid++) | ||
16456 | { | ||
16457 | AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
16458 | max_cmd[tid]); | ||
16459 | } | ||
16460 | } else | ||
16461 | { | ||
16462 | if (AdvResetSB(asc_dvc) != ADV_TRUE) | ||
16463 | { | ||
16464 | warn_code = ASC_WARN_BUSRESET_ERROR; | ||
16465 | } | ||
16466 | } | ||
16467 | } | ||
16468 | |||
16469 | return warn_code; | ||
16470 | } | ||
16471 | |||
16472 | /* | ||
16473 | * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and | ||
16474 | * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while | ||
16475 | * all of this is done. | ||
16476 | * | ||
16477 | * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. | ||
16478 | * | ||
16479 | * For a non-fatal error return a warning code. If there are no warnings | ||
16480 | * then 0 is returned. | ||
16481 | * | ||
16482 | * Note: Chip is stopped on entry. | ||
16483 | */ | ||
16484 | STATIC int __init | ||
16485 | AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc) | ||
16486 | { | ||
16487 | AdvPortAddr iop_base; | ||
16488 | ushort warn_code; | ||
16489 | ADVEEP_3550_CONFIG eep_config; | ||
16490 | int i; | ||
16491 | |||
16492 | iop_base = asc_dvc->iop_base; | ||
16493 | |||
16494 | warn_code = 0; | ||
16495 | |||
16496 | /* | ||
16497 | * Read the board's EEPROM configuration. | ||
16498 | * | ||
16499 | * Set default values if a bad checksum is found. | ||
16500 | */ | ||
16501 | if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) | ||
16502 | { | ||
16503 | warn_code |= ASC_WARN_EEPROM_CHKSUM; | ||
16504 | |||
16505 | /* | ||
16506 | * Set EEPROM default values. | ||
16507 | */ | ||
16508 | for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++) | ||
16509 | { | ||
16510 | *((uchar *) &eep_config + i) = | ||
16511 | *((uchar *) &Default_3550_EEPROM_Config + i); | ||
16512 | } | ||
16513 | |||
16514 | /* | ||
16515 | * Assume the 6 byte board serial number that was read | ||
16516 | * from EEPROM is correct even if the EEPROM checksum | ||
16517 | * failed. | ||
16518 | */ | ||
16519 | eep_config.serial_number_word3 = | ||
16520 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); | ||
16521 | |||
16522 | eep_config.serial_number_word2 = | ||
16523 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2); | ||
16524 | |||
16525 | eep_config.serial_number_word1 = | ||
16526 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3); | ||
16527 | |||
16528 | AdvSet3550EEPConfig(iop_base, &eep_config); | ||
16529 | } | ||
16530 | /* | ||
16531 | * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the | ||
16532 | * EEPROM configuration that was read. | ||
16533 | * | ||
16534 | * This is the mapping of EEPROM fields to Adv Library fields. | ||
16535 | */ | ||
16536 | asc_dvc->wdtr_able = eep_config.wdtr_able; | ||
16537 | asc_dvc->sdtr_able = eep_config.sdtr_able; | ||
16538 | asc_dvc->ultra_able = eep_config.ultra_able; | ||
16539 | asc_dvc->tagqng_able = eep_config.tagqng_able; | ||
16540 | asc_dvc->cfg->disc_enable = eep_config.disc_enable; | ||
16541 | asc_dvc->max_host_qng = eep_config.max_host_qng; | ||
16542 | asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; | ||
16543 | asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID); | ||
16544 | asc_dvc->start_motor = eep_config.start_motor; | ||
16545 | asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay; | ||
16546 | asc_dvc->bios_ctrl = eep_config.bios_ctrl; | ||
16547 | asc_dvc->no_scam = eep_config.scam_tolerant; | ||
16548 | asc_dvc->cfg->serial1 = eep_config.serial_number_word1; | ||
16549 | asc_dvc->cfg->serial2 = eep_config.serial_number_word2; | ||
16550 | asc_dvc->cfg->serial3 = eep_config.serial_number_word3; | ||
16551 | |||
16552 | /* | ||
16553 | * Set the host maximum queuing (max. 253, min. 16) and the per device | ||
16554 | * maximum queuing (max. 63, min. 4). | ||
16555 | */ | ||
16556 | if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) | ||
16557 | { | ||
16558 | eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; | ||
16559 | } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) | ||
16560 | { | ||
16561 | /* If the value is zero, assume it is uninitialized. */ | ||
16562 | if (eep_config.max_host_qng == 0) | ||
16563 | { | ||
16564 | eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; | ||
16565 | } else | ||
16566 | { | ||
16567 | eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG; | ||
16568 | } | ||
16569 | } | ||
16570 | |||
16571 | if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) | ||
16572 | { | ||
16573 | eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; | ||
16574 | } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) | ||
16575 | { | ||
16576 | /* If the value is zero, assume it is uninitialized. */ | ||
16577 | if (eep_config.max_dvc_qng == 0) | ||
16578 | { | ||
16579 | eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; | ||
16580 | } else | ||
16581 | { | ||
16582 | eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG; | ||
16583 | } | ||
16584 | } | ||
16585 | |||
16586 | /* | ||
16587 | * If 'max_dvc_qng' is greater than 'max_host_qng', then | ||
16588 | * set 'max_dvc_qng' to 'max_host_qng'. | ||
16589 | */ | ||
16590 | if (eep_config.max_dvc_qng > eep_config.max_host_qng) | ||
16591 | { | ||
16592 | eep_config.max_dvc_qng = eep_config.max_host_qng; | ||
16593 | } | ||
16594 | |||
16595 | /* | ||
16596 | * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng' | ||
16597 | * values based on possibly adjusted EEPROM values. | ||
16598 | */ | ||
16599 | asc_dvc->max_host_qng = eep_config.max_host_qng; | ||
16600 | asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; | ||
16601 | |||
16602 | |||
16603 | /* | ||
16604 | * If the EEPROM 'termination' field is set to automatic (0), then set | ||
16605 | * the ADV_DVC_CFG 'termination' field to automatic also. | ||
16606 | * | ||
16607 | * If the termination is specified with a non-zero 'termination' | ||
16608 | * value check that a legal value is set and set the ADV_DVC_CFG | ||
16609 | * 'termination' field appropriately. | ||
16610 | */ | ||
16611 | if (eep_config.termination == 0) | ||
16612 | { | ||
16613 | asc_dvc->cfg->termination = 0; /* auto termination */ | ||
16614 | } else | ||
16615 | { | ||
16616 | /* Enable manual control with low off / high off. */ | ||
16617 | if (eep_config.termination == 1) | ||
16618 | { | ||
16619 | asc_dvc->cfg->termination = TERM_CTL_SEL; | ||
16620 | |||
16621 | /* Enable manual control with low off / high on. */ | ||
16622 | } else if (eep_config.termination == 2) | ||
16623 | { | ||
16624 | asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H; | ||
16625 | |||
16626 | /* Enable manual control with low on / high on. */ | ||
16627 | } else if (eep_config.termination == 3) | ||
16628 | { | ||
16629 | asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L; | ||
16630 | } else | ||
16631 | { | ||
16632 | /* | ||
16633 | * The EEPROM 'termination' field contains a bad value. Use | ||
16634 | * automatic termination instead. | ||
16635 | */ | ||
16636 | asc_dvc->cfg->termination = 0; | ||
16637 | warn_code |= ASC_WARN_EEPROM_TERMINATION; | ||
16638 | } | ||
16639 | } | ||
16640 | |||
16641 | return warn_code; | ||
16642 | } | ||
16643 | |||
16644 | /* | ||
16645 | * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and | ||
16646 | * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while | ||
16647 | * all of this is done. | ||
16648 | * | ||
16649 | * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. | ||
16650 | * | ||
16651 | * For a non-fatal error return a warning code. If there are no warnings | ||
16652 | * then 0 is returned. | ||
16653 | * | ||
16654 | * Note: Chip is stopped on entry. | ||
16655 | */ | ||
16656 | STATIC int __init | ||
16657 | AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc) | ||
16658 | { | ||
16659 | AdvPortAddr iop_base; | ||
16660 | ushort warn_code; | ||
16661 | ADVEEP_38C0800_CONFIG eep_config; | ||
16662 | int i; | ||
16663 | uchar tid, termination; | ||
16664 | ushort sdtr_speed = 0; | ||
16665 | |||
16666 | iop_base = asc_dvc->iop_base; | ||
16667 | |||
16668 | warn_code = 0; | ||
16669 | |||
16670 | /* | ||
16671 | * Read the board's EEPROM configuration. | ||
16672 | * | ||
16673 | * Set default values if a bad checksum is found. | ||
16674 | */ | ||
16675 | if (AdvGet38C0800EEPConfig(iop_base, &eep_config) != eep_config.check_sum) | ||
16676 | { | ||
16677 | warn_code |= ASC_WARN_EEPROM_CHKSUM; | ||
16678 | |||
16679 | /* | ||
16680 | * Set EEPROM default values. | ||
16681 | */ | ||
16682 | for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++) | ||
16683 | { | ||
16684 | *((uchar *) &eep_config + i) = | ||
16685 | *((uchar *) &Default_38C0800_EEPROM_Config + i); | ||
16686 | } | ||
16687 | |||
16688 | /* | ||
16689 | * Assume the 6 byte board serial number that was read | ||
16690 | * from EEPROM is correct even if the EEPROM checksum | ||
16691 | * failed. | ||
16692 | */ | ||
16693 | eep_config.serial_number_word3 = | ||
16694 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); | ||
16695 | |||
16696 | eep_config.serial_number_word2 = | ||
16697 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2); | ||
16698 | |||
16699 | eep_config.serial_number_word1 = | ||
16700 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3); | ||
16701 | |||
16702 | AdvSet38C0800EEPConfig(iop_base, &eep_config); | ||
16703 | } | ||
16704 | /* | ||
16705 | * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the | ||
16706 | * EEPROM configuration that was read. | ||
16707 | * | ||
16708 | * This is the mapping of EEPROM fields to Adv Library fields. | ||
16709 | */ | ||
16710 | asc_dvc->wdtr_able = eep_config.wdtr_able; | ||
16711 | asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1; | ||
16712 | asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2; | ||
16713 | asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3; | ||
16714 | asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4; | ||
16715 | asc_dvc->tagqng_able = eep_config.tagqng_able; | ||
16716 | asc_dvc->cfg->disc_enable = eep_config.disc_enable; | ||
16717 | asc_dvc->max_host_qng = eep_config.max_host_qng; | ||
16718 | asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; | ||
16719 | asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID); | ||
16720 | asc_dvc->start_motor = eep_config.start_motor; | ||
16721 | asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay; | ||
16722 | asc_dvc->bios_ctrl = eep_config.bios_ctrl; | ||
16723 | asc_dvc->no_scam = eep_config.scam_tolerant; | ||
16724 | asc_dvc->cfg->serial1 = eep_config.serial_number_word1; | ||
16725 | asc_dvc->cfg->serial2 = eep_config.serial_number_word2; | ||
16726 | asc_dvc->cfg->serial3 = eep_config.serial_number_word3; | ||
16727 | |||
16728 | /* | ||
16729 | * For every Target ID if any of its 'sdtr_speed[1234]' bits | ||
16730 | * are set, then set an 'sdtr_able' bit for it. | ||
16731 | */ | ||
16732 | asc_dvc->sdtr_able = 0; | ||
16733 | for (tid = 0; tid <= ADV_MAX_TID; tid++) | ||
16734 | { | ||
16735 | if (tid == 0) | ||
16736 | { | ||
16737 | sdtr_speed = asc_dvc->sdtr_speed1; | ||
16738 | } else if (tid == 4) | ||
16739 | { | ||
16740 | sdtr_speed = asc_dvc->sdtr_speed2; | ||
16741 | } else if (tid == 8) | ||
16742 | { | ||
16743 | sdtr_speed = asc_dvc->sdtr_speed3; | ||
16744 | } else if (tid == 12) | ||
16745 | { | ||
16746 | sdtr_speed = asc_dvc->sdtr_speed4; | ||
16747 | } | ||
16748 | if (sdtr_speed & ADV_MAX_TID) | ||
16749 | { | ||
16750 | asc_dvc->sdtr_able |= (1 << tid); | ||
16751 | } | ||
16752 | sdtr_speed >>= 4; | ||
16753 | } | ||
16754 | |||
16755 | /* | ||
16756 | * Set the host maximum queuing (max. 253, min. 16) and the per device | ||
16757 | * maximum queuing (max. 63, min. 4). | ||
16758 | */ | ||
16759 | if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) | ||
16760 | { | ||
16761 | eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; | ||
16762 | } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) | ||
16763 | { | ||
16764 | /* If the value is zero, assume it is uninitialized. */ | ||
16765 | if (eep_config.max_host_qng == 0) | ||
16766 | { | ||
16767 | eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; | ||
16768 | } else | ||
16769 | { | ||
16770 | eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG; | ||
16771 | } | ||
16772 | } | ||
16773 | |||
16774 | if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) | ||
16775 | { | ||
16776 | eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; | ||
16777 | } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) | ||
16778 | { | ||
16779 | /* If the value is zero, assume it is uninitialized. */ | ||
16780 | if (eep_config.max_dvc_qng == 0) | ||
16781 | { | ||
16782 | eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; | ||
16783 | } else | ||
16784 | { | ||
16785 | eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG; | ||
16786 | } | ||
16787 | } | ||
16788 | |||
16789 | /* | ||
16790 | * If 'max_dvc_qng' is greater than 'max_host_qng', then | ||
16791 | * set 'max_dvc_qng' to 'max_host_qng'. | ||
16792 | */ | ||
16793 | if (eep_config.max_dvc_qng > eep_config.max_host_qng) | ||
16794 | { | ||
16795 | eep_config.max_dvc_qng = eep_config.max_host_qng; | ||
16796 | } | ||
16797 | |||
16798 | /* | ||
16799 | * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng' | ||
16800 | * values based on possibly adjusted EEPROM values. | ||
16801 | */ | ||
16802 | asc_dvc->max_host_qng = eep_config.max_host_qng; | ||
16803 | asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; | ||
16804 | |||
16805 | /* | ||
16806 | * If the EEPROM 'termination' field is set to automatic (0), then set | ||
16807 | * the ADV_DVC_CFG 'termination' field to automatic also. | ||
16808 | * | ||
16809 | * If the termination is specified with a non-zero 'termination' | ||
16810 | * value check that a legal value is set and set the ADV_DVC_CFG | ||
16811 | * 'termination' field appropriately. | ||
16812 | */ | ||
16813 | if (eep_config.termination_se == 0) | ||
16814 | { | ||
16815 | termination = 0; /* auto termination for SE */ | ||
16816 | } else | ||
16817 | { | ||
16818 | /* Enable manual control with low off / high off. */ | ||
16819 | if (eep_config.termination_se == 1) | ||
16820 | { | ||
16821 | termination = 0; | ||
16822 | |||
16823 | /* Enable manual control with low off / high on. */ | ||
16824 | } else if (eep_config.termination_se == 2) | ||
16825 | { | ||
16826 | termination = TERM_SE_HI; | ||
16827 | |||
16828 | /* Enable manual control with low on / high on. */ | ||
16829 | } else if (eep_config.termination_se == 3) | ||
16830 | { | ||
16831 | termination = TERM_SE; | ||
16832 | } else | ||
16833 | { | ||
16834 | /* | ||
16835 | * The EEPROM 'termination_se' field contains a bad value. | ||
16836 | * Use automatic termination instead. | ||
16837 | */ | ||
16838 | termination = 0; | ||
16839 | warn_code |= ASC_WARN_EEPROM_TERMINATION; | ||
16840 | } | ||
16841 | } | ||
16842 | |||
16843 | if (eep_config.termination_lvd == 0) | ||
16844 | { | ||
16845 | asc_dvc->cfg->termination = termination; /* auto termination for LVD */ | ||
16846 | } else | ||
16847 | { | ||
16848 | /* Enable manual control with low off / high off. */ | ||
16849 | if (eep_config.termination_lvd == 1) | ||
16850 | { | ||
16851 | asc_dvc->cfg->termination = termination; | ||
16852 | |||
16853 | /* Enable manual control with low off / high on. */ | ||
16854 | } else if (eep_config.termination_lvd == 2) | ||
16855 | { | ||
16856 | asc_dvc->cfg->termination = termination | TERM_LVD_HI; | ||
16857 | |||
16858 | /* Enable manual control with low on / high on. */ | ||
16859 | } else if (eep_config.termination_lvd == 3) | ||
16860 | { | ||
16861 | asc_dvc->cfg->termination = | ||
16862 | termination | TERM_LVD; | ||
16863 | } else | ||
16864 | { | ||
16865 | /* | ||
16866 | * The EEPROM 'termination_lvd' field contains a bad value. | ||
16867 | * Use automatic termination instead. | ||
16868 | */ | ||
16869 | asc_dvc->cfg->termination = termination; | ||
16870 | warn_code |= ASC_WARN_EEPROM_TERMINATION; | ||
16871 | } | ||
16872 | } | ||
16873 | |||
16874 | return warn_code; | ||
16875 | } | ||
16876 | |||
16877 | /* | ||
16878 | * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and | ||
16879 | * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while | ||
16880 | * all of this is done. | ||
16881 | * | ||
16882 | * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR. | ||
16883 | * | ||
16884 | * For a non-fatal error return a warning code. If there are no warnings | ||
16885 | * then 0 is returned. | ||
16886 | * | ||
16887 | * Note: Chip is stopped on entry. | ||
16888 | */ | ||
16889 | STATIC int __init | ||
16890 | AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) | ||
16891 | { | ||
16892 | AdvPortAddr iop_base; | ||
16893 | ushort warn_code; | ||
16894 | ADVEEP_38C1600_CONFIG eep_config; | ||
16895 | int i; | ||
16896 | uchar tid, termination; | ||
16897 | ushort sdtr_speed = 0; | ||
16898 | |||
16899 | iop_base = asc_dvc->iop_base; | ||
16900 | |||
16901 | warn_code = 0; | ||
16902 | |||
16903 | /* | ||
16904 | * Read the board's EEPROM configuration. | ||
16905 | * | ||
16906 | * Set default values if a bad checksum is found. | ||
16907 | */ | ||
16908 | if (AdvGet38C1600EEPConfig(iop_base, &eep_config) != eep_config.check_sum) | ||
16909 | { | ||
16910 | warn_code |= ASC_WARN_EEPROM_CHKSUM; | ||
16911 | |||
16912 | /* | ||
16913 | * Set EEPROM default values. | ||
16914 | */ | ||
16915 | for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++) | ||
16916 | { | ||
16917 | if (i == 1 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) != 0) | ||
16918 | { | ||
16919 | /* | ||
16920 | * Set Function 1 EEPROM Word 0 MSB | ||
16921 | * | ||
16922 | * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11) | ||
16923 | * EEPROM bits. | ||
16924 | * | ||
16925 | * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and | ||
16926 | * old Mac system booting problem. The Expansion ROM must | ||
16927 | * be disabled in Function 1 for these systems. | ||
16928 | * | ||
16929 | */ | ||
16930 | *((uchar *) &eep_config + i) = | ||
16931 | ((*((uchar *) &Default_38C1600_EEPROM_Config + i)) & | ||
16932 | (~(((ADV_EEPROM_BIOS_ENABLE | ADV_EEPROM_INTAB) >> 8) & | ||
16933 | 0xFF))); | ||
16934 | |||
16935 | /* | ||
16936 | * Set the INTAB (bit 11) if the GPIO 0 input indicates | ||
16937 | * the Function 1 interrupt line is wired to INTA. | ||
16938 | * | ||
16939 | * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input: | ||
16940 | * 1 - Function 1 interrupt line wired to INT A. | ||
16941 | * 0 - Function 1 interrupt line wired to INT B. | ||
16942 | * | ||
16943 | * Note: Adapter boards always have Function 0 wired to INTA. | ||
16944 | * Put all 5 GPIO bits in input mode and then read | ||
16945 | * their input values. | ||
16946 | */ | ||
16947 | AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0); | ||
16948 | if (AdvReadByteRegister(iop_base, IOPB_GPIO_DATA) & 0x01) | ||
16949 | { | ||
16950 | /* Function 1 interrupt wired to INTA; Set EEPROM bit. */ | ||
16951 | *((uchar *) &eep_config + i) |= | ||
16952 | ((ADV_EEPROM_INTAB >> 8) & 0xFF); | ||
16953 | } | ||
16954 | } | ||
16955 | else | ||
16956 | { | ||
16957 | *((uchar *) &eep_config + i) = | ||
16958 | *((uchar *) &Default_38C1600_EEPROM_Config + i); | ||
16959 | } | ||
16960 | } | ||
16961 | |||
16962 | /* | ||
16963 | * Assume the 6 byte board serial number that was read | ||
16964 | * from EEPROM is correct even if the EEPROM checksum | ||
16965 | * failed. | ||
16966 | */ | ||
16967 | eep_config.serial_number_word3 = | ||
16968 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); | ||
16969 | |||
16970 | eep_config.serial_number_word2 = | ||
16971 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2); | ||
16972 | |||
16973 | eep_config.serial_number_word1 = | ||
16974 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3); | ||
16975 | |||
16976 | AdvSet38C1600EEPConfig(iop_base, &eep_config); | ||
16977 | } | ||
16978 | |||
16979 | /* | ||
16980 | * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the | ||
16981 | * EEPROM configuration that was read. | ||
16982 | * | ||
16983 | * This is the mapping of EEPROM fields to Adv Library fields. | ||
16984 | */ | ||
16985 | asc_dvc->wdtr_able = eep_config.wdtr_able; | ||
16986 | asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1; | ||
16987 | asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2; | ||
16988 | asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3; | ||
16989 | asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4; | ||
16990 | asc_dvc->ppr_able = 0; | ||
16991 | asc_dvc->tagqng_able = eep_config.tagqng_able; | ||
16992 | asc_dvc->cfg->disc_enable = eep_config.disc_enable; | ||
16993 | asc_dvc->max_host_qng = eep_config.max_host_qng; | ||
16994 | asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; | ||
16995 | asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID); | ||
16996 | asc_dvc->start_motor = eep_config.start_motor; | ||
16997 | asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay; | ||
16998 | asc_dvc->bios_ctrl = eep_config.bios_ctrl; | ||
16999 | asc_dvc->no_scam = eep_config.scam_tolerant; | ||
17000 | |||
17001 | /* | ||
17002 | * For every Target ID if any of its 'sdtr_speed[1234]' bits | ||
17003 | * are set, then set an 'sdtr_able' bit for it. | ||
17004 | */ | ||
17005 | asc_dvc->sdtr_able = 0; | ||
17006 | for (tid = 0; tid <= ASC_MAX_TID; tid++) | ||
17007 | { | ||
17008 | if (tid == 0) | ||
17009 | { | ||
17010 | sdtr_speed = asc_dvc->sdtr_speed1; | ||
17011 | } else if (tid == 4) | ||
17012 | { | ||
17013 | sdtr_speed = asc_dvc->sdtr_speed2; | ||
17014 | } else if (tid == 8) | ||
17015 | { | ||
17016 | sdtr_speed = asc_dvc->sdtr_speed3; | ||
17017 | } else if (tid == 12) | ||
17018 | { | ||
17019 | sdtr_speed = asc_dvc->sdtr_speed4; | ||
17020 | } | ||
17021 | if (sdtr_speed & ASC_MAX_TID) | ||
17022 | { | ||
17023 | asc_dvc->sdtr_able |= (1 << tid); | ||
17024 | } | ||
17025 | sdtr_speed >>= 4; | ||
17026 | } | ||
17027 | |||
17028 | /* | ||
17029 | * Set the host maximum queuing (max. 253, min. 16) and the per device | ||
17030 | * maximum queuing (max. 63, min. 4). | ||
17031 | */ | ||
17032 | if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) | ||
17033 | { | ||
17034 | eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; | ||
17035 | } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) | ||
17036 | { | ||
17037 | /* If the value is zero, assume it is uninitialized. */ | ||
17038 | if (eep_config.max_host_qng == 0) | ||
17039 | { | ||
17040 | eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; | ||
17041 | } else | ||
17042 | { | ||
17043 | eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG; | ||
17044 | } | ||
17045 | } | ||
17046 | |||
17047 | if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) | ||
17048 | { | ||
17049 | eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; | ||
17050 | } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) | ||
17051 | { | ||
17052 | /* If the value is zero, assume it is uninitialized. */ | ||
17053 | if (eep_config.max_dvc_qng == 0) | ||
17054 | { | ||
17055 | eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; | ||
17056 | } else | ||
17057 | { | ||
17058 | eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG; | ||
17059 | } | ||
17060 | } | ||
17061 | |||
17062 | /* | ||
17063 | * If 'max_dvc_qng' is greater than 'max_host_qng', then | ||
17064 | * set 'max_dvc_qng' to 'max_host_qng'. | ||
17065 | */ | ||
17066 | if (eep_config.max_dvc_qng > eep_config.max_host_qng) | ||
17067 | { | ||
17068 | eep_config.max_dvc_qng = eep_config.max_host_qng; | ||
17069 | } | ||
17070 | |||
17071 | /* | ||
17072 | * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng' | ||
17073 | * values based on possibly adjusted EEPROM values. | ||
17074 | */ | ||
17075 | asc_dvc->max_host_qng = eep_config.max_host_qng; | ||
17076 | asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; | ||
17077 | |||
17078 | /* | ||
17079 | * If the EEPROM 'termination' field is set to automatic (0), then set | ||
17080 | * the ASC_DVC_CFG 'termination' field to automatic also. | ||
17081 | * | ||
17082 | * If the termination is specified with a non-zero 'termination' | ||
17083 | * value check that a legal value is set and set the ASC_DVC_CFG | ||
17084 | * 'termination' field appropriately. | ||
17085 | */ | ||
17086 | if (eep_config.termination_se == 0) | ||
17087 | { | ||
17088 | termination = 0; /* auto termination for SE */ | ||
17089 | } else | ||
17090 | { | ||
17091 | /* Enable manual control with low off / high off. */ | ||
17092 | if (eep_config.termination_se == 1) | ||
17093 | { | ||
17094 | termination = 0; | ||
17095 | |||
17096 | /* Enable manual control with low off / high on. */ | ||
17097 | } else if (eep_config.termination_se == 2) | ||
17098 | { | ||
17099 | termination = TERM_SE_HI; | ||
17100 | |||
17101 | /* Enable manual control with low on / high on. */ | ||
17102 | } else if (eep_config.termination_se == 3) | ||
17103 | { | ||
17104 | termination = TERM_SE; | ||
17105 | } else | ||
17106 | { | ||
17107 | /* | ||
17108 | * The EEPROM 'termination_se' field contains a bad value. | ||
17109 | * Use automatic termination instead. | ||
17110 | */ | ||
17111 | termination = 0; | ||
17112 | warn_code |= ASC_WARN_EEPROM_TERMINATION; | ||
17113 | } | ||
17114 | } | ||
17115 | |||
17116 | if (eep_config.termination_lvd == 0) | ||
17117 | { | ||
17118 | asc_dvc->cfg->termination = termination; /* auto termination for LVD */ | ||
17119 | } else | ||
17120 | { | ||
17121 | /* Enable manual control with low off / high off. */ | ||
17122 | if (eep_config.termination_lvd == 1) | ||
17123 | { | ||
17124 | asc_dvc->cfg->termination = termination; | ||
17125 | |||
17126 | /* Enable manual control with low off / high on. */ | ||
17127 | } else if (eep_config.termination_lvd == 2) | ||
17128 | { | ||
17129 | asc_dvc->cfg->termination = termination | TERM_LVD_HI; | ||
17130 | |||
17131 | /* Enable manual control with low on / high on. */ | ||
17132 | } else if (eep_config.termination_lvd == 3) | ||
17133 | { | ||
17134 | asc_dvc->cfg->termination = | ||
17135 | termination | TERM_LVD; | ||
17136 | } else | ||
17137 | { | ||
17138 | /* | ||
17139 | * The EEPROM 'termination_lvd' field contains a bad value. | ||
17140 | * Use automatic termination instead. | ||
17141 | */ | ||
17142 | asc_dvc->cfg->termination = termination; | ||
17143 | warn_code |= ASC_WARN_EEPROM_TERMINATION; | ||
17144 | } | ||
17145 | } | ||
17146 | |||
17147 | return warn_code; | ||
17148 | } | ||
17149 | |||
17150 | /* | ||
17151 | * Read EEPROM configuration into the specified buffer. | ||
17152 | * | ||
17153 | * Return a checksum based on the EEPROM configuration read. | ||
17154 | */ | ||
17155 | STATIC ushort __init | ||
17156 | AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) | ||
17157 | { | ||
17158 | ushort wval, chksum; | ||
17159 | ushort *wbuf; | ||
17160 | int eep_addr; | ||
17161 | ushort *charfields; | ||
17162 | |||
17163 | charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar; | ||
17164 | wbuf = (ushort *) cfg_buf; | ||
17165 | chksum = 0; | ||
17166 | |||
17167 | for (eep_addr = ADV_EEP_DVC_CFG_BEGIN; | ||
17168 | eep_addr < ADV_EEP_DVC_CFG_END; | ||
17169 | eep_addr++, wbuf++) | ||
17170 | { | ||
17171 | wval = AdvReadEEPWord(iop_base, eep_addr); | ||
17172 | chksum += wval; /* Checksum is calculated from word values. */ | ||
17173 | if (*charfields++) { | ||
17174 | *wbuf = le16_to_cpu(wval); | ||
17175 | } else { | ||
17176 | *wbuf = wval; | ||
17177 | } | ||
17178 | } | ||
17179 | /* Read checksum word. */ | ||
17180 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); | ||
17181 | wbuf++; charfields++; | ||
17182 | |||
17183 | /* Read rest of EEPROM not covered by the checksum. */ | ||
17184 | for (eep_addr = ADV_EEP_DVC_CTL_BEGIN; | ||
17185 | eep_addr < ADV_EEP_MAX_WORD_ADDR; | ||
17186 | eep_addr++, wbuf++) | ||
17187 | { | ||
17188 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); | ||
17189 | if (*charfields++) { | ||
17190 | *wbuf = le16_to_cpu(*wbuf); | ||
17191 | } | ||
17192 | } | ||
17193 | return chksum; | ||
17194 | } | ||
17195 | |||
17196 | /* | ||
17197 | * Read EEPROM configuration into the specified buffer. | ||
17198 | * | ||
17199 | * Return a checksum based on the EEPROM configuration read. | ||
17200 | */ | ||
17201 | STATIC ushort __init | ||
17202 | AdvGet38C0800EEPConfig(AdvPortAddr iop_base, | ||
17203 | ADVEEP_38C0800_CONFIG *cfg_buf) | ||
17204 | { | ||
17205 | ushort wval, chksum; | ||
17206 | ushort *wbuf; | ||
17207 | int eep_addr; | ||
17208 | ushort *charfields; | ||
17209 | |||
17210 | charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar; | ||
17211 | wbuf = (ushort *) cfg_buf; | ||
17212 | chksum = 0; | ||
17213 | |||
17214 | for (eep_addr = ADV_EEP_DVC_CFG_BEGIN; | ||
17215 | eep_addr < ADV_EEP_DVC_CFG_END; | ||
17216 | eep_addr++, wbuf++) | ||
17217 | { | ||
17218 | wval = AdvReadEEPWord(iop_base, eep_addr); | ||
17219 | chksum += wval; /* Checksum is calculated from word values. */ | ||
17220 | if (*charfields++) { | ||
17221 | *wbuf = le16_to_cpu(wval); | ||
17222 | } else { | ||
17223 | *wbuf = wval; | ||
17224 | } | ||
17225 | } | ||
17226 | /* Read checksum word. */ | ||
17227 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); | ||
17228 | wbuf++; charfields++; | ||
17229 | |||
17230 | /* Read rest of EEPROM not covered by the checksum. */ | ||
17231 | for (eep_addr = ADV_EEP_DVC_CTL_BEGIN; | ||
17232 | eep_addr < ADV_EEP_MAX_WORD_ADDR; | ||
17233 | eep_addr++, wbuf++) | ||
17234 | { | ||
17235 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); | ||
17236 | if (*charfields++) { | ||
17237 | *wbuf = le16_to_cpu(*wbuf); | ||
17238 | } | ||
17239 | } | ||
17240 | return chksum; | ||
17241 | } | ||
17242 | |||
17243 | /* | ||
17244 | * Read EEPROM configuration into the specified buffer. | ||
17245 | * | ||
17246 | * Return a checksum based on the EEPROM configuration read. | ||
17247 | */ | ||
17248 | STATIC ushort __init | ||
17249 | AdvGet38C1600EEPConfig(AdvPortAddr iop_base, | ||
17250 | ADVEEP_38C1600_CONFIG *cfg_buf) | ||
17251 | { | ||
17252 | ushort wval, chksum; | ||
17253 | ushort *wbuf; | ||
17254 | int eep_addr; | ||
17255 | ushort *charfields; | ||
17256 | |||
17257 | charfields = (ushort*) &ADVEEP_38C1600_Config_Field_IsChar; | ||
17258 | wbuf = (ushort *) cfg_buf; | ||
17259 | chksum = 0; | ||
17260 | |||
17261 | for (eep_addr = ADV_EEP_DVC_CFG_BEGIN; | ||
17262 | eep_addr < ADV_EEP_DVC_CFG_END; | ||
17263 | eep_addr++, wbuf++) | ||
17264 | { | ||
17265 | wval = AdvReadEEPWord(iop_base, eep_addr); | ||
17266 | chksum += wval; /* Checksum is calculated from word values. */ | ||
17267 | if (*charfields++) { | ||
17268 | *wbuf = le16_to_cpu(wval); | ||
17269 | } else { | ||
17270 | *wbuf = wval; | ||
17271 | } | ||
17272 | } | ||
17273 | /* Read checksum word. */ | ||
17274 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); | ||
17275 | wbuf++; charfields++; | ||
17276 | |||
17277 | /* Read rest of EEPROM not covered by the checksum. */ | ||
17278 | for (eep_addr = ADV_EEP_DVC_CTL_BEGIN; | ||
17279 | eep_addr < ADV_EEP_MAX_WORD_ADDR; | ||
17280 | eep_addr++, wbuf++) | ||
17281 | { | ||
17282 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); | ||
17283 | if (*charfields++) { | ||
17284 | *wbuf = le16_to_cpu(*wbuf); | ||
17285 | } | ||
17286 | } | ||
17287 | return chksum; | ||
17288 | } | ||
17289 | |||
17290 | /* | ||
17291 | * Read the EEPROM from specified location | ||
17292 | */ | ||
17293 | STATIC ushort __init | ||
17294 | AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr) | ||
17295 | { | ||
17296 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, | ||
17297 | ASC_EEP_CMD_READ | eep_word_addr); | ||
17298 | AdvWaitEEPCmd(iop_base); | ||
17299 | return AdvReadWordRegister(iop_base, IOPW_EE_DATA); | ||
17300 | } | ||
17301 | |||
17302 | /* | ||
17303 | * Wait for EEPROM command to complete | ||
17304 | */ | ||
17305 | STATIC void __init | ||
17306 | AdvWaitEEPCmd(AdvPortAddr iop_base) | ||
17307 | { | ||
17308 | int eep_delay_ms; | ||
17309 | |||
17310 | for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) | ||
17311 | { | ||
17312 | if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) | ||
17313 | { | ||
17314 | break; | ||
17315 | } | ||
17316 | DvcSleepMilliSecond(1); | ||
17317 | } | ||
17318 | if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == 0) | ||
17319 | { | ||
17320 | ASC_ASSERT(0); | ||
17321 | } | ||
17322 | return; | ||
17323 | } | ||
17324 | |||
17325 | /* | ||
17326 | * Write the EEPROM from 'cfg_buf'. | ||
17327 | */ | ||
17328 | void | ||
17329 | AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) | ||
17330 | { | ||
17331 | ushort *wbuf; | ||
17332 | ushort addr, chksum; | ||
17333 | ushort *charfields; | ||
17334 | |||
17335 | wbuf = (ushort *) cfg_buf; | ||
17336 | charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar; | ||
17337 | chksum = 0; | ||
17338 | |||
17339 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); | ||
17340 | AdvWaitEEPCmd(iop_base); | ||
17341 | |||
17342 | /* | ||
17343 | * Write EEPROM from word 0 to word 20. | ||
17344 | */ | ||
17345 | for (addr = ADV_EEP_DVC_CFG_BEGIN; | ||
17346 | addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) | ||
17347 | { | ||
17348 | ushort word; | ||
17349 | |||
17350 | if (*charfields++) { | ||
17351 | word = cpu_to_le16(*wbuf); | ||
17352 | } else { | ||
17353 | word = *wbuf; | ||
17354 | } | ||
17355 | chksum += *wbuf; /* Checksum is calculated from word values. */ | ||
17356 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); | ||
17357 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); | ||
17358 | AdvWaitEEPCmd(iop_base); | ||
17359 | DvcSleepMilliSecond(ADV_EEP_DELAY_MS); | ||
17360 | } | ||
17361 | |||
17362 | /* | ||
17363 | * Write EEPROM checksum at word 21. | ||
17364 | */ | ||
17365 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum); | ||
17366 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); | ||
17367 | AdvWaitEEPCmd(iop_base); | ||
17368 | wbuf++; charfields++; | ||
17369 | |||
17370 | /* | ||
17371 | * Write EEPROM OEM name at words 22 to 29. | ||
17372 | */ | ||
17373 | for (addr = ADV_EEP_DVC_CTL_BEGIN; | ||
17374 | addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) | ||
17375 | { | ||
17376 | ushort word; | ||
17377 | |||
17378 | if (*charfields++) { | ||
17379 | word = cpu_to_le16(*wbuf); | ||
17380 | } else { | ||
17381 | word = *wbuf; | ||
17382 | } | ||
17383 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); | ||
17384 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); | ||
17385 | AdvWaitEEPCmd(iop_base); | ||
17386 | } | ||
17387 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE); | ||
17388 | AdvWaitEEPCmd(iop_base); | ||
17389 | return; | ||
17390 | } | ||
17391 | |||
17392 | /* | ||
17393 | * Write the EEPROM from 'cfg_buf'. | ||
17394 | */ | ||
17395 | void | ||
17396 | AdvSet38C0800EEPConfig(AdvPortAddr iop_base, | ||
17397 | ADVEEP_38C0800_CONFIG *cfg_buf) | ||
17398 | { | ||
17399 | ushort *wbuf; | ||
17400 | ushort *charfields; | ||
17401 | ushort addr, chksum; | ||
17402 | |||
17403 | wbuf = (ushort *) cfg_buf; | ||
17404 | charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar; | ||
17405 | chksum = 0; | ||
17406 | |||
17407 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); | ||
17408 | AdvWaitEEPCmd(iop_base); | ||
17409 | |||
17410 | /* | ||
17411 | * Write EEPROM from word 0 to word 20. | ||
17412 | */ | ||
17413 | for (addr = ADV_EEP_DVC_CFG_BEGIN; | ||
17414 | addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) | ||
17415 | { | ||
17416 | ushort word; | ||
17417 | |||
17418 | if (*charfields++) { | ||
17419 | word = cpu_to_le16(*wbuf); | ||
17420 | } else { | ||
17421 | word = *wbuf; | ||
17422 | } | ||
17423 | chksum += *wbuf; /* Checksum is calculated from word values. */ | ||
17424 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); | ||
17425 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); | ||
17426 | AdvWaitEEPCmd(iop_base); | ||
17427 | DvcSleepMilliSecond(ADV_EEP_DELAY_MS); | ||
17428 | } | ||
17429 | |||
17430 | /* | ||
17431 | * Write EEPROM checksum at word 21. | ||
17432 | */ | ||
17433 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum); | ||
17434 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); | ||
17435 | AdvWaitEEPCmd(iop_base); | ||
17436 | wbuf++; charfields++; | ||
17437 | |||
17438 | /* | ||
17439 | * Write EEPROM OEM name at words 22 to 29. | ||
17440 | */ | ||
17441 | for (addr = ADV_EEP_DVC_CTL_BEGIN; | ||
17442 | addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) | ||
17443 | { | ||
17444 | ushort word; | ||
17445 | |||
17446 | if (*charfields++) { | ||
17447 | word = cpu_to_le16(*wbuf); | ||
17448 | } else { | ||
17449 | word = *wbuf; | ||
17450 | } | ||
17451 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); | ||
17452 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); | ||
17453 | AdvWaitEEPCmd(iop_base); | ||
17454 | } | ||
17455 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE); | ||
17456 | AdvWaitEEPCmd(iop_base); | ||
17457 | return; | ||
17458 | } | ||
17459 | |||
17460 | /* | ||
17461 | * Write the EEPROM from 'cfg_buf'. | ||
17462 | */ | ||
17463 | void | ||
17464 | AdvSet38C1600EEPConfig(AdvPortAddr iop_base, | ||
17465 | ADVEEP_38C1600_CONFIG *cfg_buf) | ||
17466 | { | ||
17467 | ushort *wbuf; | ||
17468 | ushort *charfields; | ||
17469 | ushort addr, chksum; | ||
17470 | |||
17471 | wbuf = (ushort *) cfg_buf; | ||
17472 | charfields = (ushort *) &ADVEEP_38C1600_Config_Field_IsChar; | ||
17473 | chksum = 0; | ||
17474 | |||
17475 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); | ||
17476 | AdvWaitEEPCmd(iop_base); | ||
17477 | |||
17478 | /* | ||
17479 | * Write EEPROM from word 0 to word 20. | ||
17480 | */ | ||
17481 | for (addr = ADV_EEP_DVC_CFG_BEGIN; | ||
17482 | addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) | ||
17483 | { | ||
17484 | ushort word; | ||
17485 | |||
17486 | if (*charfields++) { | ||
17487 | word = cpu_to_le16(*wbuf); | ||
17488 | } else { | ||
17489 | word = *wbuf; | ||
17490 | } | ||
17491 | chksum += *wbuf; /* Checksum is calculated from word values. */ | ||
17492 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); | ||
17493 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); | ||
17494 | AdvWaitEEPCmd(iop_base); | ||
17495 | DvcSleepMilliSecond(ADV_EEP_DELAY_MS); | ||
17496 | } | ||
17497 | |||
17498 | /* | ||
17499 | * Write EEPROM checksum at word 21. | ||
17500 | */ | ||
17501 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum); | ||
17502 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); | ||
17503 | AdvWaitEEPCmd(iop_base); | ||
17504 | wbuf++; charfields++; | ||
17505 | |||
17506 | /* | ||
17507 | * Write EEPROM OEM name at words 22 to 29. | ||
17508 | */ | ||
17509 | for (addr = ADV_EEP_DVC_CTL_BEGIN; | ||
17510 | addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) | ||
17511 | { | ||
17512 | ushort word; | ||
17513 | |||
17514 | if (*charfields++) { | ||
17515 | word = cpu_to_le16(*wbuf); | ||
17516 | } else { | ||
17517 | word = *wbuf; | ||
17518 | } | ||
17519 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); | ||
17520 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); | ||
17521 | AdvWaitEEPCmd(iop_base); | ||
17522 | } | ||
17523 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE); | ||
17524 | AdvWaitEEPCmd(iop_base); | ||
17525 | return; | ||
17526 | } | ||
17527 | |||
17528 | /* a_advlib.c */ | ||
17529 | /* | ||
17530 | * AdvExeScsiQueue() - Send a request to the RISC microcode program. | ||
17531 | * | ||
17532 | * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q, | ||
17533 | * add the carrier to the ICQ (Initiator Command Queue), and tickle the | ||
17534 | * RISC to notify it a new command is ready to be executed. | ||
17535 | * | ||
17536 | * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be | ||
17537 | * set to SCSI_MAX_RETRY. | ||
17538 | * | ||
17539 | * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode | ||
17540 | * for DMA addresses or math operations are byte swapped to little-endian | ||
17541 | * order. | ||
17542 | * | ||
17543 | * Return: | ||
17544 | * ADV_SUCCESS(1) - The request was successfully queued. | ||
17545 | * ADV_BUSY(0) - Resource unavailable; Retry again after pending | ||
17546 | * request completes. | ||
17547 | * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure | ||
17548 | * host IC error. | ||
17549 | */ | ||
17550 | STATIC int | ||
17551 | AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, | ||
17552 | ADV_SCSI_REQ_Q *scsiq) | ||
17553 | { | ||
17554 | ulong last_int_level; | ||
17555 | AdvPortAddr iop_base; | ||
17556 | ADV_DCNT req_size; | ||
17557 | ADV_PADDR req_paddr; | ||
17558 | ADV_CARR_T *new_carrp; | ||
17559 | |||
17560 | ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */ | ||
17561 | |||
17562 | /* | ||
17563 | * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID. | ||
17564 | */ | ||
17565 | if (scsiq->target_id > ADV_MAX_TID) | ||
17566 | { | ||
17567 | scsiq->host_status = QHSTA_M_INVALID_DEVICE; | ||
17568 | scsiq->done_status = QD_WITH_ERROR; | ||
17569 | return ADV_ERROR; | ||
17570 | } | ||
17571 | |||
17572 | iop_base = asc_dvc->iop_base; | ||
17573 | |||
17574 | last_int_level = DvcEnterCritical(); | ||
17575 | |||
17576 | /* | ||
17577 | * Allocate a carrier ensuring at least one carrier always | ||
17578 | * remains on the freelist and initialize fields. | ||
17579 | */ | ||
17580 | if ((new_carrp = asc_dvc->carr_freelist) == NULL) | ||
17581 | { | ||
17582 | DvcLeaveCritical(last_int_level); | ||
17583 | return ADV_BUSY; | ||
17584 | } | ||
17585 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
17586 | ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa)); | ||
17587 | asc_dvc->carr_pending_cnt++; | ||
17588 | |||
17589 | /* | ||
17590 | * Set the carrier to be a stopper by setting 'next_vpa' | ||
17591 | * to the stopper value. The current stopper will be changed | ||
17592 | * below to point to the new stopper. | ||
17593 | */ | ||
17594 | new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
17595 | |||
17596 | /* | ||
17597 | * Clear the ADV_SCSI_REQ_Q done flag. | ||
17598 | */ | ||
17599 | scsiq->a_flag &= ~ADV_SCSIQ_DONE; | ||
17600 | |||
17601 | req_size = sizeof(ADV_SCSI_REQ_Q); | ||
17602 | req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *) scsiq, | ||
17603 | (ADV_SDCNT *) &req_size, ADV_IS_SCSIQ_FLAG); | ||
17604 | |||
17605 | ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr); | ||
17606 | ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q)); | ||
17607 | |||
17608 | /* Wait for assertion before making little-endian */ | ||
17609 | req_paddr = cpu_to_le32(req_paddr); | ||
17610 | |||
17611 | /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */ | ||
17612 | scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq)); | ||
17613 | scsiq->scsiq_rptr = req_paddr; | ||
17614 | |||
17615 | scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp)); | ||
17616 | /* | ||
17617 | * Every ADV_CARR_T.carr_pa is byte swapped to little-endian | ||
17618 | * order during initialization. | ||
17619 | */ | ||
17620 | scsiq->carr_pa = asc_dvc->icq_sp->carr_pa; | ||
17621 | |||
17622 | /* | ||
17623 | * Use the current stopper to send the ADV_SCSI_REQ_Q command to | ||
17624 | * the microcode. The newly allocated stopper will become the new | ||
17625 | * stopper. | ||
17626 | */ | ||
17627 | asc_dvc->icq_sp->areq_vpa = req_paddr; | ||
17628 | |||
17629 | /* | ||
17630 | * Set the 'next_vpa' pointer for the old stopper to be the | ||
17631 | * physical address of the new stopper. The RISC can only | ||
17632 | * follow physical addresses. | ||
17633 | */ | ||
17634 | asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa; | ||
17635 | |||
17636 | /* | ||
17637 | * Set the host adapter stopper pointer to point to the new carrier. | ||
17638 | */ | ||
17639 | asc_dvc->icq_sp = new_carrp; | ||
17640 | |||
17641 | if (asc_dvc->chip_type == ADV_CHIP_ASC3550 || | ||
17642 | asc_dvc->chip_type == ADV_CHIP_ASC38C0800) | ||
17643 | { | ||
17644 | /* | ||
17645 | * Tickle the RISC to tell it to read its Command Queue Head pointer. | ||
17646 | */ | ||
17647 | AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A); | ||
17648 | if (asc_dvc->chip_type == ADV_CHIP_ASC3550) | ||
17649 | { | ||
17650 | /* | ||
17651 | * Clear the tickle value. In the ASC-3550 the RISC flag | ||
17652 | * command 'clr_tickle_a' does not work unless the host | ||
17653 | * value is cleared. | ||
17654 | */ | ||
17655 | AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP); | ||
17656 | } | ||
17657 | } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) | ||
17658 | { | ||
17659 | /* | ||
17660 | * Notify the RISC a carrier is ready by writing the physical | ||
17661 | * address of the new carrier stopper to the COMMA register. | ||
17662 | */ | ||
17663 | AdvWriteDWordRegister(iop_base, IOPDW_COMMA, | ||
17664 | le32_to_cpu(new_carrp->carr_pa)); | ||
17665 | } | ||
17666 | |||
17667 | DvcLeaveCritical(last_int_level); | ||
17668 | |||
17669 | return ADV_SUCCESS; | ||
17670 | } | ||
17671 | |||
17672 | /* | ||
17673 | * Reset SCSI Bus and purge all outstanding requests. | ||
17674 | * | ||
17675 | * Return Value: | ||
17676 | * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset. | ||
17677 | * ADV_FALSE(0) - Microcode command failed. | ||
17678 | * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC | ||
17679 | * may be hung which requires driver recovery. | ||
17680 | */ | ||
17681 | STATIC int | ||
17682 | AdvResetSB(ADV_DVC_VAR *asc_dvc) | ||
17683 | { | ||
17684 | int status; | ||
17685 | |||
17686 | /* | ||
17687 | * Send the SCSI Bus Reset idle start idle command which asserts | ||
17688 | * the SCSI Bus Reset signal. | ||
17689 | */ | ||
17690 | status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_START, 0L); | ||
17691 | if (status != ADV_TRUE) | ||
17692 | { | ||
17693 | return status; | ||
17694 | } | ||
17695 | |||
17696 | /* | ||
17697 | * Delay for the specified SCSI Bus Reset hold time. | ||
17698 | * | ||
17699 | * The hold time delay is done on the host because the RISC has no | ||
17700 | * microsecond accurate timer. | ||
17701 | */ | ||
17702 | DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US); | ||
17703 | |||
17704 | /* | ||
17705 | * Send the SCSI Bus Reset end idle command which de-asserts | ||
17706 | * the SCSI Bus Reset signal and purges any pending requests. | ||
17707 | */ | ||
17708 | status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_END, 0L); | ||
17709 | if (status != ADV_TRUE) | ||
17710 | { | ||
17711 | return status; | ||
17712 | } | ||
17713 | |||
17714 | DvcSleepMilliSecond((ADV_DCNT) asc_dvc->scsi_reset_wait * 1000); | ||
17715 | |||
17716 | return status; | ||
17717 | } | ||
17718 | |||
17719 | /* | ||
17720 | * Reset chip and SCSI Bus. | ||
17721 | * | ||
17722 | * Return Value: | ||
17723 | * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful. | ||
17724 | * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure. | ||
17725 | */ | ||
17726 | STATIC int | ||
17727 | AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc) | ||
17728 | { | ||
17729 | int status; | ||
17730 | ushort wdtr_able, sdtr_able, tagqng_able; | ||
17731 | ushort ppr_able = 0; | ||
17732 | uchar tid, max_cmd[ADV_MAX_TID + 1]; | ||
17733 | AdvPortAddr iop_base; | ||
17734 | ushort bios_sig; | ||
17735 | |||
17736 | iop_base = asc_dvc->iop_base; | ||
17737 | |||
17738 | /* | ||
17739 | * Save current per TID negotiated values. | ||
17740 | */ | ||
17741 | AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
17742 | AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
17743 | if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) | ||
17744 | { | ||
17745 | AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); | ||
17746 | } | ||
17747 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
17748 | for (tid = 0; tid <= ADV_MAX_TID; tid++) | ||
17749 | { | ||
17750 | AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
17751 | max_cmd[tid]); | ||
17752 | } | ||
17753 | |||
17754 | /* | ||
17755 | * Force the AdvInitAsc3550/38C0800Driver() function to | ||
17756 | * perform a SCSI Bus Reset by clearing the BIOS signature word. | ||
17757 | * The initialization functions assumes a SCSI Bus Reset is not | ||
17758 | * needed if the BIOS signature word is present. | ||
17759 | */ | ||
17760 | AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig); | ||
17761 | AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0); | ||
17762 | |||
17763 | /* | ||
17764 | * Stop chip and reset it. | ||
17765 | */ | ||
17766 | AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP); | ||
17767 | AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET); | ||
17768 | DvcSleepMilliSecond(100); | ||
17769 | AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG); | ||
17770 | |||
17771 | /* | ||
17772 | * Reset Adv Library error code, if any, and try | ||
17773 | * re-initializing the chip. | ||
17774 | */ | ||
17775 | asc_dvc->err_code = 0; | ||
17776 | if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) | ||
17777 | { | ||
17778 | status = AdvInitAsc38C1600Driver(asc_dvc); | ||
17779 | } | ||
17780 | else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) | ||
17781 | { | ||
17782 | status = AdvInitAsc38C0800Driver(asc_dvc); | ||
17783 | } else | ||
17784 | { | ||
17785 | status = AdvInitAsc3550Driver(asc_dvc); | ||
17786 | } | ||
17787 | |||
17788 | /* Translate initialization return value to status value. */ | ||
17789 | if (status == 0) | ||
17790 | { | ||
17791 | status = ADV_TRUE; | ||
17792 | } else | ||
17793 | { | ||
17794 | status = ADV_FALSE; | ||
17795 | } | ||
17796 | |||
17797 | /* | ||
17798 | * Restore the BIOS signature word. | ||
17799 | */ | ||
17800 | AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig); | ||
17801 | |||
17802 | /* | ||
17803 | * Restore per TID negotiated values. | ||
17804 | */ | ||
17805 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
17806 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
17807 | if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) | ||
17808 | { | ||
17809 | AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); | ||
17810 | } | ||
17811 | AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
17812 | for (tid = 0; tid <= ADV_MAX_TID; tid++) | ||
17813 | { | ||
17814 | AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
17815 | max_cmd[tid]); | ||
17816 | } | ||
17817 | |||
17818 | return status; | ||
17819 | } | ||
17820 | |||
17821 | /* | ||
17822 | * Adv Library Interrupt Service Routine | ||
17823 | * | ||
17824 | * This function is called by a driver's interrupt service routine. | ||
17825 | * The function disables and re-enables interrupts. | ||
17826 | * | ||
17827 | * When a microcode idle command is completed, the ADV_DVC_VAR | ||
17828 | * 'idle_cmd_done' field is set to ADV_TRUE. | ||
17829 | * | ||
17830 | * Note: AdvISR() can be called when interrupts are disabled or even | ||
17831 | * when there is no hardware interrupt condition present. It will | ||
17832 | * always check for completed idle commands and microcode requests. | ||
17833 | * This is an important feature that shouldn't be changed because it | ||
17834 | * allows commands to be completed from polling mode loops. | ||
17835 | * | ||
17836 | * Return: | ||
17837 | * ADV_TRUE(1) - interrupt was pending | ||
17838 | * ADV_FALSE(0) - no interrupt was pending | ||
17839 | */ | ||
17840 | STATIC int | ||
17841 | AdvISR(ADV_DVC_VAR *asc_dvc) | ||
17842 | { | ||
17843 | AdvPortAddr iop_base; | ||
17844 | uchar int_stat; | ||
17845 | ushort target_bit; | ||
17846 | ADV_CARR_T *free_carrp; | ||
17847 | ADV_VADDR irq_next_vpa; | ||
17848 | int flags; | ||
17849 | ADV_SCSI_REQ_Q *scsiq; | ||
17850 | |||
17851 | flags = DvcEnterCritical(); | ||
17852 | |||
17853 | iop_base = asc_dvc->iop_base; | ||
17854 | |||
17855 | /* Reading the register clears the interrupt. */ | ||
17856 | int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG); | ||
17857 | |||
17858 | if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB | | ||
17859 | ADV_INTR_STATUS_INTRC)) == 0) | ||
17860 | { | ||
17861 | DvcLeaveCritical(flags); | ||
17862 | return ADV_FALSE; | ||
17863 | } | ||
17864 | |||
17865 | /* | ||
17866 | * Notify the driver of an asynchronous microcode condition by | ||
17867 | * calling the ADV_DVC_VAR.async_callback function. The function | ||
17868 | * is passed the microcode ASC_MC_INTRB_CODE byte value. | ||
17869 | */ | ||
17870 | if (int_stat & ADV_INTR_STATUS_INTRB) | ||
17871 | { | ||
17872 | uchar intrb_code; | ||
17873 | |||
17874 | AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code); | ||
17875 | |||
17876 | if (asc_dvc->chip_type == ADV_CHIP_ASC3550 || | ||
17877 | asc_dvc->chip_type == ADV_CHIP_ASC38C0800) | ||
17878 | { | ||
17879 | if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE && | ||
17880 | asc_dvc->carr_pending_cnt != 0) | ||
17881 | { | ||
17882 | AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A); | ||
17883 | if (asc_dvc->chip_type == ADV_CHIP_ASC3550) | ||
17884 | { | ||
17885 | AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP); | ||
17886 | } | ||
17887 | } | ||
17888 | } | ||
17889 | |||
17890 | if (asc_dvc->async_callback != 0) | ||
17891 | { | ||
17892 | (*asc_dvc->async_callback)(asc_dvc, intrb_code); | ||
17893 | } | ||
17894 | } | ||
17895 | |||
17896 | /* | ||
17897 | * Check if the IRQ stopper carrier contains a completed request. | ||
17898 | */ | ||
17899 | while (((irq_next_vpa = | ||
17900 | le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) | ||
17901 | { | ||
17902 | /* | ||
17903 | * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure. | ||
17904 | * The RISC will have set 'areq_vpa' to a virtual address. | ||
17905 | * | ||
17906 | * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr | ||
17907 | * field to the carrier ADV_CARR_T.areq_vpa field. The conversion | ||
17908 | * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr' | ||
17909 | * in AdvExeScsiQueue(). | ||
17910 | */ | ||
17911 | scsiq = (ADV_SCSI_REQ_Q *) | ||
17912 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa)); | ||
17913 | |||
17914 | /* | ||
17915 | * Request finished with good status and the queue was not | ||
17916 | * DMAed to host memory by the firmware. Set all status fields | ||
17917 | * to indicate good status. | ||
17918 | */ | ||
17919 | if ((irq_next_vpa & ASC_RQ_GOOD) != 0) | ||
17920 | { | ||
17921 | scsiq->done_status = QD_NO_ERROR; | ||
17922 | scsiq->host_status = scsiq->scsi_status = 0; | ||
17923 | scsiq->data_cnt = 0L; | ||
17924 | } | ||
17925 | |||
17926 | /* | ||
17927 | * Advance the stopper pointer to the next carrier | ||
17928 | * ignoring the lower four bits. Free the previous | ||
17929 | * stopper carrier. | ||
17930 | */ | ||
17931 | free_carrp = asc_dvc->irq_sp; | ||
17932 | asc_dvc->irq_sp = (ADV_CARR_T *) | ||
17933 | ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa)); | ||
17934 | |||
17935 | free_carrp->next_vpa = | ||
17936 | cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); | ||
17937 | asc_dvc->carr_freelist = free_carrp; | ||
17938 | asc_dvc->carr_pending_cnt--; | ||
17939 | |||
17940 | ASC_ASSERT(scsiq != NULL); | ||
17941 | target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id); | ||
17942 | |||
17943 | /* | ||
17944 | * Clear request microcode control flag. | ||
17945 | */ | ||
17946 | scsiq->cntl = 0; | ||
17947 | |||
17948 | /* | ||
17949 | * If the command that completed was a SCSI INQUIRY and | ||
17950 | * LUN 0 was sent the command, then process the INQUIRY | ||
17951 | * command information for the device. | ||
17952 | * | ||
17953 | * Note: If data returned were either VPD or CmdDt data, | ||
17954 | * don't process the INQUIRY command information for | ||
17955 | * the device, otherwise may erroneously set *_able bits. | ||
17956 | */ | ||
17957 | if (scsiq->done_status == QD_NO_ERROR && | ||
17958 | scsiq->cdb[0] == INQUIRY && | ||
17959 | scsiq->target_lun == 0 && | ||
17960 | (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT) | ||
17961 | == ADV_INQ_RTN_STD_INQUIRY_DATA) | ||
17962 | { | ||
17963 | AdvInquiryHandling(asc_dvc, scsiq); | ||
17964 | } | ||
17965 | |||
17966 | /* | ||
17967 | * Notify the driver of the completed request by passing | ||
17968 | * the ADV_SCSI_REQ_Q pointer to its callback function. | ||
17969 | */ | ||
17970 | scsiq->a_flag |= ADV_SCSIQ_DONE; | ||
17971 | (*asc_dvc->isr_callback)(asc_dvc, scsiq); | ||
17972 | /* | ||
17973 | * Note: After the driver callback function is called, 'scsiq' | ||
17974 | * can no longer be referenced. | ||
17975 | * | ||
17976 | * Fall through and continue processing other completed | ||
17977 | * requests... | ||
17978 | */ | ||
17979 | |||
17980 | /* | ||
17981 | * Disable interrupts again in case the driver inadvertently | ||
17982 | * enabled interrupts in its callback function. | ||
17983 | * | ||
17984 | * The DvcEnterCritical() return value is ignored, because | ||
17985 | * the 'flags' saved when AdvISR() was first entered will be | ||
17986 | * used to restore the interrupt flag on exit. | ||
17987 | */ | ||
17988 | (void) DvcEnterCritical(); | ||
17989 | } | ||
17990 | DvcLeaveCritical(flags); | ||
17991 | return ADV_TRUE; | ||
17992 | } | ||
17993 | |||
17994 | /* | ||
17995 | * Send an idle command to the chip and wait for completion. | ||
17996 | * | ||
17997 | * Command completion is polled for once per microsecond. | ||
17998 | * | ||
17999 | * The function can be called from anywhere including an interrupt handler. | ||
18000 | * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical() | ||
18001 | * functions to prevent reentrancy. | ||
18002 | * | ||
18003 | * Return Values: | ||
18004 | * ADV_TRUE - command completed successfully | ||
18005 | * ADV_FALSE - command failed | ||
18006 | * ADV_ERROR - command timed out | ||
18007 | */ | ||
18008 | STATIC int | ||
18009 | AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc, | ||
18010 | ushort idle_cmd, | ||
18011 | ADV_DCNT idle_cmd_parameter) | ||
18012 | { | ||
18013 | ulong last_int_level; | ||
18014 | int result; | ||
18015 | ADV_DCNT i, j; | ||
18016 | AdvPortAddr iop_base; | ||
18017 | |||
18018 | last_int_level = DvcEnterCritical(); | ||
18019 | |||
18020 | iop_base = asc_dvc->iop_base; | ||
18021 | |||
18022 | /* | ||
18023 | * Clear the idle command status which is set by the microcode | ||
18024 | * to a non-zero value to indicate when the command is completed. | ||
18025 | * The non-zero result is one of the IDLE_CMD_STATUS_* values | ||
18026 | * defined in a_advlib.h. | ||
18027 | */ | ||
18028 | AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort) 0); | ||
18029 | |||
18030 | /* | ||
18031 | * Write the idle command value after the idle command parameter | ||
18032 | * has been written to avoid a race condition. If the order is not | ||
18033 | * followed, the microcode may process the idle command before the | ||
18034 | * parameters have been written to LRAM. | ||
18035 | */ | ||
18036 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER, | ||
18037 | cpu_to_le32(idle_cmd_parameter)); | ||
18038 | AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd); | ||
18039 | |||
18040 | /* | ||
18041 | * Tickle the RISC to tell it to process the idle command. | ||
18042 | */ | ||
18043 | AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B); | ||
18044 | if (asc_dvc->chip_type == ADV_CHIP_ASC3550) | ||
18045 | { | ||
18046 | /* | ||
18047 | * Clear the tickle value. In the ASC-3550 the RISC flag | ||
18048 | * command 'clr_tickle_b' does not work unless the host | ||
18049 | * value is cleared. | ||
18050 | */ | ||
18051 | AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP); | ||
18052 | } | ||
18053 | |||
18054 | /* Wait for up to 100 millisecond for the idle command to timeout. */ | ||
18055 | for (i = 0; i < SCSI_WAIT_100_MSEC; i++) | ||
18056 | { | ||
18057 | /* Poll once each microsecond for command completion. */ | ||
18058 | for (j = 0; j < SCSI_US_PER_MSEC; j++) | ||
18059 | { | ||
18060 | AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, result); | ||
18061 | if (result != 0) | ||
18062 | { | ||
18063 | DvcLeaveCritical(last_int_level); | ||
18064 | return result; | ||
18065 | } | ||
18066 | DvcDelayMicroSecond(asc_dvc, (ushort) 1); | ||
18067 | } | ||
18068 | } | ||
18069 | |||
18070 | ASC_ASSERT(0); /* The idle command should never timeout. */ | ||
18071 | DvcLeaveCritical(last_int_level); | ||
18072 | return ADV_ERROR; | ||
18073 | } | ||
18074 | |||
18075 | /* | ||
18076 | * Inquiry Information Byte 7 Handling | ||
18077 | * | ||
18078 | * Handle SCSI Inquiry Command information for a device by setting | ||
18079 | * microcode operating variables that affect WDTR, SDTR, and Tag | ||
18080 | * Queuing. | ||
18081 | */ | ||
18082 | STATIC void | ||
18083 | AdvInquiryHandling( | ||
18084 | ADV_DVC_VAR *asc_dvc, | ||
18085 | ADV_SCSI_REQ_Q *scsiq) | ||
18086 | { | ||
18087 | AdvPortAddr iop_base; | ||
18088 | uchar tid; | ||
18089 | ADV_SCSI_INQUIRY *inq; | ||
18090 | ushort tidmask; | ||
18091 | ushort cfg_word; | ||
18092 | |||
18093 | /* | ||
18094 | * AdvInquiryHandling() requires up to INQUIRY information Byte 7 | ||
18095 | * to be available. | ||
18096 | * | ||
18097 | * If less than 8 bytes of INQUIRY information were requested or less | ||
18098 | * than 8 bytes were transferred, then return. cdb[4] is the request | ||
18099 | * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the | ||
18100 | * microcode to the transfer residual count. | ||
18101 | */ | ||
18102 | |||
18103 | if (scsiq->cdb[4] < 8 || | ||
18104 | (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8) | ||
18105 | { | ||
18106 | return; | ||
18107 | } | ||
18108 | |||
18109 | iop_base = asc_dvc->iop_base; | ||
18110 | tid = scsiq->target_id; | ||
18111 | |||
18112 | inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr; | ||
18113 | |||
18114 | /* | ||
18115 | * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices. | ||
18116 | */ | ||
18117 | if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2) | ||
18118 | { | ||
18119 | return; | ||
18120 | } else | ||
18121 | { | ||
18122 | /* | ||
18123 | * INQUIRY Byte 7 Handling | ||
18124 | * | ||
18125 | * Use a device's INQUIRY byte 7 to determine whether it | ||
18126 | * supports WDTR, SDTR, and Tag Queuing. If the feature | ||
18127 | * is enabled in the EEPROM and the device supports the | ||
18128 | * feature, then enable it in the microcode. | ||
18129 | */ | ||
18130 | |||
18131 | tidmask = ADV_TID_TO_TIDMASK(tid); | ||
18132 | |||
18133 | /* | ||
18134 | * Wide Transfers | ||
18135 | * | ||
18136 | * If the EEPROM enabled WDTR for the device and the device | ||
18137 | * supports wide bus (16 bit) transfers, then turn on the | ||
18138 | * device's 'wdtr_able' bit and write the new value to the | ||
18139 | * microcode. | ||
18140 | */ | ||
18141 | if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq)) | ||
18142 | { | ||
18143 | AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word); | ||
18144 | if ((cfg_word & tidmask) == 0) | ||
18145 | { | ||
18146 | cfg_word |= tidmask; | ||
18147 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word); | ||
18148 | |||
18149 | /* | ||
18150 | * Clear the microcode "SDTR negotiation" and "WDTR | ||
18151 | * negotiation" done indicators for the target to cause | ||
18152 | * it to negotiate with the new setting set above. | ||
18153 | * WDTR when accepted causes the target to enter | ||
18154 | * asynchronous mode, so SDTR must be negotiated. | ||
18155 | */ | ||
18156 | AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); | ||
18157 | cfg_word &= ~tidmask; | ||
18158 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); | ||
18159 | AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word); | ||
18160 | cfg_word &= ~tidmask; | ||
18161 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word); | ||
18162 | } | ||
18163 | } | ||
18164 | |||
18165 | /* | ||
18166 | * Synchronous Transfers | ||
18167 | * | ||
18168 | * If the EEPROM enabled SDTR for the device and the device | ||
18169 | * supports synchronous transfers, then turn on the device's | ||
18170 | * 'sdtr_able' bit. Write the new value to the microcode. | ||
18171 | */ | ||
18172 | if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq)) | ||
18173 | { | ||
18174 | AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word); | ||
18175 | if ((cfg_word & tidmask) == 0) | ||
18176 | { | ||
18177 | cfg_word |= tidmask; | ||
18178 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word); | ||
18179 | |||
18180 | /* | ||
18181 | * Clear the microcode "SDTR negotiation" done indicator | ||
18182 | * for the target to cause it to negotiate with the new | ||
18183 | * setting set above. | ||
18184 | */ | ||
18185 | AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); | ||
18186 | cfg_word &= ~tidmask; | ||
18187 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); | ||
18188 | } | ||
18189 | } | ||
18190 | /* | ||
18191 | * If the Inquiry data included enough space for the SPI-3 | ||
18192 | * Clocking field, then check if DT mode is supported. | ||
18193 | */ | ||
18194 | if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 && | ||
18195 | (scsiq->cdb[4] >= 57 || | ||
18196 | (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57)) | ||
18197 | { | ||
18198 | /* | ||
18199 | * PPR (Parallel Protocol Request) Capable | ||
18200 | * | ||
18201 | * If the device supports DT mode, then it must be PPR capable. | ||
18202 | * The PPR message will be used in place of the SDTR and WDTR | ||
18203 | * messages to negotiate synchronous speed and offset, transfer | ||
18204 | * width, and protocol options. | ||
18205 | */ | ||
18206 | if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY) | ||
18207 | { | ||
18208 | AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able); | ||
18209 | asc_dvc->ppr_able |= tidmask; | ||
18210 | AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able); | ||
18211 | } | ||
18212 | } | ||
18213 | |||
18214 | /* | ||
18215 | * If the EEPROM enabled Tag Queuing for the device and the | ||
18216 | * device supports Tag Queueing, then turn on the device's | ||
18217 | * 'tagqng_enable' bit in the microcode and set the microcode | ||
18218 | * maximum command count to the ADV_DVC_VAR 'max_dvc_qng' | ||
18219 | * value. | ||
18220 | * | ||
18221 | * Tag Queuing is disabled for the BIOS which runs in polled | ||
18222 | * mode and would see no benefit from Tag Queuing. Also by | ||
18223 | * disabling Tag Queuing in the BIOS devices with Tag Queuing | ||
18224 | * bugs will at least work with the BIOS. | ||
18225 | */ | ||
18226 | if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq)) | ||
18227 | { | ||
18228 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word); | ||
18229 | cfg_word |= tidmask; | ||
18230 | AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word); | ||
18231 | |||
18232 | AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
18233 | asc_dvc->max_dvc_qng); | ||
18234 | } | ||
18235 | } | ||
18236 | } | ||
18237 | MODULE_LICENSE("Dual BSD/GPL"); | ||