ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / scsi / gdth.c
1 /************************************************************************
2  * Linux driver for                                                     *  
3  * ICP vortex GmbH:    GDT ISA/EISA/PCI Disk Array Controllers          *
4  * Intel Corporation:  Storage RAID Controllers                         *
5  *                                                                      *
6  * gdth.c                                                               *
7  * Copyright (C) 1995-03 ICP vortex GmbH, Achim Leubner                 *
8  * Copyright (C) 2002-03 Intel Corporation                              *
9  * Copyright (C) 2003    Adaptec Inc.                                   *
10  * <achim_leubner@adaptec.com>                                          *
11  *                                                                      *
12  * Additions/Fixes:                                                     *
13  * Boji Tony Kannanthanam <boji.t.kannanthanam@intel.com>               *
14  * Johannes Dinner <johannes_dinner@adaptec.com>                        *
15  *                                                                      *
16  * This program is free software; you can redistribute it and/or modify *
17  * it under the terms of the GNU General Public License as published    *
18  * by the Free Software Foundation; either version 2 of the License,    *
19  * or (at your option) any later version.                               *
20  *                                                                      *
21  * This program is distributed in the hope that it will be useful,      *
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the         *
24  * GNU General Public License for more details.                         *
25  *                                                                      *
26  * You should have received a copy of the GNU General Public License    *
27  * along with this kernel; if not, write to the Free Software           *
28  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.            *
29  *                                                                      *
30  * Tested with Linux 1.2.13, ..., 2.2.20, ..., 2.4.22                   *
31  *                                                                      *
32  * $Log: gdth.c,v $
33  * Revision 1.64  2003/09/17 08:30:26  achim
34  * EISA/ISA controller scan disabled
35  * Command line switch probe_eisa_isa added
36  *
37  * Revision 1.63  2003/07/12 14:01:00  Daniele Bellucci <bellucda@tiscali.it>
38  * Minor cleanups in gdth_ioctl.
39  *
40  * Revision 1.62  2003/02/27 15:01:59  achim
41  * Dynamic DMA mapping implemented
42  * New (character device) IOCTL interface added
43  * Other controller related changes made
44  *
45  * Revision 1.61  2002/11/08 13:09:52  boji
46  * Added support for XSCALE based RAID Controllers
47  * Fixed SCREENSERVICE initialization in SMP cases
48  * Added checks for gdth_polling before GDTH_HA_LOCK
49  *
50  * Revision 1.60  2002/02/05 09:35:22  achim
51  * MODULE_LICENSE only if kernel >= 2.4.11
52  *
53  * Revision 1.59  2002/01/30 09:46:33  achim
54  * Small changes
55  *
56  * Revision 1.58  2002/01/29 15:30:02  achim
57  * Set default value of shared_access to Y
58  * New status S_CACHE_RESERV for clustering added
59  *
60  * Revision 1.57  2001/08/21 11:16:35  achim
61  * Bugfix free_irq()
62  *
63  * Revision 1.56  2001/08/09 11:19:39  achim
64  * Scsi_Host_Template changes
65  *
66  * Revision 1.55  2001/08/09 10:11:28  achim
67  * Command HOST_UNFREEZE_IO before cache service init.
68  *
69  * Revision 1.54  2001/07/20 13:48:12  achim
70  * Expand: gdth_analyse_hdrive() removed
71  *
72  * Revision 1.53  2001/07/17 09:52:49  achim
73  * Small OEM related change
74  *
75  * Revision 1.52  2001/06/19 15:06:20  achim
76  * New host command GDT_UNFREEZE_IO added
77  *
78  * Revision 1.51  2001/05/22 06:42:37  achim
79  * PCI: Subdevice ID added
80  *
81  * Revision 1.50  2001/05/17 13:42:16  achim
82  * Support for Intel Storage RAID Controllers added
83  *
84  * Revision 1.50  2001/05/17 12:12:34  achim
85  * Support for Intel Storage RAID Controllers added
86  *
87  * Revision 1.49  2001/03/15 15:07:17  achim
88  * New __setup interface for boot command line options added
89  *
90  * Revision 1.48  2001/02/06 12:36:28  achim
91  * Bugfix Cluster protocol
92  *
93  * Revision 1.47  2001/01/10 14:42:06  achim
94  * New switch shared_access added
95  *
96  * Revision 1.46  2001/01/09 08:11:35  achim
97  * gdth_command() removed
98  * meaning of Scsi_Pointer members changed
99  *
100  * Revision 1.45  2000/11/16 12:02:24  achim
101  * Changes for kernel 2.4
102  *
103  * Revision 1.44  2000/10/11 08:44:10  achim
104  * Clustering changes: New flag media_changed added
105  *
106  * Revision 1.43  2000/09/20 12:59:01  achim
107  * DPMEM remap functions for all PCI controller types implemented
108  * Small changes for ia64 platform
109  *
110  * Revision 1.42  2000/07/20 09:04:50  achim
111  * Small changes for kernel 2.4
112  *
113  * Revision 1.41  2000/07/04 14:11:11  achim
114  * gdth_analyse_hdrive() added to rescan drives after online expansion
115  *
116  * Revision 1.40  2000/06/27 11:24:16  achim
117  * Changes Clustering, Screenservice
118  *
119  * Revision 1.39  2000/06/15 13:09:04  achim
120  * Changes for gdth_do_cmd()
121  *
122  * Revision 1.38  2000/06/15 12:08:43  achim
123  * Bugfix gdth_sync_event(), service SCREENSERVICE
124  * Data direction for command 0xc2 changed to DOU
125  *
126  * Revision 1.37  2000/05/25 13:50:10  achim
127  * New driver parameter virt_ctr added
128  *
129  * Revision 1.36  2000/05/04 08:50:46  achim
130  * Event buffer now in gdth_ha_str
131  *
132  * Revision 1.35  2000/03/03 10:44:08  achim
133  * New event_string only valid for the RP controller family
134  *
135  * Revision 1.34  2000/03/02 14:55:29  achim
136  * New mechanism for async. event handling implemented
137  *
138  * Revision 1.33  2000/02/21 15:37:37  achim
139  * Bugfix Alpha platform + DPMEM above 4GB
140  *
141  * Revision 1.32  2000/02/14 16:17:37  achim
142  * Bugfix sense_buffer[] + raw devices
143  *
144  * Revision 1.31  2000/02/10 10:29:00  achim
145  * Delete sense_buffer[0], if command OK
146  *
147  * Revision 1.30  1999/11/02 13:42:39  achim
148  * ARRAY_DRV_LIST2 implemented
149  * Now 255 log. and 100 host drives supported
150  *
151  * Revision 1.29  1999/10/05 13:28:47  achim
152  * GDT_CLUST_RESET added
153  *
154  * Revision 1.28  1999/08/12 13:44:54  achim
155  * MOUNTALL removed
156  * Cluster drives -> removeable drives
157  *
158  * Revision 1.27  1999/06/22 07:22:38  achim
159  * Small changes
160  *
161  * Revision 1.26  1999/06/10 16:09:12  achim
162  * Cluster Host Drive support: Bugfixes
163  *
164  * Revision 1.25  1999/06/01 16:03:56  achim
165  * gdth_init_pci(): Manipulate config. space to start RP controller
166  *
167  * Revision 1.24  1999/05/26 11:53:06  achim
168  * Cluster Host Drive support added
169  *
170  * Revision 1.23  1999/03/26 09:12:31  achim
171  * Default value for hdr_channel set to 0
172  *
173  * Revision 1.22  1999/03/22 16:27:16  achim
174  * Bugfix: gdth_store_event() must not be locked with GDTH_LOCK_HA()
175  *
176  * Revision 1.21  1999/03/16 13:40:34  achim
177  * Problems with reserved drives solved
178  * gdth_eh_bus_reset() implemented
179  *
180  * Revision 1.20  1999/03/10 09:08:13  achim
181  * Bugfix: Corrections in gdth_direction_tab[] made
182  * Bugfix: Increase command timeout (gdth_update_timeout()) NOT in gdth_putq()
183  *
184  * Revision 1.19  1999/03/05 14:38:16  achim
185  * Bugfix: Heads/Sectors mapping for reserved devices possibly wrong
186  * -> gdth_eval_mapping() implemented, changes in gdth_bios_param()
187  * INIT_RETRIES set to 100s to avoid DEINIT-Timeout for controllers
188  * with BIOS disabled and memory test set to Intensive
189  * Enhanced /proc support
190  *
191  * Revision 1.18  1999/02/24 09:54:33  achim
192  * Command line parameter hdr_channel implemented
193  * Bugfix for EISA controllers + Linux 2.2.x
194  *
195  * Revision 1.17  1998/12/17 15:58:11  achim
196  * Command line parameters implemented
197  * Changes for Alpha platforms
198  * PCI controller scan changed
199  * SMP support improved (spin_lock_irqsave(),...)
200  * New async. events, new scan/reserve commands included
201  *
202  * Revision 1.16  1998/09/28 16:08:46  achim
203  * GDT_PCIMPR: DPMEM remapping, if required
204  * mdelay() added
205  *
206  * Revision 1.15  1998/06/03 14:54:06  achim
207  * gdth_delay(), gdth_flush() implemented
208  * Bugfix: gdth_release() changed
209  *
210  * Revision 1.14  1998/05/22 10:01:17  achim
211  * mj: pcibios_strerror() removed
212  * Improved SMP support (if version >= 2.1.95)
213  * gdth_halt(): halt_called flag added (if version < 2.1)
214  *
215  * Revision 1.13  1998/04/16 09:14:57  achim
216  * Reserve drives (for raw service) implemented
217  * New error handling code enabled
218  * Get controller name from board_info() IOCTL
219  * Final round of PCI device driver patches by Martin Mares
220  *
221  * Revision 1.12  1998/03/03 09:32:37  achim
222  * Fibre channel controller support added
223  *
224  * Revision 1.11  1998/01/27 16:19:14  achim
225  * SA_SHIRQ added
226  * add_timer()/del_timer() instead of GDTH_TIMER
227  * scsi_add_timer()/scsi_del_timer() instead of SCSI_TIMER
228  * New error handling included
229  *
230  * Revision 1.10  1997/10/31 12:29:57  achim
231  * Read heads/sectors from host drive
232  *
233  * Revision 1.9  1997/09/04 10:07:25  achim
234  * IO-mapping with virt_to_bus(), gdth_readb(), gdth_writeb(), ...
235  * register_reboot_notifier() to get a notify on shutown used
236  *
237  * Revision 1.8  1997/04/02 12:14:30  achim
238  * Version 1.00 (see gdth.h), tested with kernel 2.0.29
239  *
240  * Revision 1.7  1997/03/12 13:33:37  achim
241  * gdth_reset() changed, new async. events
242  *
243  * Revision 1.6  1997/03/04 14:01:11  achim
244  * Shutdown routine gdth_halt() implemented
245  *
246  * Revision 1.5  1997/02/21 09:08:36  achim
247  * New controller included (RP, RP1, RP2 series)
248  * IOCTL interface implemented
249  *
250  * Revision 1.4  1996/07/05 12:48:55  achim
251  * Function gdth_bios_param() implemented
252  * New constant GDTH_MAXC_P_L inserted
253  * GDT_WRITE_THR, GDT_EXT_INFO implemented
254  * Function gdth_reset() changed
255  *
256  * Revision 1.3  1996/05/10 09:04:41  achim
257  * Small changes for Linux 1.2.13
258  *
259  * Revision 1.2  1996/05/09 12:45:27  achim
260  * Loadable module support implemented
261  * /proc support corrections made
262  *
263  * Revision 1.1  1996/04/11 07:35:57  achim
264  * Initial revision
265  *
266  ************************************************************************/
267
268 /* All GDT Disk Array Controllers are fully supported by this driver.
269  * This includes the PCI/EISA/ISA SCSI Disk Array Controllers and the
270  * PCI Fibre Channel Disk Array Controllers. See gdth.h for a complete
271  * list of all controller types.
272  * 
273  * If you have one or more GDT3000/3020 EISA controllers with 
274  * controller BIOS disabled, you have to set the IRQ values with the 
275  * command line option "gdth=irq1,irq2,...", where the irq1,irq2,... are
276  * the IRQ values for the EISA controllers.
277  * 
278  * After the optional list of IRQ values, other possible 
279  * command line options are:
280  * disable:Y                    disable driver
281  * disable:N                    enable driver
282  * reserve_mode:0               reserve no drives for the raw service
283  * reserve_mode:1               reserve all not init., removable drives
284  * reserve_mode:2               reserve all not init. drives
285  * reserve_list:h,b,t,l,h,b,t,l,...     reserve particular drive(s) with 
286  *                              h- controller no., b- channel no., 
287  *                              t- target ID, l- LUN
288  * reverse_scan:Y               reverse scan order for PCI controllers         
289  * reverse_scan:N               scan PCI controllers like BIOS
290  * max_ids:x                    x - target ID count per channel (1..MAXID)
291  * rescan:Y                     rescan all channels/IDs 
292  * rescan:N                     use all devices found until now
293  * virt_ctr:Y                   map every channel to a virtual controller 
294  * virt_ctr:N                   use multi channel support 
295  * hdr_channel:x                x - number of virtual bus for host drives
296  * shared_access:Y              disable driver reserve/release protocol to 
297  *                              access a shared resource from several nodes, 
298  *                              appropiate controller firmware required
299  * shared_access:N              enable driver reserve/release protocol
300  * probe_eisa_isa:Y             scan for EISA/ISA controllers
301  * probe_eisa_isa:N             do not scan for EISA/ISA controllers
302  *
303  * The default values are: "gdth=disable:N,reserve_mode:1,reverse_scan:N,
304  *                          max_ids:127,rescan:N,virt_ctr:N,hdr_channel:0,
305  *                          shared_access:Y,probe_eisa_isa:N".
306  * Here is another example: "gdth=reserve_list:0,1,2,0,0,1,3,0,rescan:Y".
307  * 
308  * When loading the gdth driver as a module, the same options are available. 
309  * You can set the IRQs with "IRQ=...". However, the syntax to specify the
310  * options changes slightly. You must replace all ',' between options 
311  * with ' ' and all ':' with '=' and you must use 
312  * '1' in place of 'Y' and '0' in place of 'N'.
313  * 
314  * Default: "modprobe gdth disable=0 reserve_mode=1 reverse_scan=0
315  *           max_ids=127 rescan=0 virt_ctr=0 hdr_channel=0 shared_access=0 
316  *           probe_eisa_isa=0"
317  * The other example: "modprobe gdth reserve_list=0,1,2,0,0,1,3,0 rescan=1".
318  */
319
320 /* The meaning of the Scsi_Pointer members in this driver is as follows:
321  * ptr:                     Chaining
322  * this_residual:           Command priority
323  * buffer:                  phys. DMA sense buffer 
324  * dma_handle:              phys. DMA buffer (kernel >= 2.4.0)
325  * buffers_residual:        Timeout value
326  * Status:                  Command status (gdth_do_cmd()), DMA mem. mappings
327  * Message:                 Additional info (gdth_do_cmd()), DMA direction
328  * have_data_in:            Flag for gdth_wait_completion()
329  * sent_command:            Opcode special command
330  * phase:                   Service/parameter/return code special command
331  */
332
333 /* default: activate /proc and character device IOCTL interface */
334 #define GDTH_IOCTL_PROC
335 #define GDTH_IOCTL_CHRDEV
336
337 #include <linux/module.h>
338
339 #include <linux/version.h>
340 #include <linux/kernel.h>
341 #include <linux/types.h>
342 #include <linux/pci.h>
343 #include <linux/string.h>
344 #include <linux/ctype.h>
345 #include <linux/ioport.h>
346 #include <linux/delay.h>
347 #include <linux/sched.h>
348 #include <linux/interrupt.h>
349 #include <linux/in.h>
350 #include <linux/proc_fs.h>
351 #include <linux/time.h>
352 #include <linux/timer.h>
353 #ifdef GDTH_RTC
354 #include <linux/mc146818rtc.h>
355 #endif
356 #if LINUX_VERSION_CODE >= 0x020100
357 #include <linux/reboot.h>
358 #else
359 #include <linux/bios32.h>
360 #endif
361
362 #include <asm/dma.h>
363 #include <asm/system.h>
364 #include <asm/io.h>
365 #include <asm/uaccess.h>
366 #if LINUX_VERSION_CODE >= 0x020322
367 #include <linux/spinlock.h>
368 #elif LINUX_VERSION_CODE >= 0x02015F
369 #include <asm/spinlock.h>
370 #endif
371
372 #include <linux/blkdev.h>
373
374 #include "scsi.h"
375 #include "hosts.h"
376 #if LINUX_VERSION_CODE < 0x020503
377 #include "sd.h"
378 #endif
379
380 #include "gdth.h"
381
382 static void gdth_delay(int milliseconds);
383 static void gdth_eval_mapping(ulong32 size, int *cyls, int *heads, int *secs);
384 static irqreturn_t gdth_interrupt(int irq, void *dev_id, struct pt_regs *regs);
385 static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp);
386 static int gdth_async_event(int hanum);
387 static void gdth_log_event(gdth_evt_data *dvr, char *buffer);
388
389 static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority);
390 static void gdth_next(int hanum);
391 static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b);
392 static int gdth_special_cmd(int hanum,Scsi_Cmnd *scp);
393 static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, ushort source,
394                                       ushort idx, gdth_evt_data *evt);
395 static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr);
396 static void gdth_readapp_event(gdth_ha_str *ha, unchar application, 
397                                gdth_evt_str *estr);
398 static void gdth_clear_events(void);
399
400 static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp,
401                                     char *buffer,ushort count);
402 static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp);
403 static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive);
404
405 static int gdth_search_eisa(ushort eisa_adr);
406 static int gdth_search_isa(ulong32 bios_adr);
407 static int gdth_search_pci(gdth_pci_str *pcistr);
408 static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, 
409                             ushort vendor, ushort dev);
410 static void gdth_sort_pci(gdth_pci_str *pcistr, int cnt);
411 static int gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha);
412 static int gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha);
413 static int gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha);
414
415 static void gdth_enable_int(int hanum);
416 static int gdth_get_status(unchar *pIStatus,int irq);
417 static int gdth_test_busy(int hanum);
418 static int gdth_get_cmd_index(int hanum);
419 static void gdth_release_event(int hanum);
420 static int gdth_wait(int hanum,int index,ulong32 time);
421 static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1,
422                              ulong32 p2,ulong32 p3);
423 static int gdth_search_drives(int hanum);
424 static int gdth_analyse_hdrive(int hanum, ushort hdrive);
425
426 static void *gdth_mmap(ulong paddr, ulong size);
427 static void gdth_munmap(void *addr);
428
429 static const char *gdth_ctr_name(int hanum);
430
431 #ifdef GDTH_IOCTL_CHRDEV
432 static int gdth_open(struct inode *inode, struct file *filep);
433 static int gdth_close(struct inode *inode, struct file *filep);
434 static int gdth_ioctl(struct inode *inode, struct file *filep,
435                       unsigned int cmd, unsigned long arg);
436 #endif
437
438 #if LINUX_VERSION_CODE >= 0x010300
439 static void gdth_flush(int hanum);
440 #if LINUX_VERSION_CODE >= 0x020100
441 static int gdth_halt(struct notifier_block *nb, ulong event, void *buf);
442 #else
443 static int halt_called = FALSE;
444 void gdth_halt(void);
445 #endif
446 #endif
447
448 #ifdef DEBUG_GDTH
449 static unchar   DebugState = DEBUG_GDTH;
450
451 #ifdef __SERIAL__
452 #define MAX_SERBUF 160
453 static void ser_init(void);
454 static void ser_puts(char *str);
455 static void ser_putc(char c);
456 static int  ser_printk(const char *fmt, ...);
457 static char strbuf[MAX_SERBUF+1];
458 #ifdef __COM2__
459 #define COM_BASE 0x2f8
460 #else
461 #define COM_BASE 0x3f8
462 #endif
463 static void ser_init()
464 {
465     unsigned port=COM_BASE;
466
467     outb(0x80,port+3);
468     outb(0,port+1);
469     /* 19200 Baud, if 9600: outb(12,port) */
470     outb(6, port);
471     outb(3,port+3);
472     outb(0,port+1);
473     /*
474     ser_putc('I');
475     ser_putc(' ');
476     */
477 }
478
479 static void ser_puts(char *str)
480 {
481     char *ptr;
482
483     ser_init();
484     for (ptr=str;*ptr;++ptr)
485         ser_putc(*ptr);
486 }
487
488 static void ser_putc(char c)
489 {
490     unsigned port=COM_BASE;
491
492     while ((inb(port+5) & 0x20)==0);
493     outb(c,port);
494     if (c==0x0a)
495     {
496         while ((inb(port+5) & 0x20)==0);
497         outb(0x0d,port);
498     }
499 }
500
501 static int ser_printk(const char *fmt, ...)
502 {
503     va_list args;
504     int i;
505
506     va_start(args,fmt);
507     i = vsprintf(strbuf,fmt,args);
508     ser_puts(strbuf);
509     va_end(args);
510     return i;
511 }
512
513 #define TRACE(a)    {if (DebugState==1) {ser_printk a;}}
514 #define TRACE2(a)   {if (DebugState==1 || DebugState==2) {ser_printk a;}}
515 #define TRACE3(a)   {if (DebugState!=0) {ser_printk a;}}
516
517 #else /* !__SERIAL__ */
518 #define TRACE(a)    {if (DebugState==1) {printk a;}}
519 #define TRACE2(a)   {if (DebugState==1 || DebugState==2) {printk a;}}
520 #define TRACE3(a)   {if (DebugState!=0) {printk a;}}
521 #endif
522
523 #else /* !DEBUG */
524 #define TRACE(a)
525 #define TRACE2(a)
526 #define TRACE3(a)
527 #endif
528
529 #ifdef GDTH_STATISTICS
530 static ulong32 max_rq=0, max_index=0, max_sg=0;
531 static ulong32 act_ints=0, act_ios=0, act_stats=0, act_rq=0;
532 static struct timer_list gdth_timer;
533 #endif
534
535 #define PTR2USHORT(a)   (ushort)(ulong)(a)
536 #define GDTOFFSOF(a,b)  (size_t)&(((a*)0)->b)   
537 #define INDEX_OK(i,t)   ((i)<sizeof(t)/sizeof((t)[0]))
538
539 #define NUMDATA(a)      ( (gdth_num_str  *)((a)->hostdata))
540 #define HADATA(a)       (&((gdth_ext_str *)((a)->hostdata))->haext)
541 #define CMDDATA(a)      (&((gdth_ext_str *)((a)->hostdata))->cmdext)
542
543 #define BUS_L2P(a,b)    ((b)>(a)->virt_bus ? (b-1):(b))
544
545 #if LINUX_VERSION_CODE < 0x010300
546 static void *gdth_mmap(ulong paddr, ulong size) 
547 {
548     if (paddr >= high_memory)
549         return NULL; 
550     else
551         return (void *)paddr;
552 }
553 static void gdth_munmap(void *addr) 
554 {
555 }
556 inline ulong32 virt_to_phys(volatile void *addr)
557 {
558     return (ulong32)addr;
559 }
560 inline void *phys_to_virt(ulong32 addr)
561 {
562     return (void *)addr;
563 }
564 #define virt_to_bus             virt_to_phys
565 #define bus_to_virt             phys_to_virt
566 #define gdth_readb(addr)        (*(volatile unchar *)(addr))
567 #define gdth_readw(addr)        (*(volatile ushort *)(addr))
568 #define gdth_readl(addr)        (*(volatile ulong32 *)(addr))
569 #define gdth_writeb(b,addr)     (*(volatile unchar *)(addr) = (b))
570 #define gdth_writew(b,addr)     (*(volatile ushort *)(addr) = (b))
571 #define gdth_writel(b,addr)     (*(volatile ulong32 *)(addr) = (b))
572 #define memset_io(a,b,c)        memset((void *)(a),(b),(c))
573 #define memcpy_fromio(a,b,c)    memcpy((a),(void *)(b),(c))
574 #define memcpy_toio(a,b,c)      memcpy((void *)(a),(b),(c))
575
576 #define PCI_SLOT(devfn)         ((devfn >> 3) & 0x1f)
577
578 #elif LINUX_VERSION_CODE < 0x020100
579 static int remapped = FALSE;
580 static void *gdth_mmap(ulong paddr, ulong size) 
581 {
582     if ( paddr >= high_memory) {
583         remapped = TRUE;
584         return vremap(paddr, size);
585     } else {
586         return (void *)paddr; 
587     }
588 }
589 static void gdth_munmap(void *addr) 
590 {
591     if (remapped)
592         vfree(addr);
593     remapped = FALSE;
594 }
595 #define gdth_readb(addr)        readb((ulong)(addr))
596 #define gdth_readw(addr)        readw((ulong)(addr))
597 #define gdth_readl(addr)        (ulong32)readl((ulong)(addr))
598 #define gdth_writeb(b,addr)     writeb((b),(ulong)(addr))
599 #define gdth_writew(b,addr)     writew((b),(ulong)(addr))
600 #define gdth_writel(b,addr)     writel((ulong32)(b),(ulong)(addr))
601
602 #else
603 static void *gdth_mmap(ulong paddr, ulong size) 
604
605     return ioremap(paddr, size); 
606 }
607 static void gdth_munmap(void *addr) 
608 {
609     return iounmap(addr);
610 }
611 #define gdth_readb(addr)        readb((ulong)(addr))
612 #define gdth_readw(addr)        readw((ulong)(addr))
613 #define gdth_readl(addr)        (ulong32)readl((ulong)(addr))
614 #define gdth_writeb(b,addr)     writeb((b),(ulong)(addr))
615 #define gdth_writew(b,addr)     writew((b),(ulong)(addr))
616 #define gdth_writel(b,addr)     writel((ulong32)(b),(ulong)(addr))
617 #endif
618
619
620 static unchar   gdth_drq_tab[4] = {5,6,7,7};            /* DRQ table */
621 static unchar   gdth_irq_tab[6] = {0,10,11,12,14,0};    /* IRQ table */
622 static unchar   gdth_polling;                           /* polling if TRUE */
623 static unchar   gdth_from_wait  = FALSE;                /* gdth_wait() */
624 static int      wait_index,wait_hanum;                  /* gdth_wait() */
625 static int      gdth_ctr_count  = 0;                    /* controller count */
626 static int      gdth_ctr_vcount = 0;                    /* virt. ctr. count */
627 static int      gdth_ctr_released = 0;                  /* gdth_release() */
628 static struct Scsi_Host *gdth_ctr_tab[MAXHA];           /* controller table */
629 static struct Scsi_Host *gdth_ctr_vtab[MAXHA*MAXBUS];   /* virt. ctr. table */
630 static unchar   gdth_write_through = FALSE;             /* write through */
631 static gdth_evt_str ebuffer[MAX_EVENTS];                /* event buffer */
632 static int elastidx;
633 static int eoldidx;
634 #ifdef GDTH_IOCTL_CHRDEV
635 static int major;
636 #endif
637
638 #define DIN     1                               /* IN data direction */
639 #define DOU     2                               /* OUT data direction */
640 #define DNO     DIN                             /* no data transfer */
641 #define DUN     DIN                             /* unknown data direction */
642 static unchar gdth_direction_tab[0x100] = {
643     DNO,DNO,DIN,DIN,DOU,DIN,DIN,DOU,DIN,DUN,DOU,DOU,DUN,DUN,DUN,DIN,
644     DNO,DIN,DIN,DOU,DIN,DOU,DNO,DNO,DOU,DNO,DIN,DNO,DIN,DOU,DNO,DUN,
645     DIN,DUN,DIN,DUN,DOU,DIN,DUN,DUN,DIN,DIN,DOU,DNO,DUN,DIN,DOU,DOU,
646     DOU,DOU,DOU,DNO,DIN,DNO,DNO,DIN,DOU,DOU,DOU,DOU,DIN,DOU,DIN,DOU,
647     DOU,DOU,DIN,DIN,DIN,DNO,DUN,DNO,DNO,DNO,DUN,DNO,DOU,DIN,DUN,DUN,
648     DUN,DUN,DUN,DUN,DUN,DOU,DUN,DUN,DUN,DUN,DIN,DUN,DUN,DUN,DUN,DUN,
649     DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
650     DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
651     DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
652     DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
653     DUN,DUN,DUN,DUN,DUN,DNO,DNO,DUN,DIN,DNO,DOU,DUN,DNO,DUN,DOU,DOU,
654     DOU,DOU,DOU,DNO,DUN,DIN,DOU,DIN,DIN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
655     DUN,DUN,DOU,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
656     DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
657     DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DOU,DUN,DUN,DUN,DUN,DUN,
658     DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN
659 };
660
661 /* __initfunc, __initdata macros */
662 #if LINUX_VERSION_CODE >= 0x020322
663 #define GDTH_INITFUNC(type, func)       type __init func 
664 #include <linux/init.h>
665 #elif LINUX_VERSION_CODE >= 0x020126
666 #define GDTH_INITFUNC(type, func)       __initfunc(type func)
667 #include <linux/init.h>
668 #else
669 #define GDTH_INITFUNC(type, func)       type func
670 #define __initdata
671 #define __init
672 #endif
673
674 #if LINUX_VERSION_CODE >= 0x020503
675 #define GDTH_INIT_LOCK_HA(ha)           spin_lock_init(&(ha)->smp_lock)
676 #define GDTH_LOCK_HA(ha,flags)          spin_lock_irqsave(&(ha)->smp_lock,flags)
677 #define GDTH_UNLOCK_HA(ha,flags)        spin_unlock_irqrestore(&(ha)->smp_lock,flags)
678
679 #define GDTH_LOCK_SCSI_DONE(dev, flags) spin_lock_irqsave(dev->host_lock,flags)
680 #define GDTH_UNLOCK_SCSI_DONE(dev, flags) spin_unlock_irqrestore(dev->host_lock,flags)
681 #define GDTH_LOCK_SCSI_DOCMD(dev)       spin_lock_irq(dev->host_lock)
682 #define GDTH_UNLOCK_SCSI_DOCMD(dev)     spin_unlock_irq(dev->host_lock)
683
684 #elif LINUX_VERSION_CODE >= 0x02015F
685 #define GDTH_INIT_LOCK_HA(ha)           spin_lock_init(&(ha)->smp_lock)
686 #define GDTH_LOCK_HA(ha,flags)          spin_lock_irqsave(&(ha)->smp_lock,flags)
687 #define GDTH_UNLOCK_HA(ha,flags)        spin_unlock_irqrestore(&(ha)->smp_lock,flags)
688
689 #define GDTH_LOCK_SCSI_DONE(flags)      spin_lock_irqsave(&io_request_lock,flags)
690 #define GDTH_UNLOCK_SCSI_DONE(flags)    spin_unlock_irqrestore(&io_request_lock,flags)
691 #define GDTH_LOCK_SCSI_DOCMD()          spin_lock_irq(&io_request_lock)
692 #define GDTH_UNLOCK_SCSI_DOCMD()        spin_unlock_irq(&io_request_lock)
693
694 #else
695 #define GDTH_INIT_LOCK_HA(ha)           do {} while (0)
696 #define GDTH_LOCK_HA(ha,flags)          do {save_flags(flags); cli();} while (0)
697 #define GDTH_UNLOCK_HA(ha,flags)        do {restore_flags(flags);} while (0)
698
699 #define GDTH_LOCK_SCSI_DONE(flags)      do {} while (0)
700 #define GDTH_UNLOCK_SCSI_DONE(flags)    do {} while (0)
701 #define GDTH_LOCK_SCSI_DOCMD()          do {} while (0)
702 #define GDTH_UNLOCK_SCSI_DOCMD()        do {} while (0)
703 #endif
704
705 /* LILO and modprobe/insmod parameters */
706 /* IRQ list for GDT3000/3020 EISA controllers */
707 static int irq[MAXHA] __initdata = 
708 {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
709  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
710 /* disable driver flag */
711 static int disable __initdata = 0;
712 /* reserve flag */
713 static int reserve_mode = 1;                  
714 /* reserve list */
715 static int reserve_list[MAX_RES_ARGS] = 
716 {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
717  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
718  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
719 /* scan order for PCI controllers */
720 static int reverse_scan = 0;
721 /* virtual channel for the host drives */
722 static int hdr_channel = 0;
723 /* max. IDs per channel */
724 static int max_ids = MAXID;
725 /* rescan all IDs */
726 static int rescan = 0;
727 /* map channels to virtual controllers */
728 static int virt_ctr = 0;
729 /* shared access */
730 static int shared_access = 1;
731 /* enable support for EISA and ISA controllers */
732 static int probe_eisa_isa = 0;
733
734 #ifdef MODULE
735 #if LINUX_VERSION_CODE >= 0x02011A
736 /* parameters for modprobe/insmod */
737 MODULE_PARM(irq, "i");
738 MODULE_PARM(disable, "i");
739 MODULE_PARM(reserve_mode, "i");
740 MODULE_PARM(reserve_list, "4-" __MODULE_STRING(MAX_RES_ARGS) "i");
741 MODULE_PARM(reverse_scan, "i");
742 MODULE_PARM(hdr_channel, "i");
743 MODULE_PARM(max_ids, "i");
744 MODULE_PARM(rescan, "i");
745 MODULE_PARM(virt_ctr, "i");
746 MODULE_PARM(shared_access, "i");
747 MODULE_PARM(probe_eisa_isa, "i");
748 MODULE_AUTHOR("Achim Leubner");
749 #endif
750 #if LINUX_VERSION_CODE >= 0x02040B
751 MODULE_LICENSE("GPL");
752 #endif
753 #endif
754
755 #ifdef GDTH_IOCTL_CHRDEV
756 /* ioctl interface */
757 static struct file_operations gdth_fops = {
758         .ioctl          = gdth_ioctl,
759         .open           = gdth_open,
760         .release        = gdth_close,
761 };
762 #endif
763
764 /* /proc support */
765 #if LINUX_VERSION_CODE >= 0x010300
766 #include <linux/stat.h> 
767 #if LINUX_VERSION_CODE < 0x020322
768 struct proc_dir_entry proc_scsi_gdth = {
769     PROC_SCSI_GDTH, 4, "gdth",
770     S_IFDIR | S_IRUGO | S_IXUGO, 2
771 };
772 #endif
773 #include "gdth_proc.h"
774 #include "gdth_proc.c"
775 #endif
776
777 #if LINUX_VERSION_CODE >= 0x020100
778 /* notifier block to get a notify on system shutdown/halt/reboot */
779 static struct notifier_block gdth_notifier = {
780     gdth_halt, NULL, 0
781 };
782 #endif
783
784
785 static void gdth_delay(int milliseconds)
786 {
787     if (milliseconds == 0) {
788         udelay(1);
789     } else {
790 #if LINUX_VERSION_CODE >= 0x020168
791         mdelay(milliseconds);
792 #else
793         int i;
794         for (i = 0; i < milliseconds; ++i) 
795             udelay(1000);
796 #endif
797     }
798 }
799
800 static void gdth_eval_mapping(ulong32 size, int *cyls, int *heads, int *secs)
801 {
802     *cyls = size /HEADS/SECS;
803     if (*cyls <= MAXCYLS) {
804         *heads = HEADS;
805         *secs = SECS;
806     } else {                                        /* too high for 64*32 */
807         *cyls = size /MEDHEADS/MEDSECS;
808         if (*cyls <= MAXCYLS) {
809             *heads = MEDHEADS;
810             *secs = MEDSECS;
811         } else {                                    /* too high for 127*63 */
812             *cyls = size /BIGHEADS/BIGSECS;
813             *heads = BIGHEADS;
814             *secs = BIGSECS;
815         }
816     }
817 }
818
819 /* controller search and initialization functions */
820
821 GDTH_INITFUNC(static int, gdth_search_eisa(ushort eisa_adr))
822 {
823     ulong32 id;
824     
825     TRACE(("gdth_search_eisa() adr. %x\n",eisa_adr));
826     id = inl(eisa_adr+ID0REG);
827     if (id == GDT3A_ID || id == GDT3B_ID) {     /* GDT3000A or GDT3000B */
828         if ((inb(eisa_adr+EISAREG) & 8) == 0)   
829             return 0;                           /* not EISA configured */
830         return 1;
831     }
832     if (id == GDT3_ID)                          /* GDT3000 */
833         return 1;
834
835     return 0;                                   
836 }
837
838
839 GDTH_INITFUNC(static int, gdth_search_isa(ulong32 bios_adr))
840 {
841     void *addr;
842     ulong32 id;
843
844     TRACE(("gdth_search_isa() bios adr. %x\n",bios_adr));
845     if ((addr = gdth_mmap(bios_adr+BIOS_ID_OFFS, sizeof(ulong32))) != NULL) {
846         id = gdth_readl(addr);
847         gdth_munmap(addr);
848         if (id == GDT2_ID)                          /* GDT2000 */
849             return 1;
850     }
851     return 0;
852 }
853
854
855 GDTH_INITFUNC(static int, gdth_search_pci(gdth_pci_str *pcistr))
856 {
857     ushort device, cnt;
858     
859     TRACE(("gdth_search_pci()\n"));
860
861     cnt = 0;
862     for (device = 0; device <= PCI_DEVICE_ID_VORTEX_GDT6555; ++device)
863         gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device);
864     for (device = PCI_DEVICE_ID_VORTEX_GDT6x17RP; 
865          device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP; ++device)
866         gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device);
867     gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, 
868                     PCI_DEVICE_ID_VORTEX_GDTNEWRX);
869     gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL,
870                     PCI_DEVICE_ID_INTEL_SRC);
871     gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL,
872                     PCI_DEVICE_ID_INTEL_SRC_XSCALE);
873     return cnt;
874 }
875
876 #if LINUX_VERSION_CODE >= 0x20363
877 /* Vortex only makes RAID controllers.
878  * We do not really want to specify all 550 ids here, so wildcard match.
879  */
880 static struct pci_device_id gdthtable[] = {
881     {PCI_VENDOR_ID_VORTEX,PCI_ANY_ID,PCI_ANY_ID, PCI_ANY_ID},
882     {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC,PCI_ANY_ID,PCI_ANY_ID}, 
883     {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC_XSCALE,PCI_ANY_ID,PCI_ANY_ID}, 
884     {0}
885 };
886 MODULE_DEVICE_TABLE(pci,gdthtable);
887 #endif
888
889 GDTH_INITFUNC(static void, gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
890                                            ushort vendor, ushort device))
891 {
892     ulong base0, base1, base2;
893 #if LINUX_VERSION_CODE >= 0x2015C
894     struct pci_dev *pdev;
895 #else
896     int error;
897     ushort idx;
898 #endif
899     
900     TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n",
901           *cnt, vendor, device));
902
903 #if LINUX_VERSION_CODE >= 0x20363
904     pdev = NULL;
905     while ((pdev = pci_find_device(vendor, device, pdev)) 
906            != NULL) {
907         if (pci_enable_device(pdev))
908             continue;
909         if (*cnt >= MAXHA)
910             return;
911         /* GDT PCI controller found, resources are already in pdev */
912         pcistr[*cnt].pdev = pdev;
913         pcistr[*cnt].vendor_id = vendor;
914         pcistr[*cnt].device_id = device;
915         pcistr[*cnt].subdevice_id = pdev->subsystem_device;
916         pcistr[*cnt].bus = pdev->bus->number;
917         pcistr[*cnt].device_fn = pdev->devfn;
918         pcistr[*cnt].irq = pdev->irq;
919         base0 = pci_resource_flags(pdev, 0);
920         base1 = pci_resource_flags(pdev, 1);
921         base2 = pci_resource_flags(pdev, 2);
922         if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
923             device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
924             if (!(base0 & IORESOURCE_MEM)) 
925                 continue;
926             pcistr[*cnt].dpmem = pci_resource_start(pdev, 0);
927         } else {                                  /* GDT6110, GDT6120, .. */
928             if (!(base0 & IORESOURCE_MEM) ||
929                 !(base2 & IORESOURCE_MEM) ||
930                 !(base1 & IORESOURCE_IO)) 
931                 continue;
932             pcistr[*cnt].dpmem = pci_resource_start(pdev, 2);
933             pcistr[*cnt].io_mm = pci_resource_start(pdev, 0);
934             pcistr[*cnt].io    = pci_resource_start(pdev, 1);
935         }
936         TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
937                 pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn), 
938                 pcistr[*cnt].irq, pcistr[*cnt].dpmem));
939         (*cnt)++;
940     }       
941 #elif LINUX_VERSION_CODE >= 0x2015C
942     pdev = NULL;
943     while ((pdev = pci_find_device(vendor, device, pdev)) 
944            != NULL) {
945         if (*cnt >= MAXHA)
946             return;
947         /* GDT PCI controller found, resources are already in pdev */
948         pcistr[*cnt].pdev = pdev;
949         pcistr[*cnt].vendor_id = vendor;
950         pcistr[*cnt].device_id = device;
951         pcistr[*cnt].bus = pdev->bus->number;
952         pcistr[*cnt].device_fn = pdev->devfn;
953         pcibios_read_config_word(pcistr[*cnt].bus, pcistr[*cnt].device_fn,
954                                  PCI_SUBSYSTEM_ID, &pcistr[*cnt].subdevice_id);
955         pcistr[*cnt].irq = pdev->irq;
956         base0 = pdev->base_address[0];
957         base1 = pdev->base_address[1];
958         base2 = pdev->base_address[2];
959         if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
960             device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
961             if ((base0 & PCI_BASE_ADDRESS_SPACE) != 
962                 PCI_BASE_ADDRESS_SPACE_MEMORY)
963                 continue;
964             pcistr[*cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;
965         } else {                                  /* GDT6110, GDT6120, .. */
966             if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
967                 PCI_BASE_ADDRESS_SPACE_MEMORY ||
968                 (base2 & PCI_BASE_ADDRESS_SPACE) !=
969                 PCI_BASE_ADDRESS_SPACE_MEMORY ||
970                 (base1 & PCI_BASE_ADDRESS_SPACE) !=
971                 PCI_BASE_ADDRESS_SPACE_IO)
972                 continue;
973             pcistr[*cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;
974             pcistr[*cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;
975             pcistr[*cnt].io    = base1 & PCI_BASE_ADDRESS_IO_MASK;
976         }
977         TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
978                 pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn), 
979                 pcistr[*cnt].irq, pcistr[*cnt].dpmem));
980         (*cnt)++;
981     }       
982 #else   
983     idx = 0;
984     while (!pcibios_find_device(vendor, device, idx++,
985                                 &pcistr[*cnt].bus,&pcistr[*cnt].device_fn)) {
986         if (*cnt >= MAXHA)
987             return;
988         /* GDT PCI ctr. found, now read resources from config space */
989 #if LINUX_VERSION_CODE >= 0x010300
990 #define GDTH_BASEP      (int *)
991 #else
992 #define GDTH_BASEP
993 #endif
994         if ((error = pcibios_read_config_dword(pcistr[*cnt].bus,
995                                                pcistr[*cnt].device_fn,
996                                                PCI_BASE_ADDRESS_0,
997                                                GDTH_BASEP&base0)) ||
998             (error = pcibios_read_config_dword(pcistr[*cnt].bus,
999                                                pcistr[*cnt].device_fn,
1000                                                PCI_BASE_ADDRESS_1,
1001                                                GDTH_BASEP&base1)) ||
1002             (error = pcibios_read_config_dword(pcistr[*cnt].bus,
1003                                                pcistr[*cnt].device_fn,
1004                                                PCI_BASE_ADDRESS_2,
1005                                                GDTH_BASEP&base2)) ||
1006             (error = pcibios_read_config_word(pcistr[*cnt].bus,
1007                                               pcistr[*cnt].device_fn,
1008                                               PCI_SUBSYSTEM_ID,
1009                                               &pcistr[*cnt].subdevice_id)) ||
1010             (error = pcibios_read_config_byte(pcistr[*cnt].bus,
1011                                               pcistr[*cnt].device_fn,
1012                                               PCI_INTERRUPT_LINE,
1013                                               &pcistr[*cnt].irq))) {
1014             printk("GDT-PCI: error %d reading configuration space", error);
1015             continue;
1016         }
1017         pcistr[*cnt].vendor_id = vendor;
1018         pcistr[*cnt].device_id = device;
1019         if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
1020             device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
1021             if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
1022                 PCI_BASE_ADDRESS_SPACE_MEMORY)
1023                 continue;
1024             pcistr[*cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;
1025         } else {                                    /* GDT6110, GDT6120, .. */
1026             if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
1027                 PCI_BASE_ADDRESS_SPACE_MEMORY ||
1028                 (base2 & PCI_BASE_ADDRESS_SPACE) !=
1029                 PCI_BASE_ADDRESS_SPACE_MEMORY ||
1030                 (base1 & PCI_BASE_ADDRESS_SPACE) !=
1031                 PCI_BASE_ADDRESS_SPACE_IO)
1032                 continue;
1033             pcistr[*cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;
1034             pcistr[*cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;
1035             pcistr[*cnt].io    = base1 & PCI_BASE_ADDRESS_IO_MASK;
1036         }
1037         TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
1038                 pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn), 
1039                 pcistr[*cnt].irq, pcistr[*cnt].dpmem));
1040         (*cnt)++;
1041     }
1042 #endif
1043 }   
1044
1045
1046 GDTH_INITFUNC(static void, gdth_sort_pci(gdth_pci_str *pcistr, int cnt))
1047 {    
1048     gdth_pci_str temp;
1049     int i, changed;
1050     
1051     TRACE(("gdth_sort_pci() cnt %d\n",cnt));
1052     if (cnt == 0)
1053         return;
1054
1055     do {
1056         changed = FALSE;
1057         for (i = 0; i < cnt-1; ++i) {
1058             if (!reverse_scan) {
1059                 if ((pcistr[i].bus > pcistr[i+1].bus) ||
1060                     (pcistr[i].bus == pcistr[i+1].bus &&
1061                      PCI_SLOT(pcistr[i].device_fn) > 
1062                      PCI_SLOT(pcistr[i+1].device_fn))) {
1063                     temp = pcistr[i];
1064                     pcistr[i] = pcistr[i+1];
1065                     pcistr[i+1] = temp;
1066                     changed = TRUE;
1067                 }
1068             } else {
1069                 if ((pcistr[i].bus < pcistr[i+1].bus) ||
1070                     (pcistr[i].bus == pcistr[i+1].bus &&
1071                      PCI_SLOT(pcistr[i].device_fn) < 
1072                      PCI_SLOT(pcistr[i+1].device_fn))) {
1073                     temp = pcistr[i];
1074                     pcistr[i] = pcistr[i+1];
1075                     pcistr[i+1] = temp;
1076                     changed = TRUE;
1077                 }
1078             }
1079         }
1080     } while (changed);
1081 }
1082
1083
1084 GDTH_INITFUNC(static int, gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha))
1085 {
1086     ulong32 retries,id;
1087     unchar prot_ver,eisacf,i,irq_found;
1088
1089     TRACE(("gdth_init_eisa() adr. %x\n",eisa_adr));
1090     
1091     /* disable board interrupts, deinitialize services */
1092     outb(0xff,eisa_adr+EDOORREG);
1093     outb(0x00,eisa_adr+EDENABREG);
1094     outb(0x00,eisa_adr+EINTENABREG);
1095     
1096     outb(0xff,eisa_adr+LDOORREG);
1097     retries = INIT_RETRIES;
1098     gdth_delay(20);
1099     while (inb(eisa_adr+EDOORREG) != 0xff) {
1100         if (--retries == 0) {
1101             printk("GDT-EISA: Initialization error (DEINIT failed)\n");
1102             return 0;
1103         }
1104         gdth_delay(1);
1105         TRACE2(("wait for DEINIT: retries=%d\n",retries));
1106     }
1107     prot_ver = inb(eisa_adr+MAILBOXREG);
1108     outb(0xff,eisa_adr+EDOORREG);
1109     if (prot_ver != PROTOCOL_VERSION) {
1110         printk("GDT-EISA: Illegal protocol version\n");
1111         return 0;
1112     }
1113     ha->bmic = eisa_adr;
1114     ha->brd_phys = (ulong32)eisa_adr >> 12;
1115
1116     outl(0,eisa_adr+MAILBOXREG);
1117     outl(0,eisa_adr+MAILBOXREG+4);
1118     outl(0,eisa_adr+MAILBOXREG+8);
1119     outl(0,eisa_adr+MAILBOXREG+12);
1120
1121     /* detect IRQ */ 
1122     if ((id = inl(eisa_adr+ID0REG)) == GDT3_ID) {
1123         ha->oem_id = OEM_ID_ICP;
1124         ha->type = GDT_EISA;
1125         ha->stype = id;
1126         outl(1,eisa_adr+MAILBOXREG+8);
1127         outb(0xfe,eisa_adr+LDOORREG);
1128         retries = INIT_RETRIES;
1129         gdth_delay(20);
1130         while (inb(eisa_adr+EDOORREG) != 0xfe) {
1131             if (--retries == 0) {
1132                 printk("GDT-EISA: Initialization error (get IRQ failed)\n");
1133                 return 0;
1134             }
1135             gdth_delay(1);
1136         }
1137         ha->irq = inb(eisa_adr+MAILBOXREG);
1138         outb(0xff,eisa_adr+EDOORREG);
1139         TRACE2(("GDT3000/3020: IRQ=%d\n",ha->irq));
1140         /* check the result */
1141         if (ha->irq == 0) {
1142                 TRACE2(("Unknown IRQ, use IRQ table from cmd line !\n"));
1143                 for (i = 0, irq_found = FALSE; 
1144                      i < MAXHA && irq[i] != 0xff; ++i) {
1145                 if (irq[i]==10 || irq[i]==11 || irq[i]==12 || irq[i]==14) {
1146                     irq_found = TRUE;
1147                     break;
1148                 }
1149                 }
1150             if (irq_found) {
1151                 ha->irq = irq[i];
1152                 irq[i] = 0;
1153                 printk("GDT-EISA: Can not detect controller IRQ,\n");
1154                 printk("Use IRQ setting from command line (IRQ = %d)\n",
1155                        ha->irq);
1156             } else {
1157                 printk("GDT-EISA: Initialization error (unknown IRQ), Enable\n");
1158                 printk("the controller BIOS or use command line parameters\n");
1159                 return 0;
1160             }
1161         }
1162     } else {
1163         eisacf = inb(eisa_adr+EISAREG) & 7;
1164         if (eisacf > 4)                         /* level triggered */
1165             eisacf -= 4;
1166         ha->irq = gdth_irq_tab[eisacf];
1167         ha->oem_id = OEM_ID_ICP;
1168         ha->type = GDT_EISA;
1169         ha->stype = id;
1170     }
1171     return 1;
1172 }
1173
1174        
1175 GDTH_INITFUNC(static int, gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha))
1176 {
1177     register gdt2_dpram_str *dp2_ptr;
1178     int i;
1179     unchar irq_drq,prot_ver;
1180     ulong32 retries;
1181
1182     TRACE(("gdth_init_isa() bios adr. %x\n",bios_adr));
1183
1184     ha->brd = gdth_mmap(bios_adr, sizeof(gdt2_dpram_str));
1185     if (ha->brd == NULL) {
1186         printk("GDT-ISA: Initialization error (DPMEM remap error)\n");
1187         return 0;
1188     }
1189     dp2_ptr = (gdt2_dpram_str *)ha->brd;
1190     gdth_writeb(1, &dp2_ptr->io.memlock); /* switch off write protection */
1191     /* reset interface area */
1192     memset_io((char *)&dp2_ptr->u,0,sizeof(dp2_ptr->u));
1193     if (gdth_readl(&dp2_ptr->u) != 0) {
1194         printk("GDT-PCI: Initialization error (DPMEM write error)\n");
1195         gdth_munmap(ha->brd);
1196         return 0;
1197     }
1198
1199     /* disable board interrupts, read DRQ and IRQ */
1200     gdth_writeb(0xff, &dp2_ptr->io.irqdel);
1201     gdth_writeb(0x00, &dp2_ptr->io.irqen);
1202     gdth_writeb(0x00, &dp2_ptr->u.ic.S_Status);
1203     gdth_writeb(0x00, &dp2_ptr->u.ic.Cmd_Index);
1204
1205     irq_drq = gdth_readb(&dp2_ptr->io.rq);
1206     for (i=0; i<3; ++i) {
1207         if ((irq_drq & 1)==0)
1208             break;
1209         irq_drq >>= 1;
1210     }
1211     ha->drq = gdth_drq_tab[i];
1212
1213     irq_drq = gdth_readb(&dp2_ptr->io.rq) >> 3;
1214     for (i=1; i<5; ++i) {
1215         if ((irq_drq & 1)==0)
1216             break;
1217         irq_drq >>= 1;
1218     }
1219     ha->irq = gdth_irq_tab[i];
1220
1221     /* deinitialize services */
1222     gdth_writel(bios_adr, &dp2_ptr->u.ic.S_Info[0]);
1223     gdth_writeb(0xff, &dp2_ptr->u.ic.S_Cmd_Indx);
1224     gdth_writeb(0, &dp2_ptr->io.event);
1225     retries = INIT_RETRIES;
1226     gdth_delay(20);
1227     while (gdth_readb(&dp2_ptr->u.ic.S_Status) != 0xff) {
1228         if (--retries == 0) {
1229             printk("GDT-ISA: Initialization error (DEINIT failed)\n");
1230             gdth_munmap(ha->brd);
1231             return 0;
1232         }
1233         gdth_delay(1);
1234     }
1235     prot_ver = (unchar)gdth_readl(&dp2_ptr->u.ic.S_Info[0]);
1236     gdth_writeb(0, &dp2_ptr->u.ic.Status);
1237     gdth_writeb(0xff, &dp2_ptr->io.irqdel);
1238     if (prot_ver != PROTOCOL_VERSION) {
1239         printk("GDT-ISA: Illegal protocol version\n");
1240         gdth_munmap(ha->brd);
1241         return 0;
1242     }
1243
1244     ha->oem_id = OEM_ID_ICP;
1245     ha->type = GDT_ISA;
1246     ha->ic_all_size = sizeof(dp2_ptr->u);
1247     ha->stype= GDT2_ID;
1248     ha->brd_phys = bios_adr >> 4;
1249
1250     /* special request to controller BIOS */
1251     gdth_writel(0x00, &dp2_ptr->u.ic.S_Info[0]);
1252     gdth_writel(0x00, &dp2_ptr->u.ic.S_Info[1]);
1253     gdth_writel(0x01, &dp2_ptr->u.ic.S_Info[2]);
1254     gdth_writel(0x00, &dp2_ptr->u.ic.S_Info[3]);
1255     gdth_writeb(0xfe, &dp2_ptr->u.ic.S_Cmd_Indx);
1256     gdth_writeb(0, &dp2_ptr->io.event);
1257     retries = INIT_RETRIES;
1258     gdth_delay(20);
1259     while (gdth_readb(&dp2_ptr->u.ic.S_Status) != 0xfe) {
1260         if (--retries == 0) {
1261             printk("GDT-ISA: Initialization error\n");
1262             gdth_munmap(ha->brd);
1263             return 0;
1264         }
1265         gdth_delay(1);
1266     }
1267     gdth_writeb(0, &dp2_ptr->u.ic.Status);
1268     gdth_writeb(0xff, &dp2_ptr->io.irqdel);
1269     return 1;
1270 }
1271
1272
1273 GDTH_INITFUNC(static int, gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha))
1274 {
1275     register gdt6_dpram_str *dp6_ptr;
1276     register gdt6c_dpram_str *dp6c_ptr;
1277     register gdt6m_dpram_str *dp6m_ptr;
1278     ulong32 retries;
1279     unchar prot_ver;
1280     ushort command;
1281     int i, found = FALSE;
1282 #if LINUX_VERSION_CODE < 0x2015C
1283     int rom_addr;
1284 #endif
1285
1286     TRACE(("gdth_init_pci()\n"));
1287
1288     if (pcistr->vendor_id == PCI_VENDOR_ID_INTEL)
1289         ha->oem_id = OEM_ID_INTEL;
1290     else
1291         ha->oem_id = OEM_ID_ICP;
1292     ha->brd_phys = (pcistr->bus << 8) | (pcistr->device_fn & 0xf8);
1293     ha->stype = (ulong32)pcistr->device_id;
1294     ha->subdevice_id = pcistr->subdevice_id;
1295     ha->irq = pcistr->irq;
1296 #if LINUX_VERSION_CODE >= 0x20400
1297     ha->pdev = pcistr->pdev;
1298 #endif
1299     
1300     if (ha->stype <= PCI_DEVICE_ID_VORTEX_GDT6000B) {  /* GDT6000/B */
1301         TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq));
1302         ha->brd = gdth_mmap(pcistr->dpmem, sizeof(gdt6_dpram_str));
1303         if (ha->brd == NULL) {
1304             printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
1305             return 0;
1306         }
1307         /* check and reset interface area */
1308         dp6_ptr = (gdt6_dpram_str *)ha->brd;
1309         gdth_writel(DPMEM_MAGIC, &dp6_ptr->u);
1310         if (gdth_readl(&dp6_ptr->u) != DPMEM_MAGIC) {
1311             printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", 
1312                    pcistr->dpmem);
1313             found = FALSE;
1314             for (i = 0xC8000; i < 0xE8000; i += 0x4000) {
1315                 gdth_munmap(ha->brd);
1316                 ha->brd = gdth_mmap(i, sizeof(ushort)); 
1317                 if (ha->brd == NULL) {
1318                     printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
1319                     return 0;
1320                 }
1321                 if (gdth_readw(ha->brd) != 0xffff) {
1322                     TRACE2(("init_pci_old() address 0x%x busy\n", i));
1323                     continue;
1324                 }
1325                 gdth_munmap(ha->brd);
1326 #if LINUX_VERSION_CODE >= 0x2015C
1327                 pci_write_config_dword(pcistr->pdev, 
1328                                        PCI_BASE_ADDRESS_0, i);
1329 #else
1330                 pcibios_write_config_dword(pcistr->bus, pcistr->device_fn,
1331                                            PCI_BASE_ADDRESS_0, i);
1332 #endif
1333                 ha->brd = gdth_mmap(i, sizeof(gdt6_dpram_str)); 
1334                 if (ha->brd == NULL) {
1335                     printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
1336                     return 0;
1337                 }
1338                 dp6_ptr = (gdt6_dpram_str *)ha->brd;
1339                 gdth_writel(DPMEM_MAGIC, &dp6_ptr->u);
1340                 if (gdth_readl(&dp6_ptr->u) == DPMEM_MAGIC) {
1341                     printk("GDT-PCI: Use free address at 0x%x\n", i);
1342                     found = TRUE;
1343                     break;
1344                 }
1345             }   
1346             if (!found) {
1347                 printk("GDT-PCI: No free address found!\n");
1348                 gdth_munmap(ha->brd);
1349                 return 0;
1350             }
1351         }
1352         memset_io((char *)&dp6_ptr->u,0,sizeof(dp6_ptr->u));
1353         if (gdth_readl(&dp6_ptr->u) != 0) {
1354             printk("GDT-PCI: Initialization error (DPMEM write error)\n");
1355             gdth_munmap(ha->brd);
1356             return 0;
1357         }
1358         
1359         /* disable board interrupts, deinit services */
1360         gdth_writeb(0xff, &dp6_ptr->io.irqdel);
1361         gdth_writeb(0x00, &dp6_ptr->io.irqen);
1362         gdth_writeb(0x00, &dp6_ptr->u.ic.S_Status);
1363         gdth_writeb(0x00, &dp6_ptr->u.ic.Cmd_Index);
1364
1365         gdth_writel(pcistr->dpmem, &dp6_ptr->u.ic.S_Info[0]);
1366         gdth_writeb(0xff, &dp6_ptr->u.ic.S_Cmd_Indx);
1367         gdth_writeb(0, &dp6_ptr->io.event);
1368         retries = INIT_RETRIES;
1369         gdth_delay(20);
1370         while (gdth_readb(&dp6_ptr->u.ic.S_Status) != 0xff) {
1371             if (--retries == 0) {
1372                 printk("GDT-PCI: Initialization error (DEINIT failed)\n");
1373                 gdth_munmap(ha->brd);
1374                 return 0;
1375             }
1376             gdth_delay(1);
1377         }
1378         prot_ver = (unchar)gdth_readl(&dp6_ptr->u.ic.S_Info[0]);
1379         gdth_writeb(0, &dp6_ptr->u.ic.S_Status);
1380         gdth_writeb(0xff, &dp6_ptr->io.irqdel);
1381         if (prot_ver != PROTOCOL_VERSION) {
1382             printk("GDT-PCI: Illegal protocol version\n");
1383             gdth_munmap(ha->brd);
1384             return 0;
1385         }
1386
1387         ha->type = GDT_PCI;
1388         ha->ic_all_size = sizeof(dp6_ptr->u);
1389         
1390         /* special command to controller BIOS */
1391         gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[0]);
1392         gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[1]);
1393         gdth_writel(0x01, &dp6_ptr->u.ic.S_Info[2]);
1394         gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[3]);
1395         gdth_writeb(0xfe, &dp6_ptr->u.ic.S_Cmd_Indx);
1396         gdth_writeb(0, &dp6_ptr->io.event);
1397         retries = INIT_RETRIES;
1398         gdth_delay(20);
1399         while (gdth_readb(&dp6_ptr->u.ic.S_Status) != 0xfe) {
1400             if (--retries == 0) {
1401                 printk("GDT-PCI: Initialization error\n");
1402                 gdth_munmap(ha->brd);
1403                 return 0;
1404             }
1405             gdth_delay(1);
1406         }
1407         gdth_writeb(0, &dp6_ptr->u.ic.S_Status);
1408         gdth_writeb(0xff, &dp6_ptr->io.irqdel);
1409
1410     } else if (ha->stype <= PCI_DEVICE_ID_VORTEX_GDT6555) { /* GDT6110, ... */
1411         ha->plx = (gdt6c_plx_regs *)pcistr->io;
1412         TRACE2(("init_pci_new() dpmem %lx irq %d\n",
1413             pcistr->dpmem,ha->irq));
1414         ha->brd = gdth_mmap(pcistr->dpmem, sizeof(gdt6c_dpram_str));
1415         if (ha->brd == NULL) {
1416             printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
1417             gdth_munmap(ha->brd);
1418             return 0;
1419         }
1420         /* check and reset interface area */
1421         dp6c_ptr = (gdt6c_dpram_str *)ha->brd;
1422         gdth_writel(DPMEM_MAGIC, &dp6c_ptr->u);
1423         if (gdth_readl(&dp6c_ptr->u) != DPMEM_MAGIC) {
1424             printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", 
1425                    pcistr->dpmem);
1426             found = FALSE;
1427             for (i = 0xC8000; i < 0xE8000; i += 0x4000) {
1428                 gdth_munmap(ha->brd);
1429                 ha->brd = gdth_mmap(i, sizeof(ushort)); 
1430                 if (ha->brd == NULL) {
1431                     printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
1432                     return 0;
1433                 }
1434                 if (gdth_readw(ha->brd) != 0xffff) {
1435                     TRACE2(("init_pci_plx() address 0x%x busy\n", i));
1436                     continue;
1437                 }
1438                 gdth_munmap(ha->brd);
1439 #if LINUX_VERSION_CODE >= 0x2015C
1440                 pci_write_config_dword(pcistr->pdev, 
1441                                        PCI_BASE_ADDRESS_2, i);
1442 #else
1443                 pcibios_write_config_dword(pcistr->bus, pcistr->device_fn,
1444                                            PCI_BASE_ADDRESS_2, i);
1445 #endif
1446                 ha->brd = gdth_mmap(i, sizeof(gdt6c_dpram_str)); 
1447                 if (ha->brd == NULL) {
1448                     printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
1449                     return 0;
1450                 }
1451                 dp6c_ptr = (gdt6c_dpram_str *)ha->brd;
1452                 gdth_writel(DPMEM_MAGIC, &dp6c_ptr->u);
1453                 if (gdth_readl(&dp6c_ptr->u) == DPMEM_MAGIC) {
1454                     printk("GDT-PCI: Use free address at 0x%x\n", i);
1455                     found = TRUE;
1456                     break;
1457                 }
1458             }   
1459             if (!found) {
1460                 printk("GDT-PCI: No free address found!\n");
1461                 gdth_munmap(ha->brd);
1462                 return 0;
1463             }
1464         }
1465         memset_io((char *)&dp6c_ptr->u,0,sizeof(dp6c_ptr->u));
1466         if (gdth_readl(&dp6c_ptr->u) != 0) {
1467             printk("GDT-PCI: Initialization error (DPMEM write error)\n");
1468             gdth_munmap(ha->brd);
1469             return 0;
1470         }
1471         
1472         /* disable board interrupts, deinit services */
1473         outb(0x00,PTR2USHORT(&ha->plx->control1));
1474         outb(0xff,PTR2USHORT(&ha->plx->edoor_reg));
1475         
1476         gdth_writeb(0x00, &dp6c_ptr->u.ic.S_Status);
1477         gdth_writeb(0x00, &dp6c_ptr->u.ic.Cmd_Index);
1478
1479         gdth_writel(pcistr->dpmem, &dp6c_ptr->u.ic.S_Info[0]);
1480         gdth_writeb(0xff, &dp6c_ptr->u.ic.S_Cmd_Indx);
1481
1482         outb(1,PTR2USHORT(&ha->plx->ldoor_reg));
1483
1484         retries = INIT_RETRIES;
1485         gdth_delay(20);
1486         while (gdth_readb(&dp6c_ptr->u.ic.S_Status) != 0xff) {
1487             if (--retries == 0) {
1488                 printk("GDT-PCI: Initialization error (DEINIT failed)\n");
1489                 gdth_munmap(ha->brd);
1490                 return 0;
1491             }
1492             gdth_delay(1);
1493         }
1494         prot_ver = (unchar)gdth_readl(&dp6c_ptr->u.ic.S_Info[0]);
1495         gdth_writeb(0, &dp6c_ptr->u.ic.Status);
1496         if (prot_ver != PROTOCOL_VERSION) {
1497             printk("GDT-PCI: Illegal protocol version\n");
1498             gdth_munmap(ha->brd);
1499             return 0;
1500         }
1501
1502         ha->type = GDT_PCINEW;
1503         ha->ic_all_size = sizeof(dp6c_ptr->u);
1504
1505         /* special command to controller BIOS */
1506         gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[0]);
1507         gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[1]);
1508         gdth_writel(0x01, &dp6c_ptr->u.ic.S_Info[2]);
1509         gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[3]);
1510         gdth_writeb(0xfe, &dp6c_ptr->u.ic.S_Cmd_Indx);
1511         
1512         outb(1,PTR2USHORT(&ha->plx->ldoor_reg));
1513
1514         retries = INIT_RETRIES;
1515         gdth_delay(20);
1516         while (gdth_readb(&dp6c_ptr->u.ic.S_Status) != 0xfe) {
1517             if (--retries == 0) {
1518                 printk("GDT-PCI: Initialization error\n");
1519                 gdth_munmap(ha->brd);
1520                 return 0;
1521             }
1522             gdth_delay(1);
1523         }
1524         gdth_writeb(0, &dp6c_ptr->u.ic.S_Status);
1525
1526     } else {                                            /* MPR */
1527         TRACE2(("init_pci_mpr() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq));
1528         ha->brd = gdth_mmap(pcistr->dpmem, sizeof(gdt6m_dpram_str));
1529         if (ha->brd == NULL) {
1530             printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
1531             return 0;
1532         }
1533
1534         /* manipulate config. space to enable DPMEM, start RP controller */
1535 #if LINUX_VERSION_CODE >= 0x20363
1536         pci_read_config_word(pcistr->pdev, PCI_COMMAND, &command);
1537         command |= 6;
1538         pci_write_config_word(pcistr->pdev, PCI_COMMAND, command);
1539         if (pci_resource_start(pcistr->pdev, 8) == 1UL)
1540             pci_resource_start(pcistr->pdev, 8) = 0UL;
1541         i = 0xFEFF0001UL;
1542         pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, i);
1543         gdth_delay(1);
1544         pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS,
1545                                pci_resource_start(pcistr->pdev, 8));
1546 #elif LINUX_VERSION_CODE >= 0x2015C
1547         pci_read_config_word(pcistr->pdev, PCI_COMMAND, &command);
1548         command |= 6;
1549         pci_write_config_word(pcistr->pdev, PCI_COMMAND, command);
1550         if (pcistr->pdev->rom_address == 1UL)
1551             pcistr->pdev->rom_address = 0UL;
1552         i = 0xFEFF0001UL;
1553         pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, i);
1554         gdth_delay(1);
1555         pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS,
1556                                pcistr->pdev->rom_address);
1557 #else
1558         pcibios_read_config_word(pcistr->bus, pcistr->device_fn,
1559                                  PCI_COMMAND, &command);
1560         command |= 6;
1561         pcibios_write_config_word(pcistr->bus, pcistr->device_fn, 
1562                                   PCI_COMMAND, command);
1563         pcibios_read_config_dword(pcistr->bus, pcistr->device_fn,
1564                                   PCI_ROM_ADDRESS, &rom_addr);
1565         if (rom_addr == 1UL)
1566             rom_addr = 0UL;
1567         i = 0xFEFF0001UL;
1568         pcibios_write_config_dword(pcistr->bus, pcistr->device_fn,
1569                                    PCI_ROM_ADDRESS, i);
1570         gdth_delay(1);
1571         pcibios_write_config_dword(pcistr->bus, pcistr->device_fn,
1572                                    PCI_ROM_ADDRESS, rom_addr);
1573 #endif
1574         
1575         /* Ensure that it is safe to access the non HW portions of DPMEM.
1576          * Aditional check needed for Xscale based RAID controllers */
1577         while( ((int)gdth_readb(&((gdt6m_dpram_str *)ha->brd)->i960r.sema0_reg) ) & 3 )
1578             gdth_delay(1);
1579         
1580         /* check and reset interface area */
1581         dp6m_ptr = (gdt6m_dpram_str *)ha->brd;
1582         gdth_writel(DPMEM_MAGIC, &dp6m_ptr->u);
1583         if (gdth_readl(&dp6m_ptr->u) != DPMEM_MAGIC) {
1584             printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", 
1585                    pcistr->dpmem);
1586             found = FALSE;
1587             for (i = 0xC8000; i < 0xE8000; i += 0x4000) {
1588                 gdth_munmap(ha->brd);
1589                 ha->brd = gdth_mmap(i, sizeof(ushort)); 
1590                 if (ha->brd == NULL) {
1591                     printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
1592                     return 0;
1593                 }
1594                 if (gdth_readw(ha->brd) != 0xffff) {
1595                     TRACE2(("init_pci_mpr() address 0x%x busy\n", i));
1596                     continue;
1597                 }
1598                 gdth_munmap(ha->brd);
1599 #if LINUX_VERSION_CODE >= 0x2015C
1600                 pci_write_config_dword(pcistr->pdev, 
1601                                        PCI_BASE_ADDRESS_0, i);
1602 #else
1603                 pcibios_write_config_dword(pcistr->bus, pcistr->device_fn,
1604                                            PCI_BASE_ADDRESS_0, i);
1605 #endif
1606                 ha->brd = gdth_mmap(i, sizeof(gdt6m_dpram_str)); 
1607                 if (ha->brd == NULL) {
1608                     printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
1609                     return 0;
1610                 }
1611                 dp6m_ptr = (gdt6m_dpram_str *)ha->brd;
1612                 gdth_writel(DPMEM_MAGIC, &dp6m_ptr->u);
1613                 if (gdth_readl(&dp6m_ptr->u) == DPMEM_MAGIC) {
1614                     printk("GDT-PCI: Use free address at 0x%x\n", i);
1615                     found = TRUE;
1616                     break;
1617                 }
1618             }   
1619             if (!found) {
1620                 printk("GDT-PCI: No free address found!\n");
1621                 gdth_munmap(ha->brd);
1622                 return 0;
1623             }
1624         }
1625         memset_io((char *)&dp6m_ptr->u,0,sizeof(dp6m_ptr->u));
1626         
1627         /* disable board interrupts, deinit services */
1628         gdth_writeb(gdth_readb(&dp6m_ptr->i960r.edoor_en_reg) | 4,
1629                     &dp6m_ptr->i960r.edoor_en_reg);
1630         gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg);
1631         gdth_writeb(0x00, &dp6m_ptr->u.ic.S_Status);
1632         gdth_writeb(0x00, &dp6m_ptr->u.ic.Cmd_Index);
1633
1634         gdth_writel(pcistr->dpmem, &dp6m_ptr->u.ic.S_Info[0]);
1635         gdth_writeb(0xff, &dp6m_ptr->u.ic.S_Cmd_Indx);
1636         gdth_writeb(1, &dp6m_ptr->i960r.ldoor_reg);
1637         retries = INIT_RETRIES;
1638         gdth_delay(20);
1639         while (gdth_readb(&dp6m_ptr->u.ic.S_Status) != 0xff) {
1640             if (--retries == 0) {
1641                 printk("GDT-PCI: Initialization error (DEINIT failed)\n");
1642                 gdth_munmap(ha->brd);
1643                 return 0;
1644             }
1645             gdth_delay(1);
1646         }
1647         prot_ver = (unchar)gdth_readl(&dp6m_ptr->u.ic.S_Info[0]);
1648         gdth_writeb(0, &dp6m_ptr->u.ic.S_Status);
1649         if (prot_ver != PROTOCOL_VERSION) {
1650             printk("GDT-PCI: Illegal protocol version\n");
1651             gdth_munmap(ha->brd);
1652             return 0;
1653         }
1654
1655         ha->type = GDT_PCIMPR;
1656         ha->ic_all_size = sizeof(dp6m_ptr->u);
1657         
1658         /* special command to controller BIOS */
1659         gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[0]);
1660         gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[1]);
1661         gdth_writel(0x01, &dp6m_ptr->u.ic.S_Info[2]);
1662         gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[3]);
1663         gdth_writeb(0xfe, &dp6m_ptr->u.ic.S_Cmd_Indx);
1664         gdth_writeb(1, &dp6m_ptr->i960r.ldoor_reg);
1665         retries = INIT_RETRIES;
1666         gdth_delay(20);
1667         while (gdth_readb(&dp6m_ptr->u.ic.S_Status) != 0xfe) {
1668             if (--retries == 0) {
1669                 printk("GDT-PCI: Initialization error\n");
1670                 gdth_munmap(ha->brd);
1671                 return 0;
1672             }
1673             gdth_delay(1);
1674         }
1675         gdth_writeb(0, &dp6m_ptr->u.ic.S_Status);
1676     }
1677
1678     return 1;
1679 }
1680
1681
1682 /* controller protocol functions */
1683
1684 GDTH_INITFUNC(static void, gdth_enable_int(int hanum))
1685 {
1686     gdth_ha_str *ha;
1687     ulong flags;
1688     gdt2_dpram_str *dp2_ptr;
1689     gdt6_dpram_str *dp6_ptr;
1690     gdt6m_dpram_str *dp6m_ptr;
1691
1692     TRACE(("gdth_enable_int() hanum %d\n",hanum));
1693     ha = HADATA(gdth_ctr_tab[hanum]);
1694     GDTH_LOCK_HA(ha, flags);
1695
1696     if (ha->type == GDT_EISA) {
1697         outb(0xff, ha->bmic + EDOORREG);
1698         outb(0xff, ha->bmic + EDENABREG);
1699         outb(0x01, ha->bmic + EINTENABREG);
1700     } else if (ha->type == GDT_ISA) {
1701         dp2_ptr = (gdt2_dpram_str *)ha->brd;
1702         gdth_writeb(1, &dp2_ptr->io.irqdel);
1703         gdth_writeb(0, &dp2_ptr->u.ic.Cmd_Index);
1704         gdth_writeb(1, &dp2_ptr->io.irqen);
1705     } else if (ha->type == GDT_PCI) {
1706         dp6_ptr = (gdt6_dpram_str *)ha->brd;
1707         gdth_writeb(1, &dp6_ptr->io.irqdel);
1708         gdth_writeb(0, &dp6_ptr->u.ic.Cmd_Index);
1709         gdth_writeb(1, &dp6_ptr->io.irqen);
1710     } else if (ha->type == GDT_PCINEW) {
1711         outb(0xff, PTR2USHORT(&ha->plx->edoor_reg));
1712         outb(0x03, PTR2USHORT(&ha->plx->control1));
1713     } else if (ha->type == GDT_PCIMPR) {
1714         dp6m_ptr = (gdt6m_dpram_str *)ha->brd;
1715         gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg);
1716         gdth_writeb(gdth_readb(&dp6m_ptr->i960r.edoor_en_reg) & ~4,
1717                     &dp6m_ptr->i960r.edoor_en_reg);
1718     }
1719     GDTH_UNLOCK_HA(ha, flags);
1720 }
1721
1722
1723 static int gdth_get_status(unchar *pIStatus,int irq)
1724 {
1725     register gdth_ha_str *ha;
1726     int i;
1727
1728     TRACE(("gdth_get_status() irq %d ctr_count %d\n",
1729            irq,gdth_ctr_count));
1730     
1731     *pIStatus = 0;
1732     for (i=0; i<gdth_ctr_count; ++i) {
1733         ha = HADATA(gdth_ctr_tab[i]);
1734         if (ha->irq != (unchar)irq)             /* check IRQ */
1735             continue;
1736         if (ha->type == GDT_EISA)
1737             *pIStatus = inb((ushort)ha->bmic + EDOORREG);
1738         else if (ha->type == GDT_ISA)
1739             *pIStatus =
1740                 gdth_readb(&((gdt2_dpram_str *)ha->brd)->u.ic.Cmd_Index);
1741         else if (ha->type == GDT_PCI)
1742             *pIStatus =
1743                 gdth_readb(&((gdt6_dpram_str *)ha->brd)->u.ic.Cmd_Index);
1744         else if (ha->type == GDT_PCINEW) 
1745             *pIStatus = inb(PTR2USHORT(&ha->plx->edoor_reg));
1746         else if (ha->type == GDT_PCIMPR)
1747             *pIStatus =
1748                 gdth_readb(&((gdt6m_dpram_str *)ha->brd)->i960r.edoor_reg);
1749    
1750         if (*pIStatus)                                  
1751             return i;                           /* board found */
1752     }
1753     return -1;
1754 }
1755                  
1756     
1757 static int gdth_test_busy(int hanum)
1758 {
1759     register gdth_ha_str *ha;
1760     register int gdtsema0 = 0;
1761
1762     TRACE(("gdth_test_busy() hanum %d\n",hanum));
1763     
1764     ha = HADATA(gdth_ctr_tab[hanum]);
1765     if (ha->type == GDT_EISA)
1766         gdtsema0 = (int)inb(ha->bmic + SEMA0REG);
1767     else if (ha->type == GDT_ISA)
1768         gdtsema0 = (int)gdth_readb(&((gdt2_dpram_str *)ha->brd)->u.ic.Sema0);
1769     else if (ha->type == GDT_PCI)
1770         gdtsema0 = (int)gdth_readb(&((gdt6_dpram_str *)ha->brd)->u.ic.Sema0);
1771     else if (ha->type == GDT_PCINEW) 
1772         gdtsema0 = (int)inb(PTR2USHORT(&ha->plx->sema0_reg));
1773     else if (ha->type == GDT_PCIMPR)
1774         gdtsema0 = 
1775             (int)gdth_readb(&((gdt6m_dpram_str *)ha->brd)->i960r.sema0_reg);
1776
1777     return (gdtsema0 & 1);
1778 }
1779
1780
1781 static int gdth_get_cmd_index(int hanum)
1782 {
1783     register gdth_ha_str *ha;
1784     int i;
1785
1786     TRACE(("gdth_get_cmd_index() hanum %d\n",hanum));
1787
1788     ha = HADATA(gdth_ctr_tab[hanum]);
1789     for (i=0; i<GDTH_MAXCMDS; ++i) {
1790         if (ha->cmd_tab[i].cmnd == UNUSED_CMND) {
1791             ha->cmd_tab[i].cmnd = ha->pccb->RequestBuffer;
1792             ha->cmd_tab[i].service = ha->pccb->Service;
1793             ha->pccb->CommandIndex = (ulong32)i+2;
1794             return (i+2);
1795         }
1796     }
1797     return 0;
1798 }
1799
1800
1801 static void gdth_set_sema0(int hanum)
1802 {
1803     register gdth_ha_str *ha;
1804
1805     TRACE(("gdth_set_sema0() hanum %d\n",hanum));
1806
1807     ha = HADATA(gdth_ctr_tab[hanum]);
1808     if (ha->type == GDT_EISA) {
1809         outb(1, ha->bmic + SEMA0REG);
1810     } else if (ha->type == GDT_ISA) {
1811         gdth_writeb(1, &((gdt2_dpram_str *)ha->brd)->u.ic.Sema0);
1812     } else if (ha->type == GDT_PCI) {
1813         gdth_writeb(1, &((gdt6_dpram_str *)ha->brd)->u.ic.Sema0);
1814     } else if (ha->type == GDT_PCINEW) { 
1815         outb(1, PTR2USHORT(&ha->plx->sema0_reg));
1816     } else if (ha->type == GDT_PCIMPR) {
1817         gdth_writeb(1, &((gdt6m_dpram_str *)ha->brd)->i960r.sema0_reg);
1818     }
1819 }
1820
1821
1822 static void gdth_copy_command(int hanum)
1823 {
1824     register gdth_ha_str *ha;
1825     register gdth_cmd_str *cmd_ptr;
1826     register gdt6m_dpram_str *dp6m_ptr;
1827     register gdt6c_dpram_str *dp6c_ptr;
1828     gdt6_dpram_str *dp6_ptr;
1829     gdt2_dpram_str *dp2_ptr;
1830     ushort cp_count,dp_offset,cmd_no;
1831     
1832     TRACE(("gdth_copy_command() hanum %d\n",hanum));
1833
1834     ha = HADATA(gdth_ctr_tab[hanum]);
1835     cp_count = ha->cmd_len;
1836     dp_offset= ha->cmd_offs_dpmem;
1837     cmd_no   = ha->cmd_cnt;
1838     cmd_ptr  = ha->pccb;
1839
1840     ++ha->cmd_cnt;                                                      
1841     if (ha->type == GDT_EISA)
1842         return;                                 /* no DPMEM, no copy */
1843
1844     /* set cpcount dword aligned */
1845     if (cp_count & 3)
1846         cp_count += (4 - (cp_count & 3));
1847
1848     ha->cmd_offs_dpmem += cp_count;
1849     
1850     /* set offset and service, copy command to DPMEM */
1851     if (ha->type == GDT_ISA) {
1852         dp2_ptr = (gdt2_dpram_str *)ha->brd;
1853         gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, 
1854                     &dp2_ptr->u.ic.comm_queue[cmd_no].offset);
1855         gdth_writew((ushort)cmd_ptr->Service, 
1856                     &dp2_ptr->u.ic.comm_queue[cmd_no].serv_id);
1857         memcpy_toio(&dp2_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count);
1858     } else if (ha->type == GDT_PCI) {
1859         dp6_ptr = (gdt6_dpram_str *)ha->brd;
1860         gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, 
1861                     &dp6_ptr->u.ic.comm_queue[cmd_no].offset);
1862         gdth_writew((ushort)cmd_ptr->Service, 
1863                     &dp6_ptr->u.ic.comm_queue[cmd_no].serv_id);
1864         memcpy_toio(&dp6_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count);
1865     } else if (ha->type == GDT_PCINEW) {
1866         dp6c_ptr = (gdt6c_dpram_str *)ha->brd;
1867         gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, 
1868                     &dp6c_ptr->u.ic.comm_queue[cmd_no].offset);
1869         gdth_writew((ushort)cmd_ptr->Service, 
1870                     &dp6c_ptr->u.ic.comm_queue[cmd_no].serv_id);
1871         memcpy_toio(&dp6c_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count);
1872     } else if (ha->type == GDT_PCIMPR) {
1873         dp6m_ptr = (gdt6m_dpram_str *)ha->brd;
1874         gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, 
1875                     &dp6m_ptr->u.ic.comm_queue[cmd_no].offset);
1876         gdth_writew((ushort)cmd_ptr->Service, 
1877                     &dp6m_ptr->u.ic.comm_queue[cmd_no].serv_id);
1878         memcpy_toio(&dp6m_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count);
1879     }
1880 }
1881
1882
1883 static void gdth_release_event(int hanum)
1884 {
1885     register gdth_ha_str *ha;
1886
1887     TRACE(("gdth_release_event() hanum %d\n",hanum));
1888     ha = HADATA(gdth_ctr_tab[hanum]);
1889
1890 #ifdef GDTH_STATISTICS
1891     {
1892         ulong32 i,j;
1893         for (i=0,j=0; j<GDTH_MAXCMDS; ++j) {
1894             if (ha->cmd_tab[j].cmnd != UNUSED_CMND)
1895                 ++i;
1896         }
1897         if (max_index < i) {
1898             max_index = i;
1899             TRACE3(("GDT: max_index = %d\n",(ushort)i));
1900         }
1901     }
1902 #endif
1903
1904     if (ha->pccb->OpCode == GDT_INIT)
1905         ha->pccb->Service |= 0x80;
1906
1907     if (ha->type == GDT_EISA) {
1908         if (ha->pccb->OpCode == GDT_INIT)               /* store DMA buffer */
1909             outl(ha->ccb_phys, ha->bmic + MAILBOXREG);
1910         outb(ha->pccb->Service, ha->bmic + LDOORREG);
1911     } else if (ha->type == GDT_ISA) {
1912         gdth_writeb(0, &((gdt2_dpram_str *)ha->brd)->io.event);
1913     } else if (ha->type == GDT_PCI) {
1914         gdth_writeb(0, &((gdt6_dpram_str *)ha->brd)->io.event);
1915     } else if (ha->type == GDT_PCINEW) { 
1916         outb(1, PTR2USHORT(&ha->plx->ldoor_reg));
1917     } else if (ha->type == GDT_PCIMPR) {
1918         gdth_writeb(1, &((gdt6m_dpram_str *)ha->brd)->i960r.ldoor_reg);
1919     }
1920 }
1921
1922     
1923 static int gdth_wait(int hanum,int index,ulong32 time)
1924 {
1925     gdth_ha_str *ha;
1926     int answer_found = FALSE;
1927
1928     TRACE(("gdth_wait() hanum %d index %d time %d\n",hanum,index,time));
1929
1930     ha = HADATA(gdth_ctr_tab[hanum]);
1931     if (index == 0)
1932         return 1;                               /* no wait required */
1933
1934     gdth_from_wait = TRUE;
1935     do {
1936         gdth_interrupt((int)ha->irq,ha,NULL);
1937         if (wait_hanum==hanum && wait_index==index) {
1938             answer_found = TRUE;
1939             break;
1940         }
1941         gdth_delay(1);
1942     } while (--time);
1943     gdth_from_wait = FALSE;
1944     
1945     while (gdth_test_busy(hanum))
1946         gdth_delay(0);
1947
1948     return (answer_found);
1949 }
1950
1951
1952 static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1,
1953                              ulong32 p2,ulong32 p3)
1954 {
1955     register gdth_ha_str *ha;
1956     register gdth_cmd_str *cmd_ptr;
1957     int retries,index;
1958
1959     TRACE2(("gdth_internal_cmd() service %d opcode %d\n",service,opcode));
1960
1961     ha = HADATA(gdth_ctr_tab[hanum]);
1962     cmd_ptr = ha->pccb;
1963     memset((char*)cmd_ptr,0,sizeof(gdth_cmd_str));
1964
1965     /* make command  */
1966     for (retries = INIT_RETRIES;;) {
1967         cmd_ptr->Service          = service;
1968         cmd_ptr->RequestBuffer    = INTERNAL_CMND;
1969         if (!(index=gdth_get_cmd_index(hanum))) {
1970             TRACE(("GDT: No free command index found\n"));
1971             return 0;
1972         }
1973         gdth_set_sema0(hanum);
1974         cmd_ptr->OpCode           = opcode;
1975         cmd_ptr->BoardNode        = LOCALBOARD;
1976         if (service == CACHESERVICE) {
1977             if (opcode == GDT_IOCTL) {
1978                 cmd_ptr->u.ioctl.subfunc = p1;
1979                 cmd_ptr->u.ioctl.channel = p2;
1980                 cmd_ptr->u.ioctl.param_size = (ushort)p3;
1981                 cmd_ptr->u.ioctl.p_param = ha->scratch_phys;
1982             } else {
1983                 cmd_ptr->u.cache.DeviceNo = (ushort)p1;
1984                 cmd_ptr->u.cache.BlockNo  = p2;
1985             }
1986         } else if (service == SCSIRAWSERVICE) {
1987             cmd_ptr->u.raw.direction  = p1;
1988             cmd_ptr->u.raw.bus        = (unchar)p2;
1989             cmd_ptr->u.raw.target     = (unchar)p3;
1990             cmd_ptr->u.raw.lun        = (unchar)(p3 >> 8);
1991         } else if (service == SCREENSERVICE) {
1992             if (opcode == GDT_REALTIME) {
1993                 *(ulong32 *)&cmd_ptr->u.screen.su.data[0] = p1;
1994                 *(ulong32 *)&cmd_ptr->u.screen.su.data[4] = p2;
1995                 *(ulong32 *)&cmd_ptr->u.screen.su.data[8] = p3;
1996             }
1997         }
1998         ha->cmd_len          = sizeof(gdth_cmd_str);
1999         ha->cmd_offs_dpmem   = 0;
2000         ha->cmd_cnt          = 0;
2001         gdth_copy_command(hanum);
2002         gdth_release_event(hanum);
2003         gdth_delay(20);
2004         if (!gdth_wait(hanum,index,INIT_TIMEOUT)) {
2005             printk("GDT: Initialization error (timeout service %d)\n",service);
2006             return 0;
2007         }
2008         if (ha->status != S_BSY || --retries == 0)
2009             break;
2010         gdth_delay(1);   
2011     }   
2012     
2013     return (ha->status != S_OK ? 0:1);
2014 }
2015     
2016
2017 /* search for devices */
2018
2019 GDTH_INITFUNC(static int, gdth_search_drives(int hanum))
2020 {
2021     register gdth_ha_str *ha;
2022     ushort cdev_cnt, i;
2023     ulong32 bus_no, drv_cnt, drv_no, j;
2024     gdth_getch_str *chn;
2025     gdth_drlist_str *drl;
2026     gdth_iochan_str *ioc;
2027     gdth_raw_iochan_str *iocr;
2028     gdth_arcdl_str *alst;
2029     gdth_alist_str *alst2;
2030     gdth_oem_str_ioctl *oemstr;
2031
2032 #ifdef GDTH_RTC
2033     unchar rtc[12];
2034     ulong flags;
2035 #endif     
2036    
2037     TRACE(("gdth_search_drives() hanum %d\n",hanum));
2038     ha = HADATA(gdth_ctr_tab[hanum]);
2039
2040     /* initialize controller services, at first: screen service */
2041     if (!gdth_internal_cmd(hanum,SCREENSERVICE,GDT_INIT,0,0,0)) {
2042         printk("GDT: Initialization error screen service (code %d)\n",
2043                ha->status);
2044         return 0;
2045     }
2046     TRACE2(("gdth_search_drives(): SCREENSERVICE initialized\n"));
2047
2048 #ifdef GDTH_RTC
2049     /* read realtime clock info, send to controller */
2050     /* 1. wait for the falling edge of update flag */
2051     spin_lock_irqsave(&rtc_lock, flags);
2052     for (j = 0; j < 1000000; ++j)
2053         if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
2054             break;
2055     for (j = 0; j < 1000000; ++j)
2056         if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
2057             break;
2058     /* 2. read info */
2059     do {
2060         for (j = 0; j < 12; ++j) 
2061             rtc[j] = CMOS_READ(j);
2062     } while (rtc[0] != CMOS_READ(0));
2063     spin_unlock_irqrestore(&rtc_lock, flags);
2064     TRACE2(("gdth_search_drives(): RTC: %x/%x/%x\n",*(ulong32 *)&rtc[0],
2065             *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]));
2066     /* 3. send to controller firmware */
2067     gdth_internal_cmd(hanum,SCREENSERVICE,GDT_REALTIME, *(ulong32 *)&rtc[0],
2068                       *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]);
2069 #endif  
2070  
2071     /* unfreeze all IOs */
2072     gdth_internal_cmd(hanum,CACHESERVICE,GDT_UNFREEZE_IO,0,0,0);
2073  
2074     /* initialize cache service */
2075     if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_INIT,LINUX_OS,0,0)) {
2076         printk("GDT: Initialization error cache service (code %d)\n",
2077                ha->status);
2078         return 0;
2079     }
2080     TRACE2(("gdth_search_drives(): CACHESERVICE initialized\n"));
2081     cdev_cnt = (ushort)ha->info;
2082     ha->fw_vers = ha->service;
2083
2084     /* detect number of buses - try new IOCTL */
2085     iocr = (gdth_raw_iochan_str *)ha->pscratch;
2086     iocr->hdr.version        = 0xffffffff;
2087     iocr->hdr.list_entries   = MAXBUS;
2088     iocr->hdr.first_chan     = 0;
2089     iocr->hdr.last_chan      = MAXBUS-1;
2090     iocr->hdr.list_offset    = GDTOFFSOF(gdth_raw_iochan_str, list[0]);
2091     if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,IOCHAN_RAW_DESC,
2092                           INVALID_CHANNEL,sizeof(gdth_raw_iochan_str))) {
2093         TRACE2(("IOCHAN_RAW_DESC supported!\n"));
2094         ha->bus_cnt = iocr->hdr.chan_count;
2095         for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) {
2096             if (iocr->list[bus_no].proc_id < MAXID)
2097                 ha->bus_id[bus_no] = iocr->list[bus_no].proc_id;
2098             else
2099                 ha->bus_id[bus_no] = 0xff;
2100         }
2101     } else {
2102         /* old method */
2103         chn = (gdth_getch_str *)ha->pscratch;
2104         for (bus_no = 0; bus_no < MAXBUS; ++bus_no) {
2105             chn->channel_no = bus_no;
2106             if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,
2107                                    SCSI_CHAN_CNT | L_CTRL_PATTERN,
2108                                    IO_CHANNEL | INVALID_CHANNEL,
2109                                    sizeof(gdth_getch_str))) {
2110                 if (bus_no == 0) {
2111                     printk("GDT: Error detecting channel count (0x%x)\n",
2112                            ha->status);
2113                     return 0;
2114                 }
2115                 break;
2116             }
2117             if (chn->siop_id < MAXID)
2118                 ha->bus_id[bus_no] = chn->siop_id;
2119             else
2120                 ha->bus_id[bus_no] = 0xff;
2121         }       
2122         ha->bus_cnt = (unchar)bus_no;
2123     }
2124     TRACE2(("gdth_search_drives() %d channels\n",ha->bus_cnt));
2125
2126     /* read cache configuration */
2127     if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,CACHE_INFO,
2128                            INVALID_CHANNEL,sizeof(gdth_cinfo_str))) {
2129         printk("GDT: Initialization error cache service (code %d)\n",
2130                ha->status);
2131         return 0;
2132     }
2133     ha->cpar = ((gdth_cinfo_str *)ha->pscratch)->cpar;
2134     TRACE2(("gdth_search_drives() cinfo: vs %x sta %d str %d dw %d b %d\n",
2135             ha->cpar.version,ha->cpar.state,ha->cpar.strategy,
2136             ha->cpar.write_back,ha->cpar.block_size));
2137
2138     /* read board info and features */
2139     ha->more_proc = FALSE;
2140     if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,BOARD_INFO,
2141                           INVALID_CHANNEL,sizeof(gdth_binfo_str))) {
2142         memcpy(&ha->binfo, (gdth_binfo_str *)ha->pscratch,
2143                sizeof(gdth_binfo_str));
2144         if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,BOARD_FEATURES,
2145                               INVALID_CHANNEL,sizeof(gdth_bfeat_str))) {
2146             TRACE2(("BOARD_INFO/BOARD_FEATURES supported\n"));
2147             ha->bfeat = *(gdth_bfeat_str *)ha->pscratch;
2148             ha->more_proc = TRUE;
2149         }
2150     } else {
2151         TRACE2(("BOARD_INFO requires firmware >= 1.10/2.08\n"));
2152         strcpy(ha->binfo.type_string, gdth_ctr_name(hanum));
2153     }
2154     TRACE2(("Controller name: %s\n",ha->binfo.type_string));
2155
2156     /* read more informations */
2157     if (ha->more_proc) {
2158         /* physical drives, channel addresses */
2159         ioc = (gdth_iochan_str *)ha->pscratch;
2160         ioc->hdr.version        = 0xffffffff;
2161         ioc->hdr.list_entries   = MAXBUS;
2162         ioc->hdr.first_chan     = 0;
2163         ioc->hdr.last_chan      = MAXBUS-1;
2164         ioc->hdr.list_offset    = GDTOFFSOF(gdth_iochan_str, list[0]);
2165         if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,IOCHAN_DESC,
2166                               INVALID_CHANNEL,sizeof(gdth_iochan_str))) {
2167             for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) {
2168                 ha->raw[bus_no].address = ioc->list[bus_no].address;
2169                 ha->raw[bus_no].local_no = ioc->list[bus_no].local_no;
2170             }
2171         } else {
2172             for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) {
2173                 ha->raw[bus_no].address = IO_CHANNEL;
2174                 ha->raw[bus_no].local_no = bus_no;
2175             }
2176         }
2177         for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) {
2178             chn = (gdth_getch_str *)ha->pscratch;
2179             chn->channel_no = ha->raw[bus_no].local_no;
2180             if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,
2181                                   SCSI_CHAN_CNT | L_CTRL_PATTERN,
2182                                   ha->raw[bus_no].address | INVALID_CHANNEL,
2183                                   sizeof(gdth_getch_str))) {
2184                 ha->raw[bus_no].pdev_cnt = chn->drive_cnt;
2185                 TRACE2(("Channel %d: %d phys. drives\n",
2186                         bus_no,chn->drive_cnt));
2187             }
2188             if (ha->raw[bus_no].pdev_cnt > 0) {
2189                 drl = (gdth_drlist_str *)ha->pscratch;
2190                 drl->sc_no = ha->raw[bus_no].local_no;
2191                 drl->sc_cnt = ha->raw[bus_no].pdev_cnt;
2192                 if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,
2193                                       SCSI_DR_LIST | L_CTRL_PATTERN,
2194                                       ha->raw[bus_no].address | INVALID_CHANNEL,
2195                                       sizeof(gdth_drlist_str))) {
2196                     for (j = 0; j < ha->raw[bus_no].pdev_cnt; ++j) 
2197                         ha->raw[bus_no].id_list[j] = drl->sc_list[j];
2198                 } else {
2199                     ha->raw[bus_no].pdev_cnt = 0;
2200                 }
2201             }
2202         }
2203
2204         /* logical drives */
2205         if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,CACHE_DRV_CNT,
2206                               INVALID_CHANNEL,sizeof(ulong32))) {
2207             drv_cnt = *(ulong32 *)ha->pscratch;
2208             if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,CACHE_DRV_LIST,
2209                                   INVALID_CHANNEL,drv_cnt * sizeof(ulong32))) {
2210                 for (j = 0; j < drv_cnt; ++j) {
2211                     drv_no = ((ulong32 *)ha->pscratch)[j];
2212                     if (drv_no < MAX_LDRIVES) {
2213                         ha->hdr[drv_no].is_logdrv = TRUE;
2214                         TRACE2(("Drive %d is log. drive\n",drv_no));
2215                     }
2216                 }
2217             }
2218             alst = (gdth_arcdl_str *)ha->pscratch;
2219             alst->entries_avail = MAX_LDRIVES;
2220             alst->first_entry = 0;
2221             alst->list_offset = GDTOFFSOF(gdth_arcdl_str, list[0]);
2222             if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,
2223                                   ARRAY_DRV_LIST2 | LA_CTRL_PATTERN, 
2224                                   INVALID_CHANNEL, sizeof(gdth_arcdl_str) +
2225                                   (alst->entries_avail-1) * sizeof(gdth_alist_str))) { 
2226                 for (j = 0; j < alst->entries_init; ++j) {
2227                     ha->hdr[j].is_arraydrv = alst->list[j].is_arrayd;
2228                     ha->hdr[j].is_master = alst->list[j].is_master;
2229                     ha->hdr[j].is_parity = alst->list[j].is_parity;
2230                     ha->hdr[j].is_hotfix = alst->list[j].is_hotfix;
2231                     ha->hdr[j].master_no = alst->list[j].cd_handle;
2232                 }
2233             } else if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,
2234                                          ARRAY_DRV_LIST | LA_CTRL_PATTERN,
2235                                          0, 35 * sizeof(gdth_alist_str))) {
2236                 for (j = 0; j < 35; ++j) {
2237                     alst2 = &((gdth_alist_str *)ha->pscratch)[j];
2238                     ha->hdr[j].is_arraydrv = alst2->is_arrayd;
2239                     ha->hdr[j].is_master = alst2->is_master;
2240                     ha->hdr[j].is_parity = alst2->is_parity;
2241                     ha->hdr[j].is_hotfix = alst2->is_hotfix;
2242                     ha->hdr[j].master_no = alst2->cd_handle;
2243                 }
2244             }
2245         }
2246     }       
2247                                   
2248     /* initialize raw service */
2249     if (!gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_INIT,0,0,0)) {
2250         printk("GDT: Initialization error raw service (code %d)\n",
2251                ha->status);
2252         return 0;
2253     }
2254     TRACE2(("gdth_search_drives(): RAWSERVICE initialized\n"));
2255
2256     /* set/get features raw service (scatter/gather) */
2257     if (gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_SET_FEAT,SCATTER_GATHER,
2258                           0,0)) {
2259         TRACE2(("gdth_search_drives(): set features RAWSERVICE OK\n"));
2260         if (gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_GET_FEAT,0,0,0)) {
2261             TRACE2(("gdth_search_dr(): get feat RAWSERVICE %d\n",
2262                     ha->info));
2263             ha->raw_feat = (ushort)ha->info;
2264         }
2265     } 
2266
2267     /* set/get features cache service (equal to raw service) */
2268     if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_SET_FEAT,0,
2269                           SCATTER_GATHER,0)) {
2270         TRACE2(("gdth_search_drives(): set features CACHESERVICE OK\n"));
2271         if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_GET_FEAT,0,0,0)) {
2272             TRACE2(("gdth_search_dr(): get feat CACHESERV. %d\n",
2273                     ha->info));
2274             ha->cache_feat = (ushort)ha->info;
2275         }
2276     }
2277
2278     /* reserve drives for raw service */
2279     if (reserve_mode != 0) {
2280         gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_RESERVE_ALL,
2281                           reserve_mode == 1 ? 1 : 3, 0, 0);
2282         TRACE2(("gdth_search_drives(): RESERVE_ALL code %d\n", 
2283                 ha->status));
2284     }
2285     for (i = 0; i < MAX_RES_ARGS; i += 4) {
2286         if (reserve_list[i] == hanum && reserve_list[i+1] < ha->bus_cnt && 
2287             reserve_list[i+2] < ha->tid_cnt && reserve_list[i+3] < MAXLUN) {
2288             TRACE2(("gdth_search_drives(): reserve ha %d bus %d id %d lun %d\n",
2289                     reserve_list[i], reserve_list[i+1],
2290                     reserve_list[i+2], reserve_list[i+3]));
2291             if (!gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_RESERVE,0,
2292                                    reserve_list[i+1], reserve_list[i+2] | 
2293                                    (reserve_list[i+3] << 8))) {
2294                 printk("GDT: Error raw service (RESERVE, code %d)\n",
2295                        ha->status);
2296              }
2297         }
2298     }
2299
2300     /* Determine OEM string using IOCTL */
2301     oemstr = (gdth_oem_str_ioctl *)ha->pscratch;
2302     oemstr->params.ctl_version = 0x01;
2303     oemstr->params.buffer_size = sizeof(oemstr->text);
2304     if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,
2305                           CACHE_READ_OEM_STRING_RECORD,INVALID_CHANNEL,
2306                           sizeof(gdth_oem_str_ioctl))) {
2307         TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD OK\n"));
2308         printk("GDT CTR%d Vendor: %s\n",hanum,oemstr->text.oem_company_name);
2309         /* Save the Host Drive inquiry data */
2310         strlcpy(ha->oem_name,oemstr->text.scsi_host_drive_inquiry_vendor_id,
2311                 sizeof(ha->oem_name));
2312     } else {
2313         /* Old method, based on PCI ID */
2314         TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD failed\n"));
2315         if (ha->oem_id == OEM_ID_INTEL)
2316             strlcpy(ha->oem_name,"Intel  ", sizeof(ha->oem_name));
2317         else
2318             strlcpy(ha->oem_name,"ICP    ", sizeof(ha->oem_name));
2319     }
2320
2321     /* scanning for host drives */
2322     for (i = 0; i < cdev_cnt; ++i) 
2323         gdth_analyse_hdrive(hanum,i);
2324     
2325     TRACE(("gdth_search_drives() OK\n"));
2326     return 1;
2327 }
2328
2329 static int gdth_analyse_hdrive(int hanum,ushort hdrive)
2330 {
2331     register gdth_ha_str *ha;
2332     int drv_cyls, drv_hds, drv_secs;
2333
2334     TRACE(("gdth_analyse_hdrive() hanum %d drive %d\n",hanum,hdrive));
2335     if (hdrive >= MAX_HDRIVES)
2336         return 0;
2337     ha = HADATA(gdth_ctr_tab[hanum]);
2338
2339     if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_INFO,hdrive,0,0)) 
2340         return 0;
2341     ha->hdr[hdrive].present = TRUE;
2342     ha->hdr[hdrive].size = ha->info;
2343
2344     /* evaluate mapping (sectors per head, heads per cylinder) */
2345     ha->hdr[hdrive].size &= ~SECS32;
2346     if (ha->info2 == 0) {
2347         gdth_eval_mapping(ha->hdr[hdrive].size,&drv_cyls,&drv_hds,&drv_secs);
2348     } else {
2349         drv_hds = ha->info2 & 0xff;
2350         drv_secs = (ha->info2 >> 8) & 0xff;
2351         drv_cyls = ha->hdr[hdrive].size /drv_hds/drv_secs;
2352     }
2353     ha->hdr[hdrive].heads = (unchar)drv_hds;
2354     ha->hdr[hdrive].secs  = (unchar)drv_secs;
2355     /* round size */
2356     ha->hdr[hdrive].size  = drv_cyls * drv_hds * drv_secs;
2357     TRACE2(("gdth_search_dr() cdr. %d size %d hds %d scs %d\n",
2358             hdrive,ha->hdr[hdrive].size,drv_hds,drv_secs));
2359             
2360     /* get informations about device */
2361     if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_DEVTYPE,hdrive,0,0)) {
2362         TRACE2(("gdth_search_dr() cache drive %d devtype %d\n",
2363                 hdrive,ha->info));
2364         ha->hdr[hdrive].devtype = (ushort)ha->info;
2365     }
2366
2367     /* cluster info */
2368     if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_CLUST_INFO,hdrive,0,0)) {
2369         TRACE2(("gdth_search_dr() cache drive %d cluster info %d\n",
2370                 hdrive,ha->info));
2371         if (!shared_access)
2372             ha->hdr[hdrive].cluster_type = (unchar)ha->info;
2373     }
2374
2375     /* R/W attributes */
2376     if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_RW_ATTRIBS,hdrive,0,0)) {
2377         TRACE2(("gdth_search_dr() cache drive %d r/w attrib. %d\n",
2378                 hdrive,ha->info));
2379         ha->hdr[hdrive].rw_attribs = (unchar)ha->info;
2380     }
2381
2382     return 1;
2383 }
2384
2385
2386 /* command queueing/sending functions */
2387
2388 static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority)
2389 {
2390     register gdth_ha_str *ha;
2391     register Scsi_Cmnd *pscp;
2392     register Scsi_Cmnd *nscp;
2393     ulong flags;
2394     unchar b, t;
2395
2396     TRACE(("gdth_putq() priority %d\n",priority));
2397     ha = HADATA(gdth_ctr_tab[hanum]);
2398     GDTH_LOCK_HA(ha, flags);
2399
2400     scp->SCp.this_residual = (int)priority;
2401 #if LINUX_VERSION_CODE >= 0x02053C
2402     b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
2403     t = scp->device->id;
2404 #else
2405     b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
2406     t = scp->target;
2407 #endif
2408 #if LINUX_VERSION_CODE >= 0x010300
2409     if (priority >= DEFAULT_PRI) {
2410         if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
2411             (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) {
2412             TRACE2(("gdth_putq(): locked IO -> update_timeout()\n"));
2413             scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0);
2414         }
2415     }
2416 #endif
2417
2418     if (ha->req_first==NULL) {
2419         ha->req_first = scp;                    /* queue was empty */
2420         scp->SCp.ptr = NULL;
2421     } else {                                    /* queue not empty */
2422         pscp = ha->req_first;
2423         nscp = (Scsi_Cmnd *)pscp->SCp.ptr;
2424         /* priority: 0-highest,..,0xff-lowest */
2425         while (nscp && (unchar)nscp->SCp.this_residual <= priority) {
2426             pscp = nscp;
2427             nscp = (Scsi_Cmnd *)pscp->SCp.ptr;
2428         }
2429         pscp->SCp.ptr = (char *)scp;
2430         scp->SCp.ptr  = (char *)nscp;
2431     }
2432     GDTH_UNLOCK_HA(ha, flags);
2433
2434 #ifdef GDTH_STATISTICS
2435     flags = 0;
2436     for (nscp=ha->req_first; nscp; nscp=(Scsi_Cmnd*)nscp->SCp.ptr)
2437         ++flags;
2438     if (max_rq < flags) {
2439         max_rq = flags;
2440         TRACE3(("GDT: max_rq = %d\n",(ushort)max_rq));
2441     }
2442 #endif
2443 }
2444
2445 static void gdth_next(int hanum)
2446 {
2447     register gdth_ha_str *ha;
2448     register Scsi_Cmnd *pscp;
2449     register Scsi_Cmnd *nscp;
2450     unchar b, t, l, firsttime;
2451     unchar this_cmd, next_cmd;
2452     ulong flags = 0;
2453     int cmd_index;
2454
2455     TRACE(("gdth_next() hanum %d\n",hanum));
2456     ha = HADATA(gdth_ctr_tab[hanum]);
2457     if (!gdth_polling) 
2458         GDTH_LOCK_HA(ha, flags);
2459
2460     ha->cmd_cnt = ha->cmd_offs_dpmem = 0;
2461     this_cmd = firsttime = TRUE;
2462     next_cmd = gdth_polling ? FALSE:TRUE;
2463     cmd_index = 0;
2464
2465     for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) {
2466         if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr)
2467             pscp = (Scsi_Cmnd *)pscp->SCp.ptr;
2468 #if LINUX_VERSION_CODE >= 0x02053C
2469         b = virt_ctr ? NUMDATA(nscp->device->host)->busnum : nscp->device->channel;
2470         t = nscp->device->id;
2471         l = nscp->device->lun;
2472 #else
2473         b = virt_ctr ? NUMDATA(nscp->host)->busnum : nscp->channel;
2474         t = nscp->target;
2475         l = nscp->lun;
2476 #endif
2477         if (nscp->SCp.this_residual >= DEFAULT_PRI) {
2478             if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
2479                 (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) 
2480                 continue;
2481         }
2482
2483         if (firsttime) {
2484             if (gdth_test_busy(hanum)) {        /* controller busy ? */
2485                 TRACE(("gdth_next() controller %d busy !\n",hanum));
2486                 if (!gdth_polling) {
2487                     GDTH_UNLOCK_HA(ha, flags);
2488                     return;
2489                 }
2490                 while (gdth_test_busy(hanum))
2491                     gdth_delay(1);
2492             }   
2493             firsttime = FALSE;
2494         }
2495
2496 #if LINUX_VERSION_CODE >= 0x010300
2497         if (nscp->done != gdth_scsi_done || nscp->cmnd[0] != 0xff) 
2498 #endif
2499         {
2500         if (nscp->SCp.phase == -1) {
2501             nscp->SCp.phase = CACHESERVICE;           /* default: cache svc. */ 
2502             if (nscp->cmnd[0] == TEST_UNIT_READY) {
2503                 TRACE2(("TEST_UNIT_READY Bus %d Id %d LUN %d\n", 
2504                         b, t, l));
2505                 /* TEST_UNIT_READY -> set scan mode */
2506                 if ((ha->scan_mode & 0x0f) == 0) {
2507                     if (b == 0 && t == 0 && l == 0) {
2508                         ha->scan_mode |= 1;
2509                         TRACE2(("Scan mode: 0x%x\n", ha->scan_mode));
2510                     }
2511                 } else if ((ha->scan_mode & 0x0f) == 1) {
2512                     if (b == 0 && ((t == 0 && l == 1) ||
2513                          (t == 1 && l == 0))) {
2514                         nscp->SCp.sent_command = GDT_SCAN_START;
2515                         nscp->SCp.phase = ((ha->scan_mode & 0x10 ? 1:0) << 8) 
2516                             | SCSIRAWSERVICE;
2517                         ha->scan_mode = 0x12;
2518                         TRACE2(("Scan mode: 0x%x (SCAN_START)\n", 
2519                                 ha->scan_mode));
2520                     } else {
2521                         ha->scan_mode &= 0x10;
2522                         TRACE2(("Scan mode: 0x%x\n", ha->scan_mode));
2523                     }                   
2524                 } else if (ha->scan_mode == 0x12) {
2525                     if (b == ha->bus_cnt && t == ha->tid_cnt-1) {
2526                         nscp->SCp.phase = SCSIRAWSERVICE;
2527                         nscp->SCp.sent_command = GDT_SCAN_END;
2528                         ha->scan_mode &= 0x10;
2529                         TRACE2(("Scan mode: 0x%x (SCAN_END)\n", 
2530                                 ha->scan_mode));
2531                     }
2532                 }
2533             }
2534             if (b == ha->virt_bus && nscp->cmnd[0] != INQUIRY &&
2535                 nscp->cmnd[0] != READ_CAPACITY && nscp->cmnd[0] != MODE_SENSE &&
2536                 (ha->hdr[t].cluster_type & CLUSTER_DRIVE)) {
2537                 /* always GDT_CLUST_INFO! */
2538                 nscp->SCp.sent_command = GDT_CLUST_INFO;
2539             }
2540         }
2541         }
2542
2543         if (nscp->SCp.sent_command != -1) {
2544             if ((nscp->SCp.phase & 0xff) == CACHESERVICE) {
2545                 if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t)))
2546                     this_cmd = FALSE;
2547                 next_cmd = FALSE;
2548             } else if ((nscp->SCp.phase & 0xff) == SCSIRAWSERVICE) {
2549                 if (!(cmd_index=gdth_fill_raw_cmd(hanum,nscp,BUS_L2P(ha,b))))
2550                     this_cmd = FALSE;
2551                 next_cmd = FALSE;
2552             } else {
2553                 memset((char*)nscp->sense_buffer,0,16);
2554                 nscp->sense_buffer[0] = 0x70;
2555                 nscp->sense_buffer[2] = NOT_READY;
2556                 nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
2557                 if (!nscp->SCp.have_data_in)
2558                     nscp->SCp.have_data_in++;
2559                 else {
2560                     if (!gdth_polling) 
2561                         GDTH_UNLOCK_HA(ha,flags);
2562                     /* io_request_lock already active ! */
2563                     nscp->scsi_done(nscp);
2564                     if (!gdth_polling) 
2565                         GDTH_LOCK_HA(ha,flags);
2566                 }
2567             }
2568         } else
2569
2570 #if LINUX_VERSION_CODE >= 0x010300
2571         if (nscp->done == gdth_scsi_done && nscp->cmnd[0] == 0xff) {
2572             if (!(cmd_index=gdth_special_cmd(hanum,nscp)))
2573                 this_cmd = FALSE;
2574             next_cmd = FALSE;
2575         } else
2576 #endif
2577         if (b != ha->virt_bus) {
2578             if (ha->raw[BUS_L2P(ha,b)].io_cnt[t] >= GDTH_MAX_RAW ||
2579                 !(cmd_index=gdth_fill_raw_cmd(hanum,nscp,BUS_L2P(ha,b)))) 
2580                 this_cmd = FALSE;
2581             else 
2582                 ha->raw[BUS_L2P(ha,b)].io_cnt[t]++;
2583         } else if (t >= MAX_HDRIVES || !ha->hdr[t].present || l != 0) {
2584             TRACE2(("Command 0x%x to bus %d id %d lun %d -> IGNORE\n",
2585                     nscp->cmnd[0], b, t, l));
2586             nscp->result = DID_BAD_TARGET << 16;
2587             if (!nscp->SCp.have_data_in)
2588                 nscp->SCp.have_data_in++;
2589             else {
2590                 if (!gdth_polling) 
2591                     GDTH_UNLOCK_HA(ha,flags);
2592                 /* io_request_lock already active ! */      
2593                 nscp->scsi_done(nscp);
2594                 if (!gdth_polling) 
2595                     GDTH_LOCK_HA(ha,flags);
2596             }
2597         } else {
2598             switch (nscp->cmnd[0]) {
2599               case TEST_UNIT_READY:
2600               case INQUIRY:
2601               case REQUEST_SENSE:
2602               case READ_CAPACITY:
2603               case VERIFY:
2604               case START_STOP:
2605               case MODE_SENSE:
2606                 TRACE(("cache cmd %x/%x/%x/%x/%x/%x\n",nscp->cmnd[0],
2607                        nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3],
2608                        nscp->cmnd[4],nscp->cmnd[5]));
2609                 if (ha->hdr[t].media_changed && nscp->cmnd[0] != INQUIRY) {
2610                     /* return UNIT_ATTENTION */
2611                     TRACE2(("cmd 0x%x target %d: UNIT_ATTENTION\n",
2612                              nscp->cmnd[0], t));
2613                     ha->hdr[t].media_changed = FALSE;
2614                     memset((char*)nscp->sense_buffer,0,16);
2615                     nscp->sense_buffer[0] = 0x70;
2616                     nscp->sense_buffer[2] = UNIT_ATTENTION;
2617                     nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
2618                     if (!nscp->SCp.have_data_in)
2619                         nscp->SCp.have_data_in++;
2620                     else {
2621                         if (!gdth_polling) 
2622                             GDTH_UNLOCK_HA(ha,flags);
2623                         /* io_request_lock already active ! */      
2624                         nscp->scsi_done(nscp);
2625                         if (!gdth_polling) 
2626                             GDTH_LOCK_HA(ha,flags);
2627                     }
2628                 } else if (gdth_internal_cache_cmd(hanum,nscp)) {
2629                     if (!gdth_polling) 
2630                         GDTH_UNLOCK_HA(ha,flags);
2631                     /* io_request_lock already active ! */      
2632                     nscp->scsi_done(nscp);
2633                     if (!gdth_polling) 
2634                         GDTH_LOCK_HA(ha,flags);
2635                 }
2636                 break;
2637
2638               case ALLOW_MEDIUM_REMOVAL:
2639                 TRACE(("cache cmd %x/%x/%x/%x/%x/%x\n",nscp->cmnd[0],
2640                        nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3],
2641                        nscp->cmnd[4],nscp->cmnd[5]));
2642                 if ( (nscp->cmnd[4]&1) && !(ha->hdr[t].devtype&1) ) {
2643                     TRACE(("Prevent r. nonremov. drive->do nothing\n"));
2644                     nscp->result = DID_OK << 16;
2645                     nscp->sense_buffer[0] = 0;
2646                     if (!nscp->SCp.have_data_in)
2647                         nscp->SCp.have_data_in++;
2648                     else {
2649                         if (!gdth_polling) 
2650                             GDTH_UNLOCK_HA(ha,flags);
2651                         /* io_request_lock already active ! */      
2652                         nscp->scsi_done(nscp);
2653                         if (!gdth_polling) 
2654                             GDTH_LOCK_HA(ha,flags);
2655                     }
2656                 } else {
2657                     nscp->cmnd[3] = (ha->hdr[t].devtype&1) ? 1:0;
2658                     TRACE(("Prevent/allow r. %d rem. drive %d\n",
2659                            nscp->cmnd[4],nscp->cmnd[3]));
2660                     if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t)))
2661                         this_cmd = FALSE;
2662                 }
2663                 break;
2664                 
2665               case RESERVE:
2666               case RELEASE:
2667                 TRACE2(("cache cmd %s\n",nscp->cmnd[0] == RESERVE ?
2668                         "RESERVE" : "RELEASE"));
2669                 if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t)))
2670                     this_cmd = FALSE;
2671                 break;
2672                 
2673               case READ_6:
2674               case WRITE_6:
2675               case READ_10:
2676               case WRITE_10:
2677                 if (ha->hdr[t].media_changed) {
2678                     /* return UNIT_ATTENTION */
2679                     TRACE2(("cmd 0x%x target %d: UNIT_ATTENTION\n",
2680                              nscp->cmnd[0], t));
2681                     ha->hdr[t].media_changed = FALSE;
2682                     memset((char*)nscp->sense_buffer,0,16);
2683                     nscp->sense_buffer[0] = 0x70;
2684                     nscp->sense_buffer[2] = UNIT_ATTENTION;
2685                     nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
2686                     if (!nscp->SCp.have_data_in)
2687                         nscp->SCp.have_data_in++;
2688                     else {
2689                         if (!gdth_polling) 
2690                             GDTH_UNLOCK_HA(ha,flags);
2691                         /* io_request_lock already active ! */      
2692                         nscp->scsi_done(nscp);
2693                         if (!gdth_polling) 
2694                             GDTH_LOCK_HA(ha,flags);
2695                     }
2696                 } else if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t)))
2697                     this_cmd = FALSE;
2698                 break;
2699
2700               default:
2701                 TRACE2(("cache cmd %x/%x/%x/%x/%x/%x unknown\n",nscp->cmnd[0],
2702                         nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3],
2703                         nscp->cmnd[4],nscp->cmnd[5]));
2704                 printk("GDT: Unknown SCSI command 0x%x to cache service !\n",
2705                        nscp->cmnd[0]);
2706                 nscp->result = DID_ABORT << 16;
2707                 if (!nscp->SCp.have_data_in)
2708                     nscp->SCp.have_data_in++;
2709                 else {
2710                     if (!gdth_polling) 
2711                         GDTH_UNLOCK_HA(ha,flags);
2712                     /* io_request_lock already active ! */  
2713                     nscp->scsi_done(nscp);
2714                     if (!gdth_polling) 
2715                         GDTH_LOCK_HA(ha,flags);
2716                 }
2717                 break;
2718             }
2719         }
2720
2721         if (!this_cmd)
2722             break;
2723         if (nscp == ha->req_first)
2724             ha->req_first = pscp = (Scsi_Cmnd *)nscp->SCp.ptr;
2725         else
2726             pscp->SCp.ptr = nscp->SCp.ptr;
2727         if (!next_cmd)
2728             break;
2729     }
2730
2731     if (ha->cmd_cnt > 0) {
2732         gdth_release_event(hanum);
2733     }
2734
2735     if (!gdth_polling) 
2736         GDTH_UNLOCK_HA(ha, flags);
2737
2738     if (gdth_polling && ha->cmd_cnt > 0) {
2739         if (!gdth_wait(hanum,cmd_index,POLL_TIMEOUT))
2740             printk("GDT: Controller %d: Command %d timed out !\n",
2741                    hanum,cmd_index);
2742     }
2743 }
2744     
2745 static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp,
2746                                     char *buffer,ushort count)
2747 {
2748     ushort cpcount,i;
2749     ushort cpsum,cpnow;
2750     struct scatterlist *sl;
2751     gdth_ha_str *ha;
2752     int sgcnt;
2753     char *address;
2754
2755     cpcount = count<=(ushort)scp->bufflen ? count:(ushort)scp->bufflen;
2756     ha = HADATA(gdth_ctr_tab[hanum]);
2757
2758     if (scp->use_sg) {
2759         sl = (struct scatterlist *)scp->request_buffer;
2760 #if LINUX_VERSION_CODE >= 0x020400
2761         sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,PCI_DMA_FROMDEVICE);
2762         for (i=0,cpsum=0; i<sgcnt; ++i,++sl) {
2763             cpnow = (ushort)sg_dma_len(sl);
2764             TRACE(("copy_internal() now %d sum %d count %d %d\n",
2765                           cpnow,cpsum,cpcount,(ushort)scp->bufflen));
2766             if (cpsum+cpnow > cpcount) 
2767                 cpnow = cpcount - cpsum;
2768             cpsum += cpnow;
2769             address = (char *)phys_to_virt(sg_dma_address(sl));
2770             memcpy(address,buffer,cpnow);
2771             if (cpsum == cpcount)
2772                 break;
2773             buffer += cpnow;
2774         }
2775         pci_unmap_sg(ha->pdev,scp->request_buffer,
2776                      scp->use_sg,PCI_DMA_FROMDEVICE);
2777 #else
2778         sgcnt = scp->use_sg;
2779         for (i=0,cpsum=0; i<sgcnt; ++i,++sl) {
2780             cpnow = (ushort)sl->length;
2781             TRACE(("copy_internal() now %d sum %d count %d %d\n",
2782                           cpnow,cpsum,cpcount,(ushort)scp->bufflen));
2783             if (cpsum+cpnow > cpcount) 
2784                cpnow = cpcount - cpsum;
2785             cpsum += cpnow;
2786             address = (char *)sl->address;
2787             memcpy(address,buffer,cpnow);
2788             if (cpsum == cpcount)
2789                 break;
2790             buffer += cpnow;
2791         }
2792 #endif
2793     } else {
2794         TRACE(("copy_internal() count %d\n",cpcount));
2795         memcpy((char*)scp->request_buffer,buffer,cpcount);
2796     }
2797 }
2798
2799 static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp)
2800 {
2801     register gdth_ha_str *ha;
2802     unchar t;
2803     gdth_inq_data inq;
2804     gdth_rdcap_data rdc;
2805     gdth_sense_data sd;
2806     gdth_modep_data mpd;
2807
2808     ha = HADATA(gdth_ctr_tab[hanum]);
2809 #if LINUX_VERSION_CODE >= 0x02053C
2810     t  = scp->device->id;
2811 #else
2812     t  = scp->target;
2813 #endif
2814     TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n",
2815            scp->cmnd[0],t));
2816
2817     switch (scp->cmnd[0]) {
2818       case TEST_UNIT_READY:
2819       case VERIFY:
2820       case START_STOP:
2821         TRACE2(("Test/Verify/Start hdrive %d\n",t));
2822         break;
2823
2824       case INQUIRY:
2825         TRACE2(("Inquiry hdrive %d devtype %d\n",
2826                 t,ha->hdr[t].devtype));
2827         inq.type_qual = (ha->hdr[t].devtype&4) ? TYPE_ROM:TYPE_DISK;
2828         /* you can here set all disks to removable, if you want to do
2829            a flush using the ALLOW_MEDIUM_REMOVAL command */
2830         inq.modif_rmb = 0x00;
2831         if ((ha->hdr[t].devtype & 1) ||
2832             (ha->hdr[t].cluster_type & CLUSTER_DRIVE))
2833             inq.modif_rmb = 0x80;
2834         inq.version   = 2;
2835         inq.resp_aenc = 2;
2836         inq.add_length= 32;
2837         strcpy(inq.vendor,ha->oem_name);
2838         sprintf(inq.product,"Host Drive  #%02d",t);
2839         strcpy(inq.revision,"   ");
2840         gdth_copy_internal_data(hanum,scp,(char*)&inq,sizeof(gdth_inq_data));
2841         break;
2842
2843       case REQUEST_SENSE:
2844         TRACE2(("Request sense hdrive %d\n",t));
2845         sd.errorcode = 0x70;
2846         sd.segno     = 0x00;
2847         sd.key       = NO_SENSE;
2848         sd.info      = 0;
2849         sd.add_length= 0;
2850         gdth_copy_internal_data(hanum,scp,(char*)&sd,sizeof(gdth_sense_data));
2851         break;
2852
2853       case MODE_SENSE:
2854         TRACE2(("Mode sense hdrive %d\n",t));
2855         memset((char*)&mpd,0,sizeof(gdth_modep_data));
2856         mpd.hd.data_length = sizeof(gdth_modep_data);
2857         mpd.hd.dev_par     = (ha->hdr[t].devtype&2) ? 0x80:0;
2858         mpd.hd.bd_length   = sizeof(mpd.bd);
2859         mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16;
2860         mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8;
2861         mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff);
2862         gdth_copy_internal_data(hanum,scp,(char*)&mpd,sizeof(gdth_modep_data));
2863         break;
2864
2865       case READ_CAPACITY:
2866         TRACE2(("Read capacity hdrive %d\n",t));
2867         rdc.last_block_no = ntohl(ha->hdr[t].size-1);
2868         rdc.block_length  = ntohl(SECTOR_SIZE);
2869         gdth_copy_internal_data(hanum,scp,(char*)&rdc,sizeof(gdth_rdcap_data));
2870         break;
2871
2872       default:
2873         TRACE2(("Internal cache cmd 0x%x unknown\n",scp->cmnd[0]));
2874         break;
2875     }
2876
2877     scp->result = DID_OK << 16;
2878     scp->sense_buffer[0] = 0;
2879
2880     if (!scp->SCp.have_data_in)
2881         scp->SCp.have_data_in++;
2882     else 
2883         return 1;
2884
2885     return 0;
2886 }
2887     
2888 static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive)
2889 {
2890     register gdth_ha_str *ha;
2891     register gdth_cmd_str *cmdp;
2892     struct scatterlist *sl;
2893     ushort i, cnt;
2894     ulong32 no, phys_addr;
2895     int cmd_index, read_write, sgcnt;
2896
2897     ha = HADATA(gdth_ctr_tab[hanum]);
2898     cmdp = ha->pccb;
2899     TRACE(("gdth_fill_cache_cmd() cmd 0x%x cmdsize %d hdrive %d\n",
2900                  scp->cmnd[0],scp->cmd_len,hdrive));
2901
2902     if (ha->type==GDT_EISA && ha->cmd_cnt>0) 
2903         return 0;
2904
2905     cmdp->Service = CACHESERVICE;
2906     cmdp->RequestBuffer = scp;
2907     /* search free command index */
2908     if (!(cmd_index=gdth_get_cmd_index(hanum))) {
2909         TRACE(("GDT: No free command index found\n"));
2910         return 0;
2911     }
2912     /* if it's the first command, set command semaphore */
2913     if (ha->cmd_cnt == 0)
2914         gdth_set_sema0(hanum);
2915
2916     /* fill command */
2917     read_write = 0;
2918     if (scp->SCp.sent_command != -1) 
2919         cmdp->OpCode = scp->SCp.sent_command;   /* special cache cmd. */
2920     else if (scp->cmnd[0] == RESERVE) 
2921         cmdp->OpCode = GDT_RESERVE_DRV;
2922     else if (scp->cmnd[0] == RELEASE)
2923         cmdp->OpCode = GDT_RELEASE_DRV;
2924     else if (scp->cmnd[0] == ALLOW_MEDIUM_REMOVAL) {
2925         if (scp->cmnd[4] & 1)                   /* prevent ? */
2926             cmdp->OpCode = GDT_MOUNT;
2927         else if (scp->cmnd[3] & 1)              /* removable drive ? */
2928             cmdp->OpCode = GDT_UNMOUNT;
2929         else
2930             cmdp->OpCode = GDT_FLUSH;
2931     } else if (scp->cmnd[0] == WRITE_6 || scp->cmnd[0] == WRITE_10 ||
2932                scp->cmnd[0] == WRITE_12) {
2933         read_write = 1;
2934         if (gdth_write_through || ((ha->hdr[hdrive].rw_attribs & 1) && 
2935                                    (ha->cache_feat & GDT_WR_THROUGH)))
2936             cmdp->OpCode = GDT_WRITE_THR;
2937         else
2938             cmdp->OpCode = GDT_WRITE;
2939     } else {
2940         read_write = 2;
2941         cmdp->OpCode = GDT_READ;
2942     }
2943     
2944     cmdp->BoardNode        = LOCALBOARD;
2945     cmdp->u.cache.DeviceNo = hdrive;
2946     cmdp->u.cache.BlockNo  = 1;
2947     cmdp->u.cache.sg_canz  = 0;
2948
2949     if (read_write) {
2950         if (scp->cmd_len != 6) {
2951             memcpy(&no, &scp->cmnd[2], sizeof(ulong32));
2952             cmdp->u.cache.BlockNo = ntohl(no);
2953             memcpy(&cnt, &scp->cmnd[7], sizeof(ushort));
2954             cmdp->u.cache.BlockCnt = (ulong32)ntohs(cnt);
2955         } else {
2956             memcpy(&no, &scp->cmnd[0], sizeof(ulong32));
2957             cmdp->u.cache.BlockNo = ntohl(no) & 0x001fffffUL;
2958             cmdp->u.cache.BlockCnt= scp->cmnd[4]==0 ? 0x100 : scp->cmnd[4];
2959         }
2960
2961         if (scp->use_sg) {
2962             cmdp->u.cache.DestAddr= 0xffffffff;
2963             sl = (struct scatterlist *)scp->request_buffer;
2964             sgcnt = scp->use_sg;
2965 #if LINUX_VERSION_CODE >= 0x020400
2966             scp->SCp.Status = GDTH_MAP_SG;
2967             scp->SCp.Message = (read_write == 1 ? 
2968                 PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);   
2969             sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,scp->SCp.Message);
2970             for (i=0; i<sgcnt; ++i,++sl) {
2971                 cmdp->u.cache.sg_lst[i].sg_ptr = sg_dma_address(sl);
2972                 cmdp->u.cache.sg_lst[i].sg_len = sg_dma_len(sl);
2973             }
2974 #else
2975             for (i=0; i<sgcnt; ++i,++sl) {
2976                 cmdp->u.cache.sg_lst[i].sg_ptr = virt_to_bus(sl->address);
2977                 cmdp->u.cache.sg_lst[i].sg_len = (ulong32)sl->length;
2978             }
2979 #endif
2980             cmdp->u.cache.sg_canz = (ulong32)i;
2981
2982 #ifdef GDTH_STATISTICS
2983             if (max_sg < (ulong32)i) {
2984                 max_sg = (ulong32)i;
2985                 TRACE3(("GDT: max_sg = %d\n",i));
2986             }
2987 #endif
2988             if (i<GDTH_MAXSG)
2989                 cmdp->u.cache.sg_lst[i].sg_len = 0;
2990         } else {
2991 #if LINUX_VERSION_CODE >= 0x020400
2992             scp->SCp.Status = GDTH_MAP_SINGLE;
2993             scp->SCp.Message = (read_write == 1 ? 
2994                 PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);   
2995             phys_addr = pci_map_single(ha->pdev,scp->request_buffer,
2996                                        scp->request_bufflen,scp->SCp.Message);
2997             scp->SCp.dma_handle = phys_addr;
2998 #else
2999             phys_addr = virt_to_bus(scp->request_buffer);
3000 #endif
3001             if (ha->cache_feat & SCATTER_GATHER) {
3002                 cmdp->u.cache.DestAddr = 0xffffffff;
3003                 cmdp->u.cache.sg_canz = 1;
3004                 cmdp->u.cache.sg_lst[0].sg_ptr = phys_addr;
3005                 cmdp->u.cache.sg_lst[0].sg_len = scp->request_bufflen;
3006                 cmdp->u.cache.sg_lst[1].sg_len = 0;
3007             } else {
3008                 cmdp->u.cache.DestAddr  = phys_addr;
3009                 cmdp->u.cache.sg_canz= 0;
3010             }
3011         }
3012     }
3013     TRACE(("cache cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n",
3014            cmdp->u.cache.DestAddr,cmdp->u.cache.sg_canz,
3015            cmdp->u.cache.sg_lst[0].sg_ptr,
3016            cmdp->u.cache.sg_lst[0].sg_len));
3017     TRACE(("cache cmd: cmd %d blockno. %d, blockcnt %d\n",
3018            cmdp->OpCode,cmdp->u.cache.BlockNo,cmdp->u.cache.BlockCnt));
3019
3020     /* evaluate command size, check space */
3021     ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.cache.sg_lst) +
3022         (ushort)cmdp->u.cache.sg_canz * sizeof(gdth_sg_str);
3023     if (ha->cmd_len & 3)
3024         ha->cmd_len += (4 - (ha->cmd_len & 3));
3025
3026     if (ha->cmd_cnt > 0) {
3027         if ((ha->cmd_offs_dpmem + ha->cmd_len + DPMEM_COMMAND_OFFSET) >
3028             ha->ic_all_size) {
3029             TRACE2(("gdth_fill_cache() DPMEM overflow\n"));
3030             ha->cmd_tab[cmd_index-2].cmnd = UNUSED_CMND;
3031             return 0;
3032         }
3033     }
3034
3035     /* copy command */
3036     gdth_copy_command(hanum);
3037     return cmd_index;
3038 }
3039
3040 static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b)
3041 {
3042     register gdth_ha_str *ha;
3043     register gdth_cmd_str *cmdp;
3044     struct scatterlist *sl;
3045     ushort i;
3046     ulong32 phys_addr, sense_paddr;
3047     int cmd_index, sgcnt;
3048     unchar t,l;
3049
3050     ha = HADATA(gdth_ctr_tab[hanum]);
3051 #if LINUX_VERSION_CODE >= 0x02053C
3052     t = scp->device->id;
3053     l = scp->device->lun;
3054 #else
3055     t = scp->target;
3056     l = scp->lun;
3057 #endif
3058     cmdp = ha->pccb;
3059     TRACE(("gdth_fill_raw_cmd() cmd 0x%x bus %d ID %d LUN %d\n",
3060            scp->cmnd[0],b,t,l));
3061
3062     if (ha->type==GDT_EISA && ha->cmd_cnt>0) 
3063         return 0;
3064
3065     cmdp->Service = SCSIRAWSERVICE;
3066     cmdp->RequestBuffer = scp;
3067     /* search free command index */
3068     if (!(cmd_index=gdth_get_cmd_index(hanum))) {
3069         TRACE(("GDT: No free command index found\n"));
3070         return 0;
3071     }
3072     /* if it's the first command, set command semaphore */
3073     if (ha->cmd_cnt == 0)
3074         gdth_set_sema0(hanum);
3075
3076     /* fill command */  
3077     if (scp->SCp.sent_command != -1) {
3078         cmdp->OpCode           = scp->SCp.sent_command; /* special raw cmd. */
3079         cmdp->BoardNode        = LOCALBOARD;
3080         cmdp->u.raw.direction  = (scp->SCp.phase >> 8);
3081         TRACE2(("special raw cmd 0x%x param 0x%x\n", 
3082                 cmdp->OpCode, cmdp->u.raw.direction));
3083
3084         /* evaluate command size */
3085         ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw.sg_lst);
3086     } else {
3087 #if LINUX_VERSION_CODE >= 0x020400
3088         sense_paddr = pci_map_single(ha->pdev,scp->sense_buffer,
3089                                      16,PCI_DMA_FROMDEVICE);
3090         scp->SCp.buffer = (struct scatterlist *)sense_paddr;
3091 #else
3092         sense_paddr = virt_to_bus(scp->sense_buffer);
3093 #endif
3094         cmdp->OpCode           = GDT_WRITE;             /* always */
3095         cmdp->BoardNode        = LOCALBOARD;
3096         cmdp->u.raw.reserved   = 0;
3097         cmdp->u.raw.mdisc_time = 0;
3098         cmdp->u.raw.mcon_time  = 0;
3099         cmdp->u.raw.clen       = scp->cmd_len;
3100         cmdp->u.raw.target     = t;
3101         cmdp->u.raw.lun        = l;
3102         cmdp->u.raw.bus        = b;
3103         cmdp->u.raw.priority   = 0;
3104         cmdp->u.raw.link_p     = 0;
3105         cmdp->u.raw.sdlen      = scp->request_bufflen;
3106         cmdp->u.raw.sense_len  = 16;
3107         cmdp->u.raw.sense_data = sense_paddr;
3108         cmdp->u.raw.direction  = 
3109             gdth_direction_tab[scp->cmnd[0]]==DOU ? GDTH_DATA_OUT:GDTH_DATA_IN;
3110         memcpy(cmdp->u.raw.cmd,scp->cmnd,12);
3111
3112         if (scp->use_sg) {
3113             cmdp->u.raw.sdata  = 0xffffffff;
3114             sl = (struct scatterlist *)scp->request_buffer;
3115             sgcnt = scp->use_sg;
3116 #if LINUX_VERSION_CODE >= 0x020400
3117             scp->SCp.Status = GDTH_MAP_SG;
3118             scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; 
3119             sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,scp->SCp.Message);
3120             for (i=0; i<sgcnt; ++i,++sl) {
3121                 cmdp->u.raw.sg_lst[i].sg_ptr = sg_dma_address(sl);
3122                 cmdp->u.raw.sg_lst[i].sg_len = sg_dma_len(sl);
3123             }
3124 #else
3125             for (i=0; i<sgcnt; ++i,++sl) {
3126                 cmdp->u.raw.sg_lst[i].sg_ptr = virt_to_bus(sl->address);
3127                 cmdp->u.raw.sg_lst[i].sg_len = (ulong32)sl->length;
3128             }
3129 #endif
3130             cmdp->u.raw.sg_ranz = (ulong32)i;
3131
3132 #ifdef GDTH_STATISTICS
3133             if (max_sg < (ulong32)i) {
3134                 max_sg = (ulong32)i;
3135                 TRACE3(("GDT: max_sg = %d\n",i));
3136             }
3137 #endif
3138             if (i<GDTH_MAXSG)
3139                 cmdp->u.raw.sg_lst[i].sg_len = 0;
3140         } else {
3141 #if LINUX_VERSION_CODE >= 0x020400
3142             scp->SCp.Status = GDTH_MAP_SINGLE;
3143             scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; 
3144             phys_addr = pci_map_single(ha->pdev,scp->request_buffer,
3145                                        scp->request_bufflen,scp->SCp.Message);
3146             scp->SCp.dma_handle = phys_addr;
3147 #else
3148             phys_addr = virt_to_bus(scp->request_buffer);
3149 #endif
3150             if (ha->raw_feat & SCATTER_GATHER) {
3151                 cmdp->u.raw.sdata  = 0xffffffff;
3152                 cmdp->u.raw.sg_ranz= 1;
3153                 cmdp->u.raw.sg_lst[0].sg_ptr = phys_addr;
3154                 cmdp->u.raw.sg_lst[0].sg_len = scp->request_bufflen;
3155                 cmdp->u.raw.sg_lst[1].sg_len = 0;
3156             } else {
3157                 cmdp->u.raw.sdata  = phys_addr;
3158                 cmdp->u.raw.sg_ranz= 0;
3159             }
3160         }
3161         TRACE(("raw cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n",
3162                cmdp->u.raw.sdata,cmdp->u.raw.sg_ranz,
3163                cmdp->u.raw.sg_lst[0].sg_ptr,
3164                cmdp->u.raw.sg_lst[0].sg_len));
3165
3166         /* evaluate command size */
3167         ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw.sg_lst) +
3168             (ushort)cmdp->u.raw.sg_ranz * sizeof(gdth_sg_str);
3169     }
3170     /* check space */
3171     if (ha->cmd_len & 3)
3172         ha->cmd_len += (4 - (ha->cmd_len & 3));
3173
3174     if (ha->cmd_cnt > 0) {
3175         if ((ha->cmd_offs_dpmem + ha->cmd_len + DPMEM_COMMAND_OFFSET) >
3176             ha->ic_all_size) {
3177             TRACE2(("gdth_fill_raw() DPMEM overflow\n"));
3178             ha->cmd_tab[cmd_index-2].cmnd = UNUSED_CMND;
3179             return 0;
3180         }
3181     }
3182
3183     /* copy command */
3184     gdth_copy_command(hanum);
3185     return cmd_index;
3186 }
3187
3188 static int gdth_special_cmd(int hanum,Scsi_Cmnd *scp)
3189 {
3190     register gdth_ha_str *ha;
3191     register gdth_cmd_str *cmdp;
3192     int cmd_index;
3193
3194     ha  = HADATA(gdth_ctr_tab[hanum]);
3195     cmdp= ha->pccb;
3196     TRACE2(("gdth_special_cmd(): "));
3197
3198     if (ha->type==GDT_EISA && ha->cmd_cnt>0) 
3199         return 0;
3200
3201     memcpy( cmdp, scp->request_buffer, sizeof(gdth_cmd_str));
3202     cmdp->RequestBuffer = scp;
3203
3204     /* search free command index */
3205     if (!(cmd_index=gdth_get_cmd_index(hanum))) {
3206         TRACE(("GDT: No free command index found\n"));
3207         return 0;
3208     }
3209
3210     /* if it's the first command, set command semaphore */
3211     if (ha->cmd_cnt == 0)
3212        gdth_set_sema0(hanum);
3213
3214     /* evaluate command size, check space */
3215     if (cmdp->OpCode == GDT_IOCTL) {
3216         TRACE2(("IOCTL\n"));
3217         ha->cmd_len = 
3218             GDTOFFSOF(gdth_cmd_str,u.ioctl.p_param) + sizeof(ulong32);
3219     } else if (cmdp->Service == CACHESERVICE) {
3220         TRACE2(("cache command %d\n",cmdp->OpCode));
3221         ha->cmd_len = 
3222             GDTOFFSOF(gdth_cmd_str,u.cache.sg_lst) + sizeof(gdth_sg_str);
3223     } else if (cmdp->Service == SCSIRAWSERVICE) {
3224         TRACE2(("raw command %d/%d\n",cmdp->OpCode,cmdp->u.raw.cmd[0]));
3225         ha->cmd_len = 
3226             GDTOFFSOF(gdth_cmd_str,u.raw.sg_lst) + sizeof(gdth_sg_str);
3227     }
3228
3229     if (ha->cmd_len & 3)
3230         ha->cmd_len += (4 - (ha->cmd_len & 3));
3231
3232     if (ha->cmd_cnt > 0) {
3233         if ((ha->cmd_offs_dpmem + ha->cmd_len + DPMEM_COMMAND_OFFSET) >
3234             ha->ic_all_size) {
3235             TRACE2(("gdth_special_cmd() DPMEM overflow\n"));
3236             ha->cmd_tab[cmd_index-2].cmnd = UNUSED_CMND;
3237             return 0;
3238         }
3239     }
3240
3241     /* copy command */
3242     gdth_copy_command(hanum);
3243     return cmd_index;
3244 }    
3245
3246
3247 /* Controller event handling functions */
3248 static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, ushort source, 
3249                                       ushort idx, gdth_evt_data *evt)
3250 {
3251     gdth_evt_str *e;
3252     struct timeval tv;
3253
3254     /* no GDTH_LOCK_HA() ! */
3255     TRACE2(("gdth_store_event() source %d idx %d\n", source, idx));
3256     if (source == 0)                        /* no source -> no event */
3257         return 0;
3258
3259     if (ebuffer[elastidx].event_source == source &&
3260         ebuffer[elastidx].event_idx == idx &&
3261         ((evt->size != 0 && ebuffer[elastidx].event_data.size != 0 &&
3262             !memcmp((char *)&ebuffer[elastidx].event_data.eu,
3263             (char *)&evt->eu, evt->size)) ||
3264         (evt->size == 0 && ebuffer[elastidx].event_data.size == 0 &&
3265             !strcmp((char *)&ebuffer[elastidx].event_data.event_string,
3266             (char *)&evt->event_string)))) { 
3267         e = &ebuffer[elastidx];
3268         do_gettimeofday(&tv);
3269         e->last_stamp = tv.tv_sec;
3270         ++e->same_count;
3271     } else {
3272         if (ebuffer[elastidx].event_source != 0) {  /* entry not free ? */
3273             ++elastidx;
3274             if (elastidx == MAX_EVENTS)
3275                 elastidx = 0;
3276             if (elastidx == eoldidx) {              /* reached mark ? */
3277                 ++eoldidx;
3278                 if (eoldidx == MAX_EVENTS)
3279                     eoldidx = 0;
3280             }
3281         }
3282         e = &ebuffer[elastidx];
3283         e->event_source = source;
3284         e->event_idx = idx;
3285         do_gettimeofday(&tv);
3286         e->first_stamp = e->last_stamp = tv.tv_sec;
3287         e->same_count = 1;
3288         e->event_data = *evt;
3289         e->application = 0;
3290     }
3291     return e;
3292 }
3293
3294 static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr)
3295 {
3296     gdth_evt_str *e;
3297     int eindex;
3298     ulong flags;
3299
3300     TRACE2(("gdth_read_event() handle %d\n", handle));
3301     GDTH_LOCK_HA(ha, flags);
3302     if (handle == -1)
3303         eindex = eoldidx;
3304     else
3305         eindex = handle;
3306     estr->event_source = 0;
3307
3308     if (eindex >= MAX_EVENTS) {
3309         GDTH_UNLOCK_HA(ha, flags);
3310         return eindex;
3311     }
3312     e = &ebuffer[eindex];
3313     if (e->event_source != 0) {
3314         if (eindex != elastidx) {
3315             if (++eindex == MAX_EVENTS)
3316                 eindex = 0;
3317         } else {
3318             eindex = -1;
3319         }
3320         memcpy(estr, e, sizeof(gdth_evt_str));
3321     }
3322     GDTH_UNLOCK_HA(ha, flags);
3323     return eindex;
3324 }
3325
3326 static void gdth_readapp_event(gdth_ha_str *ha,
3327                                unchar application, gdth_evt_str *estr)
3328 {
3329     gdth_evt_str *e;
3330     int eindex;
3331     ulong flags;
3332     unchar found = FALSE;
3333
3334     TRACE2(("gdth_readapp_event() app. %d\n", application));
3335     GDTH_LOCK_HA(ha, flags);
3336     eindex = eoldidx;
3337     for (;;) {
3338         e = &ebuffer[eindex];
3339         if (e->event_source == 0)
3340             break;
3341         if ((e->application & application) == 0) {
3342             e->application |= application;
3343             found = TRUE;
3344             break;
3345         }
3346         if (eindex == elastidx)
3347             break;
3348         if (++eindex == MAX_EVENTS)
3349             eindex = 0;
3350     }
3351     if (found)
3352         memcpy(estr, e, sizeof(gdth_evt_str));
3353     else
3354         estr->event_source = 0;
3355     GDTH_UNLOCK_HA(ha, flags);
3356 }
3357
3358 static void gdth_clear_events()
3359 {
3360     TRACE(("gdth_clear_events()"));
3361
3362     eoldidx = elastidx = 0;
3363     ebuffer[0].event_source = 0;
3364 }
3365
3366
3367 /* SCSI interface functions */
3368
3369 static irqreturn_t gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs)
3370 {
3371     register gdth_ha_str *ha;
3372     gdt6m_dpram_str *dp6m_ptr;
3373     gdt6_dpram_str *dp6_ptr;
3374     gdt2_dpram_str *dp2_ptr;
3375     Scsi_Cmnd *scp;
3376     int hanum, rval, i;
3377     unchar IStatus;
3378     ushort Service;
3379     ulong flags = 0;
3380
3381     TRACE(("gdth_interrupt() IRQ %d\n",irq));
3382
3383     /* if polling and not from gdth_wait() -> return */
3384     if (gdth_polling) {
3385         if (!gdth_from_wait) {
3386             return IRQ_HANDLED;
3387         }
3388     }
3389
3390     if (!gdth_polling)
3391         GDTH_LOCK_HA((gdth_ha_str *)dev_id,flags);
3392     wait_index = 0;
3393
3394     /* search controller */
3395     if ((hanum = gdth_get_status(&IStatus,irq)) == -1) {
3396         /* spurious interrupt */
3397         if (!gdth_polling)
3398             GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
3399         return IRQ_HANDLED;
3400     }
3401
3402 #ifdef GDTH_STATISTICS
3403     ++act_ints;
3404 #endif
3405     
3406     ha = HADATA(gdth_ctr_tab[hanum]);
3407     if (ha->type == GDT_EISA) {
3408         if (IStatus & 0x80) {                       /* error flag */
3409             IStatus &= ~0x80;
3410             ha->status = inw(ha->bmic + MAILBOXREG+8);
3411             TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status));
3412         } else                                      /* no error */
3413             ha->status = S_OK;
3414         ha->info = inl(ha->bmic + MAILBOXREG+12);
3415         ha->service = inw(ha->bmic + MAILBOXREG+10);
3416         ha->info2 = inl(ha->bmic + MAILBOXREG+4);
3417
3418         outb(0xff, ha->bmic + EDOORREG);            /* acknowledge interrupt */
3419         outb(0x00, ha->bmic + SEMA1REG);            /* reset status semaphore */
3420     } else if (ha->type == GDT_ISA) {
3421         dp2_ptr = (gdt2_dpram_str *)ha->brd;
3422         if (IStatus & 0x80) {                       /* error flag */
3423             IStatus &= ~0x80;
3424             ha->status = gdth_readw(&dp2_ptr->u.ic.Status);
3425             TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status));
3426         } else                                      /* no error */
3427             ha->status = S_OK;
3428         ha->info = gdth_readl(&dp2_ptr->u.ic.Info[0]);
3429         ha->service = gdth_readw(&dp2_ptr->u.ic.Service);
3430         ha->info2 = gdth_readl(&dp2_ptr->u.ic.Info[1]);
3431
3432         gdth_writeb(0xff, &dp2_ptr->io.irqdel);     /* acknowledge interrupt */
3433         gdth_writeb(0, &dp2_ptr->u.ic.Cmd_Index);   /* reset command index */
3434         gdth_writeb(0, &dp2_ptr->io.Sema1);         /* reset status semaphore */
3435     } else if (ha->type == GDT_PCI) {
3436         dp6_ptr = (gdt6_dpram_str *)ha->brd;
3437         if (IStatus & 0x80) {                       /* error flag */
3438             IStatus &= ~0x80;
3439             ha->status = gdth_readw(&dp6_ptr->u.ic.Status);
3440             TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status));
3441         } else                                      /* no error */
3442             ha->status = S_OK;
3443         ha->info = gdth_readl(&dp6_ptr->u.ic.Info[0]);
3444         ha->service = gdth_readw(&dp6_ptr->u.ic.Service);
3445         ha->info2 = gdth_readl(&dp6_ptr->u.ic.Info[1]);
3446
3447         gdth_writeb(0xff, &dp6_ptr->io.irqdel);     /* acknowledge interrupt */
3448         gdth_writeb(0, &dp6_ptr->u.ic.Cmd_Index);   /* reset command index */
3449         gdth_writeb(0, &dp6_ptr->io.Sema1);         /* reset status semaphore */
3450     } else if (ha->type == GDT_PCINEW) {
3451         if (IStatus & 0x80) {                       /* error flag */
3452             IStatus &= ~0x80;
3453             ha->status = inw(PTR2USHORT(&ha->plx->status));
3454             TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status));
3455         } else
3456             ha->status = S_OK;
3457         ha->info = inl(PTR2USHORT(&ha->plx->info[0]));
3458         ha->service = inw(PTR2USHORT(&ha->plx->service));
3459         ha->info2 = inl(PTR2USHORT(&ha->plx->info[1]));
3460
3461         outb(0xff, PTR2USHORT(&ha->plx->edoor_reg)); 
3462         outb(0x00, PTR2USHORT(&ha->plx->sema1_reg)); 
3463     } else if (ha->type == GDT_PCIMPR) {
3464         dp6m_ptr = (gdt6m_dpram_str *)ha->brd;
3465         if (IStatus & 0x80) {                       /* error flag */
3466             IStatus &= ~0x80;
3467             ha->status = gdth_readw(&dp6m_ptr->i960r.status);
3468             TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status));
3469         } else                                      /* no error */
3470             ha->status = S_OK;
3471         ha->info = gdth_readl(&dp6m_ptr->i960r.info[0]);
3472         ha->service = gdth_readw(&dp6m_ptr->i960r.service);
3473         ha->info2 = gdth_readl(&dp6m_ptr->i960r.info[1]);
3474
3475         /* event string */
3476         if (IStatus == ASYNCINDEX) {
3477             if (ha->service != SCREENSERVICE &&
3478                 (ha->fw_vers & 0xff) >= 0x1a) {
3479                 ha->dvr.severity =   
3480                     gdth_readb(&((gdt6m_dpram_str *)ha->brd)->i960r.severity);
3481                 for (i = 0; i < 256; ++i) {
3482                     ha->dvr.event_string[i] = gdth_readb
3483                         (&((gdt6m_dpram_str *)ha->brd)->i960r.evt_str[i]);
3484                     if (ha->dvr.event_string[i] == 0)
3485                         break;
3486                 }
3487             }
3488         }
3489         gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg);
3490         gdth_writeb(0, &dp6m_ptr->i960r.sema1_reg);
3491     } else {
3492         TRACE2(("gdth_interrupt() unknown controller type\n"));
3493         if (!gdth_polling)
3494             GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
3495         return IRQ_HANDLED;
3496     }
3497
3498     TRACE(("gdth_interrupt() index %d stat %d info %d\n",
3499            IStatus,ha->status,ha->info));
3500
3501     if (gdth_from_wait) {
3502         wait_hanum = hanum;
3503         wait_index = (int)IStatus;
3504     }
3505
3506     if (IStatus == ASYNCINDEX) {
3507         TRACE2(("gdth_interrupt() async. event\n"));
3508         gdth_async_event(hanum);
3509         if (!gdth_polling)
3510             GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
3511         gdth_next(hanum);
3512         return IRQ_HANDLED;
3513     } 
3514
3515     if (IStatus == SPEZINDEX) {
3516         TRACE2(("Service unknown or not initialized !\n"));
3517         ha->dvr.size = sizeof(ha->dvr.eu.driver);
3518         ha->dvr.eu.driver.ionode = hanum;
3519         gdth_store_event(ha, ES_DRIVER, 4, &ha->dvr);
3520         if (!gdth_polling)
3521             GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
3522         return IRQ_HANDLED;
3523     }
3524     scp     = ha->cmd_tab[IStatus-2].cmnd;
3525     Service = ha->cmd_tab[IStatus-2].service;
3526     ha->cmd_tab[IStatus-2].cmnd = UNUSED_CMND;
3527     if (scp == UNUSED_CMND) {
3528         TRACE2(("gdth_interrupt() index to unused command (%d)\n",IStatus));
3529         ha->dvr.size = sizeof(ha->dvr.eu.driver);
3530         ha->dvr.eu.driver.ionode = hanum;
3531         ha->dvr.eu.driver.index = IStatus;
3532         gdth_store_event(ha, ES_DRIVER, 1, &ha->dvr);
3533         if (!gdth_polling)
3534             GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
3535         return IRQ_HANDLED;
3536     }
3537     if (scp == INTERNAL_CMND) {
3538         TRACE(("gdth_interrupt() answer to internal command\n"));
3539         if (!gdth_polling)
3540             GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
3541         return IRQ_HANDLED;
3542     }
3543
3544     TRACE(("gdth_interrupt() sync. status\n"));
3545     rval = gdth_sync_event(hanum,Service,IStatus,scp);
3546     if (!gdth_polling)
3547         GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
3548     if (rval == 2) {
3549         gdth_putq(hanum,scp,scp->SCp.this_residual);
3550     } else if (rval == 1) {
3551 #if LINUX_VERSION_CODE >= 0x02053C
3552         GDTH_LOCK_SCSI_DONE(scp->device->host, flags);
3553         scp->scsi_done(scp);
3554         GDTH_UNLOCK_SCSI_DONE(scp->device->host, flags);
3555 #elif LINUX_VERSION_CODE >= 0x020503
3556         GDTH_LOCK_SCSI_DONE(scp->host, flags);
3557         scp->scsi_done(scp);
3558         GDTH_UNLOCK_SCSI_DONE(scp->host, flags);
3559 #else
3560         GDTH_LOCK_SCSI_DONE(flags);
3561         scp->scsi_done(scp);
3562         GDTH_UNLOCK_SCSI_DONE(flags);
3563 #endif
3564     }
3565     gdth_next(hanum);
3566     return IRQ_HANDLED;
3567 }
3568
3569 static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
3570 {
3571     register gdth_ha_str *ha;
3572     gdth_msg_str *msg;
3573     gdth_cmd_str *cmdp;
3574     unchar b, t;
3575
3576     ha   = HADATA(gdth_ctr_tab[hanum]);
3577     cmdp = ha->pccb;
3578     TRACE(("gdth_sync_event() serv %d status %d\n",
3579            service,ha->status));
3580
3581     if (service == SCREENSERVICE) {
3582         msg  = (gdth_msg_str *)ha->pscratch;
3583         ha->scratch_busy = FALSE;
3584         TRACE(("len: %d, answer: %d, ext: %d, alen: %d\n",
3585                msg->msg_len,msg->msg_answer,msg->msg_ext,msg->msg_alen));
3586         if (msg->msg_len)
3587             if (!(msg->msg_answer && msg->msg_ext)) {
3588                 msg->msg_text[msg->msg_len] = '\0';
3589                 printk("%s",msg->msg_text);
3590             }
3591
3592         if (msg->msg_ext && !msg->msg_answer) {
3593             while (gdth_test_busy(hanum))
3594                 gdth_delay(0);
3595             cmdp->Service       = SCREENSERVICE;
3596             cmdp->RequestBuffer = SCREEN_CMND;
3597             gdth_get_cmd_index(hanum);
3598             gdth_set_sema0(hanum);
3599             cmdp->OpCode        = GDT_READ;
3600             cmdp->BoardNode     = LOCALBOARD;
3601             cmdp->u.screen.reserved  = 0;
3602             cmdp->u.screen.su.msg.msg_handle= msg->msg_handle;
3603             cmdp->u.screen.su.msg.msg_addr  = ha->scratch_phys;
3604             ha->scratch_busy = TRUE;
3605             ha->cmd_offs_dpmem = 0;
3606             ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) 
3607                 + sizeof(ulong32);
3608             ha->cmd_cnt = 0;
3609             gdth_copy_command(hanum);
3610             gdth_release_event(hanum);
3611             return 0;
3612         }
3613
3614         if (msg->msg_answer && msg->msg_alen) {
3615             /* default answers (getchar() not possible) */
3616             if (msg->msg_alen == 1) {
3617                 msg->msg_alen = 0;
3618                 msg->msg_len = 1;
3619                 msg->msg_text[0] = 0;
3620             } else {
3621                 msg->msg_alen -= 2;
3622                 msg->msg_len = 2;
3623                 msg->msg_text[0] = 1;
3624                 msg->msg_text[1] = 0;
3625             }
3626             msg->msg_ext    = 0;
3627             msg->msg_answer = 0;
3628             while (gdth_test_busy(hanum))
3629                 gdth_delay(0);
3630             cmdp->Service       = SCREENSERVICE;
3631             cmdp->RequestBuffer = SCREEN_CMND;
3632             gdth_get_cmd_index(hanum);
3633             gdth_set_sema0(hanum);
3634             cmdp->OpCode        = GDT_WRITE;
3635             cmdp->BoardNode     = LOCALBOARD;
3636             cmdp->u.screen.reserved  = 0;
3637             cmdp->u.screen.su.msg.msg_handle= msg->msg_handle;
3638             cmdp->u.screen.su.msg.msg_addr  = ha->scratch_phys;
3639             ha->scratch_busy = TRUE;
3640             ha->cmd_offs_dpmem = 0;
3641             ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) 
3642                 + sizeof(ulong32);
3643             ha->cmd_cnt = 0;
3644             gdth_copy_command(hanum);
3645             gdth_release_event(hanum);
3646             return 0;
3647         }
3648         printk("\n");
3649
3650     } else {
3651 #if LINUX_VERSION_CODE >= 0x02053C
3652         b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
3653         t = scp->device->id;
3654 #else
3655         b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
3656         t = scp->target;
3657 #endif
3658         if (scp->SCp.sent_command == -1 && b != ha->virt_bus) {
3659             ha->raw[BUS_L2P(ha,b)].io_cnt[t]--;
3660         }
3661         /* cache or raw service */
3662         if (ha->status == S_BSY) {
3663             TRACE2(("Controller busy -> retry !\n"));
3664             if (scp->SCp.sent_command == GDT_MOUNT)
3665                 scp->SCp.sent_command = GDT_CLUST_INFO;
3666             /* retry */
3667             return 2;
3668         }
3669 #if LINUX_VERSION_CODE >= 0x020400
3670         if (scp->SCp.Status == GDTH_MAP_SG) 
3671             pci_unmap_sg(ha->pdev,scp->request_buffer,
3672                          scp->use_sg,scp->SCp.Message);
3673         else if (scp->SCp.Status == GDTH_MAP_SINGLE) 
3674             pci_unmap_single(ha->pdev,scp->SCp.dma_handle,
3675                          scp->request_bufflen,scp->SCp.Message);
3676         if (scp->SCp.buffer) 
3677             pci_unmap_single(ha->pdev,(dma_addr_t)scp->SCp.buffer,
3678                                                 16,PCI_DMA_FROMDEVICE);
3679 #endif
3680         if (ha->status == S_OK) {
3681             scp->SCp.Status = S_OK;
3682             scp->SCp.Message = ha->info;
3683             if (scp->SCp.sent_command != -1) {
3684                 TRACE2(("gdth_sync_event(): special cmd 0x%x OK\n",
3685                         scp->SCp.sent_command));
3686                 /* special commands GDT_CLUST_INFO/GDT_MOUNT ? */
3687                 if (scp->SCp.sent_command == GDT_CLUST_INFO) {
3688                     ha->hdr[t].cluster_type = (unchar)ha->info;
3689                     if (!(ha->hdr[t].cluster_type & 
3690                         CLUSTER_MOUNTED)) {
3691                         /* NOT MOUNTED -> MOUNT */
3692                         scp->SCp.sent_command = GDT_MOUNT;
3693                         if (ha->hdr[t].cluster_type & 
3694                             CLUSTER_RESERVED) {
3695                             /* cluster drive RESERVED (on the other node) */
3696                             scp->SCp.phase = -2;      /* reservation conflict */
3697                         }
3698                     } else {
3699                         scp->SCp.sent_command = -1;
3700                     }
3701                 } else {
3702                     if (scp->SCp.sent_command == GDT_MOUNT) {
3703                         ha->hdr[t].cluster_type |= CLUSTER_MOUNTED;
3704                         ha->hdr[t].media_changed = TRUE;
3705                     } else if (scp->SCp.sent_command == GDT_UNMOUNT) {
3706                         ha->hdr[t].cluster_type &= ~CLUSTER_MOUNTED;
3707                         ha->hdr[t].media_changed = TRUE;
3708                     } 
3709                     scp->SCp.sent_command = -1;
3710                 }
3711                 /* retry */
3712                 scp->SCp.this_residual = HIGH_PRI;
3713                 return 2;
3714             } else {
3715                 /* RESERVE/RELEASE ? */
3716                 if (scp->cmnd[0] == RESERVE) {
3717                     ha->hdr[t].cluster_type |= CLUSTER_RESERVED;
3718                 } else if (scp->cmnd[0] == RELEASE) {
3719                     ha->hdr[t].cluster_type &= ~CLUSTER_RESERVED;
3720                 }           
3721                 scp->result = DID_OK << 16;
3722                 scp->sense_buffer[0] = 0;
3723             }
3724         } else {
3725             scp->SCp.Status = ha->status;
3726             scp->SCp.Message = ha->info;
3727
3728             if (scp->SCp.sent_command != -1) {
3729                 TRACE2(("gdth_sync_event(): special cmd 0x%x error 0x%x\n",
3730                         scp->SCp.sent_command, ha->status));
3731                 if (scp->SCp.sent_command == GDT_SCAN_START ||
3732                     scp->SCp.sent_command == GDT_SCAN_END) {
3733                     scp->SCp.sent_command = -1;
3734                     /* retry */
3735                     scp->SCp.this_residual = HIGH_PRI;
3736                     return 2;
3737                 }
3738                 memset((char*)scp->sense_buffer,0,16);
3739                 scp->sense_buffer[0] = 0x70;
3740                 scp->sense_buffer[2] = NOT_READY;
3741                 scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
3742             } else if (service == CACHESERVICE) {
3743                 if (ha->status == S_CACHE_UNKNOWN &&
3744                     (ha->hdr[t].cluster_type & 
3745                      CLUSTER_RESERVE_STATE) == CLUSTER_RESERVE_STATE) {
3746                     /* bus reset -> force GDT_CLUST_INFO */
3747                     ha->hdr[t].cluster_type &= ~CLUSTER_RESERVED;
3748                 }
3749                 memset((char*)scp->sense_buffer,0,16);
3750                 if (ha->status == (ushort)S_CACHE_RESERV) {
3751                     scp->result = (DID_OK << 16) | (RESERVATION_CONFLICT << 1);
3752                 } else {
3753                     scp->sense_buffer[0] = 0x70;
3754                     scp->sense_buffer[2] = NOT_READY;
3755                     scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
3756                 }
3757 #if LINUX_VERSION_CODE >= 0x010300
3758                 if (scp->done != gdth_scsi_done)
3759 #endif  
3760                 {
3761                     ha->dvr.size = sizeof(ha->dvr.eu.sync);
3762                     ha->dvr.eu.sync.ionode  = hanum;
3763                     ha->dvr.eu.sync.service = service;
3764                     ha->dvr.eu.sync.status  = ha->status;
3765                     ha->dvr.eu.sync.info    = ha->info;
3766                     ha->dvr.eu.sync.hostdrive = t;
3767                     if (ha->status >= 0x8000)
3768                         gdth_store_event(ha, ES_SYNC, 0, &ha->dvr);
3769                     else
3770                         gdth_store_event(ha, ES_SYNC, service, &ha->dvr);
3771                 }
3772             } else {
3773                 /* sense buffer filled from controller firmware (DMA) */
3774                 if (ha->status != S_RAW_SCSI || ha->info >= 0x100) {
3775                     scp->result = DID_BAD_TARGET << 16;
3776                 } else {
3777                     scp->result = (DID_OK << 16) | ha->info;
3778                 }
3779             }
3780         }
3781         if (!scp->SCp.have_data_in)
3782             scp->SCp.have_data_in++;
3783         else 
3784             return 1;
3785     }
3786
3787     return 0;
3788 }
3789
3790 static char *async_cache_tab[] = {
3791 /* 0*/  "\011\000\002\002\002\004\002\006\004"
3792         "GDT HA %u, service %u, async. status %u/%lu unknown",
3793 /* 1*/  "\011\000\002\002\002\004\002\006\004"
3794         "GDT HA %u, service %u, async. status %u/%lu unknown",
3795 /* 2*/  "\005\000\002\006\004"
3796         "GDT HA %u, Host Drive %lu not ready",
3797 /* 3*/  "\005\000\002\006\004"
3798         "GDT HA %u, Host Drive %lu: REASSIGN not successful and/or data error on reassigned blocks. Drive may crash in the future and should be replaced",
3799 /* 4*/  "\005\000\002\006\004"
3800         "GDT HA %u, mirror update on Host Drive %lu failed",
3801 /* 5*/  "\005\000\002\006\004"
3802         "GDT HA %u, Mirror Drive %lu failed",
3803 /* 6*/  "\005\000\002\006\004"
3804         "GDT HA %u, Mirror Drive %lu: REASSIGN not successful and/or data error on reassigned blocks. Drive may crash in the future and should be replaced",
3805 /* 7*/  "\005\000\002\006\004"
3806         "GDT HA %u, Host Drive %lu write protected",
3807 /* 8*/  "\005\000\002\006\004"
3808         "GDT HA %u, media changed in Host Drive %lu",
3809 /* 9*/  "\005\000\002\006\004"
3810         "GDT HA %u, Host Drive %lu is offline",
3811 /*10*/  "\005\000\002\006\004"
3812         "GDT HA %u, media change of Mirror Drive %lu",
3813 /*11*/  "\005\000\002\006\004"
3814         "GDT HA %u, Mirror Drive %lu is write protected",
3815 /*12*/  "\005\000\002\006\004"
3816         "GDT HA %u, general error on Host Drive %lu. Please check the devices of this drive!",
3817 /*13*/  "\007\000\002\006\002\010\002"
3818         "GDT HA %u, Array Drive %u: Cache Drive %u failed",
3819 /*14*/  "\005\000\002\006\002"
3820         "GDT HA %u, Array Drive %u: FAIL state entered",
3821 /*15*/  "\005\000\002\006\002"
3822         "GDT HA %u, Array Drive %u: error",
3823 /*16*/  "\007\000\002\006\002\010\002"
3824         "GDT HA %u, Array Drive %u: failed drive replaced by Cache Drive %u",
3825 /*17*/  "\005\000\002\006\002"
3826         "GDT HA %u, Array Drive %u: parity build failed",
3827 /*18*/  "\005\000\002\006\002"
3828         "GDT HA %u, Array Drive %u: drive rebuild failed",
3829 /*19*/  "\005\000\002\010\002"
3830         "GDT HA %u, Test of Hot Fix %u failed",
3831 /*20*/  "\005\000\002\006\002"
3832         "GDT HA %u, Array Drive %u: drive build finished successfully",
3833 /*21*/  "\005\000\002\006\002"
3834         "GDT HA %u, Array Drive %u: drive rebuild finished successfully",
3835 /*22*/  "\007\000\002\006\002\010\002"
3836         "GDT HA %u, Array Drive %u: Hot Fix %u activated",
3837 /*23*/  "\005\000\002\006\002"
3838         "GDT HA %u, Host Drive %u: processing of i/o aborted due to serious drive error",
3839 /*24*/  "\005\000\002\010\002"
3840         "GDT HA %u, mirror update on Cache Drive %u completed",
3841 /*25*/  "\005\000\002\010\002"
3842         "GDT HA %u, mirror update on Cache Drive %lu failed",
3843 /*26*/  "\005\000\002\006\002"
3844         "GDT HA %u, Array Drive %u: drive rebuild started",
3845 /*27*/  "\005\000\002\012\001"
3846         "GDT HA %u, Fault bus %u: SHELF OK detected",
3847 /*28*/  "\005\000\002\012\001"
3848         "GDT HA %u, Fault bus %u: SHELF not OK detected",
3849 /*29*/  "\007\000\002\012\001\013\001"
3850         "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug started",
3851 /*30*/  "\007\000\002\012\001\013\001"
3852         "GDT HA %u, Fault bus %u, ID %u: new disk detected",
3853 /*31*/  "\007\000\002\012\001\013\001"
3854         "GDT HA %u, Fault bus %u, ID %u: old disk detected",
3855 /*32*/  "\007\000\002\012\001\013\001"
3856         "GDT HA %u, Fault bus %u, ID %u: plugging an active disk is invalid",
3857 /*33*/  "\007\000\002\012\001\013\001"
3858         "GDT HA %u, Fault bus %u, ID %u: invalid device detected",
3859 /*34*/  "\011\000\002\012\001\013\001\006\004"
3860         "GDT HA %u, Fault bus %u, ID %u: insufficient disk capacity (%lu MB required)",
3861 /*35*/  "\007\000\002\012\001\013\001"
3862         "GDT HA %u, Fault bus %u, ID %u: disk write protected",
3863 /*36*/  "\007\000\002\012\001\013\001"
3864         "GDT HA %u, Fault bus %u, ID %u: disk not available",
3865 /*37*/  "\007\000\002\012\001\006\004"
3866         "GDT HA %u, Fault bus %u: swap detected (%lu)",
3867 /*38*/  "\007\000\002\012\001\013\001"
3868         "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug finished successfully",
3869 /*39*/  "\007\000\002\012\001\013\001"
3870         "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug aborted due to user Hot Plug",
3871 /*40*/  "\007\000\002\012\001\013\001"
3872         "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug aborted",
3873 /*41*/  "\007\000\002\012\001\013\001"
3874         "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug for Hot Fix started",
3875 /*42*/  "\005\000\002\006\002"
3876         "GDT HA %u, Array Drive %u: drive build started",
3877 /*43*/  "\003\000\002"
3878         "GDT HA %u, DRAM parity error detected",
3879 /*44*/  "\005\000\002\006\002"
3880         "GDT HA %u, Mirror Drive %u: update started",
3881 /*45*/  "\007\000\002\006\002\010\002"
3882         "GDT HA %u, Mirror Drive %u: Hot Fix %u activated",
3883 /*46*/  "\005\000\002\006\002"
3884         "GDT HA %u, Array Drive %u: no matching Pool Hot Fix Drive available",
3885 /*47*/  "\005\000\002\006\002"
3886         "GDT HA %u, Array Drive %u: Pool Hot Fix Drive available",
3887 /*48*/  "\005\000\002\006\002"
3888         "GDT HA %u, Mirror Drive %u: no matching Pool Hot Fix Drive available",
3889 /*49*/  "\005\000\002\006\002"
3890         "GDT HA %u, Mirror Drive %u: Pool Hot Fix Drive available",
3891 /*50*/  "\007\000\002\012\001\013\001"
3892         "GDT HA %u, SCSI bus %u, ID %u: IGNORE_WIDE_RESIDUE message received",
3893 /*51*/  "\005\000\002\006\002"
3894         "GDT HA %u, Array Drive %u: expand started",
3895 /*52*/  "\005\000\002\006\002"
3896         "GDT HA %u, Array Drive %u: expand finished successfully",
3897 /*53*/  "\005\000\002\006\002"
3898         "GDT HA %u, Array Drive %u: expand failed",
3899 /*54*/  "\003\000\002"
3900         "GDT HA %u, CPU temperature critical",
3901 /*55*/  "\003\000\002"
3902         "GDT HA %u, CPU temperature OK",
3903 /*56*/  "\005\000\002\006\004"
3904         "GDT HA %u, Host drive %lu created",
3905 /*57*/  "\005\000\002\006\002"
3906         "GDT HA %u, Array Drive %u: expand restarted",
3907 /*58*/  "\005\000\002\006\002"
3908         "GDT HA %u, Array Drive %u: expand stopped",
3909 /*59*/  "\005\000\002\010\002"
3910         "GDT HA %u, Mirror Drive %u: drive build quited",
3911 /*60*/  "\005\000\002\006\002"
3912         "GDT HA %u, Array Drive %u: parity build quited",
3913 /*61*/  "\005\000\002\006\002"
3914         "GDT HA %u, Array Drive %u: drive rebuild quited",
3915 /*62*/  "\005\000\002\006\002"
3916         "GDT HA %u, Array Drive %u: parity verify started",
3917 /*63*/  "\005\000\002\006\002"
3918         "GDT HA %u, Array Drive %u: parity verify done",
3919 /*64*/  "\005\000\002\006\002"
3920         "GDT HA %u, Array Drive %u: parity verify failed",
3921 /*65*/  "\005\000\002\006\002"
3922         "GDT HA %u, Array Drive %u: parity error detected",
3923 /*66*/  "\005\000\002\006\002"
3924         "GDT HA %u, Array Drive %u: parity verify quited",
3925 /*67*/  "\005\000\002\006\002"
3926         "GDT HA %u, Host Drive %u reserved",
3927 /*68*/  "\005\000\002\006\002"
3928         "GDT HA %u, Host Drive %u mounted and released",
3929 /*69*/  "\005\000\002\006\002"
3930         "GDT HA %u, Host Drive %u released",
3931 /*70*/  "\003\000\002"
3932         "GDT HA %u, DRAM error detected and corrected with ECC",
3933 /*71*/  "\003\000\002"
3934         "GDT HA %u, Uncorrectable DRAM error detected with ECC",
3935 /*72*/  "\011\000\002\012\001\013\001\014\001"
3936         "GDT HA %u, SCSI bus %u, ID %u, LUN %u: reassigning block",
3937 /*73*/  "\005\000\002\006\002"
3938         "GDT HA %u, Host drive %u resetted locally",
3939 /*74*/  "\005\000\002\006\002"
3940         "GDT HA %u, Host drive %u resetted remotely",
3941 /*75*/  "\003\000\002"
3942         "GDT HA %u, async. status 75 unknown",
3943 };
3944
3945
3946 static int gdth_async_event(int hanum)
3947 {
3948     gdth_ha_str *ha;
3949     gdth_msg_str *msg;
3950     gdth_cmd_str *cmdp;
3951     int cmd_index;
3952
3953     ha  = HADATA(gdth_ctr_tab[hanum]);
3954     cmdp= ha->pccb;
3955     msg = (gdth_msg_str *)ha->pscratch;
3956     TRACE2(("gdth_async_event() ha %d serv %d\n",
3957             hanum,ha->service));
3958
3959     if (ha->service == SCREENSERVICE) {
3960         if (ha->status == MSG_REQUEST) {
3961             while (gdth_test_busy(hanum))
3962                 gdth_delay(0);
3963             cmdp->Service       = SCREENSERVICE;
3964             cmdp->RequestBuffer = SCREEN_CMND;
3965             cmd_index = gdth_get_cmd_index(hanum);
3966             gdth_set_sema0(hanum);
3967             cmdp->OpCode        = GDT_READ;
3968             cmdp->BoardNode     = LOCALBOARD;
3969             cmdp->u.screen.reserved  = 0;
3970             cmdp->u.screen.su.msg.msg_handle= MSG_INV_HANDLE;
3971             cmdp->u.screen.su.msg.msg_addr  = ha->scratch_phys;
3972             ha->scratch_busy = TRUE;
3973             ha->cmd_offs_dpmem = 0;
3974             ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) 
3975                 + sizeof(ulong32);
3976             ha->cmd_cnt = 0;
3977             gdth_copy_command(hanum);
3978             if (ha->type == GDT_EISA)
3979                 printk("[EISA slot %d] ",(ushort)ha->brd_phys);
3980             else if (ha->type == GDT_ISA)
3981                 printk("[DPMEM 0x%4X] ",(ushort)ha->brd_phys);
3982             else 
3983                 printk("[PCI %d/%d] ",(ushort)(ha->brd_phys>>8),
3984                        (ushort)((ha->brd_phys>>3)&0x1f));
3985             gdth_release_event(hanum);
3986         }
3987
3988     } else {
3989         if (ha->type == GDT_PCIMPR && 
3990             (ha->fw_vers & 0xff) >= 0x1a) {
3991             ha->dvr.size = 0;
3992             ha->dvr.eu.async.ionode = hanum;
3993             ha->dvr.eu.async.status  = ha->status;
3994             /* severity and event_string already set! */
3995         } else {        
3996             ha->dvr.size = sizeof(ha->dvr.eu.async);
3997             ha->dvr.eu.async.ionode   = hanum;
3998             ha->dvr.eu.async.service = ha->service;
3999             ha->dvr.eu.async.status  = ha->status;
4000             ha->dvr.eu.async.info    = ha->info;
4001             *(ulong32 *)ha->dvr.eu.async.scsi_coord  = ha->info2;
4002         }
4003         gdth_store_event( ha, ES_ASYNC, ha->service, &ha->dvr );
4004         gdth_log_event( &ha->dvr, NULL );
4005     
4006         /* new host drive from expand? */
4007         if (ha->service == CACHESERVICE && ha->status == 56) {
4008             TRACE2(("gdth_async_event(): new host drive %d created\n",
4009                     (ushort)ha->info));
4010             /* gdth_analyse_hdrive(hanum, (ushort)ha->info); */
4011         }   
4012     }
4013     return 1;
4014 }
4015
4016 static void gdth_log_event(gdth_evt_data *dvr, char *buffer)
4017 {
4018     gdth_stackframe stack;
4019     char *f = NULL;
4020     int i,j;
4021
4022     TRACE2(("gdth_log_event()\n"));
4023     if (dvr->size == 0) {
4024         if (buffer == NULL) {
4025             printk("Adapter %d: %s\n",dvr->eu.async.ionode,dvr->event_string); 
4026         } else {
4027             sprintf(buffer,"Adapter %d: %s\n",
4028                 dvr->eu.async.ionode,dvr->event_string); 
4029         }
4030     } else if (dvr->eu.async.service == CACHESERVICE && 
4031         INDEX_OK(dvr->eu.async.status, async_cache_tab)) {
4032         TRACE2(("GDT: Async. event cache service, event no.: %d\n",
4033                 dvr->eu.async.status));
4034         
4035         f = async_cache_tab[dvr->eu.async.status];
4036         
4037         /* i: parameter to push, j: stack element to fill */
4038         for (j=0,i=1; i < f[0]; i+=2) {
4039             switch (f[i+1]) {
4040               case 4:
4041                 stack.b[j++] = *(ulong32*)&dvr->eu.stream[(int)f[i]];
4042                 break;
4043               case 2:
4044                 stack.b[j++] = *(ushort*)&dvr->eu.stream[(int)f[i]];
4045                 break;
4046               case 1:
4047                 stack.b[j++] = *(unchar*)&dvr->eu.stream[(int)f[i]];
4048                 break;
4049               default:
4050                 break;
4051             }
4052         }
4053         
4054         if (buffer == NULL) {
4055             printk(&f[(int)f[0]],stack); 
4056             printk("\n");
4057         } else {
4058             sprintf(buffer,&f[(int)f[0]],stack); 
4059         }
4060
4061     } else {
4062         if (buffer == NULL) {
4063             printk("GDT HA %u, Unknown async. event service %d event no. %d\n",
4064                    dvr->eu.async.ionode,dvr->eu.async.service,dvr->eu.async.status);
4065         } else {
4066             sprintf(buffer,"GDT HA %u, Unknown async. event service %d event no. %d",
4067                     dvr->eu.async.ionode,dvr->eu.async.service,dvr->eu.async.status);
4068         }
4069     }
4070 }
4071
4072 #ifdef GDTH_STATISTICS
4073 void gdth_timeout(ulong data)
4074 {
4075     ulong32 i;
4076     Scsi_Cmnd *nscp;
4077     gdth_ha_str *ha;
4078     ulong flags;
4079     int hanum = 0;
4080
4081     ha = HADATA(gdth_ctr_tab[hanum]);
4082     GDTH_LOCK_HA(ha, flags);
4083
4084     for (act_stats=0,i=0; i<GDTH_MAXCMDS; ++i) 
4085         if (ha->cmd_tab[i].cmnd != UNUSED_CMND)
4086             ++act_stats;
4087
4088     for (act_rq=0,nscp=ha->req_first; nscp; nscp=(Scsi_Cmnd*)nscp->SCp.ptr)
4089         ++act_rq;
4090
4091     TRACE2(("gdth_to(): ints %d, ios %d, act_stats %d, act_rq %d\n",
4092             act_ints, act_ios, act_stats, act_rq));
4093     act_ints = act_ios = 0;
4094
4095     gdth_timer.expires = jiffies + 30 * HZ;
4096     add_timer(&gdth_timer);
4097     GDTH_UNLOCK_HA(ha, flags);
4098 }
4099 #endif
4100
4101 GDTH_INITFUNC(void, internal_setup(char *str,int *ints))
4102 {
4103     int i, argc;
4104     char *cur_str, *argv;
4105
4106     TRACE2(("internal_setup() str %s ints[0] %d\n", 
4107             str ? str:"NULL", ints ? ints[0]:0));
4108
4109     /* read irq[] from ints[] */
4110     if (ints) {
4111         argc = ints[0];
4112         if (argc > 0) {
4113             if (argc > MAXHA)
4114                 argc = MAXHA;
4115             for (i = 0; i < argc; ++i)
4116                 irq[i] = ints[i+1];
4117         }
4118     }
4119
4120     /* analyse string */
4121     argv = str;
4122     while (argv && (cur_str = strchr(argv, ':'))) {
4123         int val = 0, c = *++cur_str;
4124         
4125         if (c == 'n' || c == 'N')
4126             val = 0;
4127         else if (c == 'y' || c == 'Y')
4128             val = 1;
4129         else
4130             val = (int)simple_strtoul(cur_str, NULL, 0);
4131
4132         if (!strncmp(argv, "disable:", 8))
4133             disable = val;
4134         else if (!strncmp(argv, "reserve_mode:", 13))
4135             reserve_mode = val;
4136         else if (!strncmp(argv, "reverse_scan:", 13))
4137             reverse_scan = val;
4138         else if (!strncmp(argv, "hdr_channel:", 12))
4139             hdr_channel = val;
4140         else if (!strncmp(argv, "max_ids:", 8))
4141             max_ids = val;
4142         else if (!strncmp(argv, "rescan:", 7))
4143             rescan = val;
4144         else if (!strncmp(argv, "virt_ctr:", 9))
4145             virt_ctr = val;
4146         else if (!strncmp(argv, "shared_access:", 14))
4147             shared_access = val;
4148         else if (!strncmp(argv, "probe_eisa_isa:", 15))
4149             probe_eisa_isa = val;
4150         else if (!strncmp(argv, "reserve_list:", 13)) {
4151             reserve_list[0] = val;
4152             for (i = 1; i < MAX_RES_ARGS; i++) {
4153                 cur_str = strchr(cur_str, ',');
4154                 if (!cur_str)
4155                     break;
4156                 if (!isdigit((int)*++cur_str)) {
4157                     --cur_str;          
4158                     break;
4159                 }
4160                 reserve_list[i] = 
4161                     (int)simple_strtoul(cur_str, NULL, 0);
4162             }
4163             if (!cur_str)
4164                 break;
4165             argv = ++cur_str;
4166             continue;
4167         }
4168
4169         if ((argv = strchr(argv, ',')))
4170             ++argv;
4171     }
4172 }
4173
4174 GDTH_INITFUNC(int, option_setup(char *str))
4175 {
4176     int ints[MAXHA];
4177     char *cur = str;
4178     int i = 1;
4179
4180     TRACE2(("option_setup() str %s\n", str ? str:"NULL")); 
4181
4182     while (cur && isdigit(*cur) && i <= MAXHA) {
4183         ints[i++] = simple_strtoul(cur, NULL, 0);
4184         if ((cur = strchr(cur, ',')) != NULL) cur++;
4185     }
4186
4187     ints[0] = i - 1;
4188     internal_setup(cur, ints);
4189     return 1;
4190 }
4191
4192 GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
4193 {
4194     struct Scsi_Host *shp;
4195     gdth_ha_str *ha;
4196     ulong32 isa_bios;
4197     ushort eisa_slot;
4198     int i,hanum,cnt,ctr;
4199     unchar b;
4200     
4201  
4202 #ifdef DEBUG_GDTH
4203     printk("GDT: This driver contains debugging information !! Trace level = %d\n",
4204         DebugState);
4205     printk("     Destination of debugging information: ");
4206 #ifdef __SERIAL__
4207 #ifdef __COM2__
4208     printk("Serial port COM2\n");
4209 #else
4210     printk("Serial port COM1\n");
4211 #endif
4212 #else
4213     printk("Console\n");
4214 #endif
4215     gdth_delay(3000);
4216 #endif
4217
4218     TRACE(("gdth_detect()\n"));
4219
4220     if (disable) {
4221         printk("GDT: Controller driver disabled from command line !\n");
4222         return 0;
4223     }
4224
4225     printk("GDT: Storage RAID Controller Driver. Version: %s \n",GDTH_VERSION_STR);
4226     /* initializations */
4227     gdth_polling = TRUE; b = 0;
4228     gdth_clear_events();
4229
4230     /* As default we do not probe for EISA or ISA controllers */
4231     if (probe_eisa_isa) {    
4232         /* scanning for controllers, at first: ISA controller */
4233         for (isa_bios=0xc8000UL; isa_bios<=0xd8000UL; isa_bios+=0x8000UL) {
4234             dma_addr_t scratch_dma_handle;
4235
4236             if (gdth_ctr_count >= MAXHA) 
4237                 break;
4238             if (gdth_search_isa(isa_bios)) {        /* controller found */
4239                 shp = scsi_register(shtp,sizeof(gdth_ext_str));
4240                 if (shp == NULL)
4241                     continue;  
4242
4243                 ha = HADATA(shp);
4244                 if (!gdth_init_isa(isa_bios,ha)) {
4245                     scsi_unregister(shp);
4246                     continue;
4247                 }
4248 #ifdef __ia64__
4249                 break;
4250 #else
4251                 /* controller found and initialized */
4252                 printk("Configuring GDT-ISA HA at BIOS 0x%05X IRQ %u DRQ %u\n",
4253                        isa_bios,ha->irq,ha->drq);
4254
4255 #if LINUX_VERSION_CODE >= 0x010346 
4256                 if (request_irq(ha->irq,gdth_interrupt,SA_INTERRUPT,"gdth",ha))
4257 #else
4258                 if (request_irq(ha->irq,gdth_interrupt,SA_INTERRUPT,"gdth")) 
4259 #endif
4260                 {
4261                     printk("GDT-ISA: Unable to allocate IRQ\n");
4262                     scsi_unregister(shp);
4263                     continue;
4264                 }
4265                 if (request_dma(ha->drq,"gdth")) {
4266                     printk("GDT-ISA: Unable to allocate DMA channel\n");
4267 #if LINUX_VERSION_CODE >= 0x010346 
4268                     free_irq(ha->irq,ha);
4269 #else
4270                     free_irq(ha->irq);
4271 #endif
4272                     scsi_unregister(shp);
4273                     continue;
4274                 }
4275                 set_dma_mode(ha->drq,DMA_MODE_CASCADE);
4276                 enable_dma(ha->drq);
4277                 shp->unchecked_isa_dma = 1;
4278                 shp->irq = ha->irq;
4279                 shp->dma_channel = ha->drq;
4280                 hanum = gdth_ctr_count;         
4281                 gdth_ctr_tab[gdth_ctr_count++] = shp;
4282                 gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
4283
4284                 NUMDATA(shp)->hanum = (ushort)hanum;
4285                 NUMDATA(shp)->busnum= 0;
4286
4287                 ha->pccb = CMDDATA(shp);
4288                 ha->ccb_phys = 0L;
4289 #if LINUX_VERSION_CODE >= 0x020400
4290                 ha->pdev = NULL;
4291                 ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, 
4292                                                     &scratch_dma_handle);
4293                 ha->scratch_phys = (ulong32)scratch_dma_handle;
4294 #else
4295                 ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
4296                 if (ha->pscratch)
4297                     ha->scratch_phys = virt_to_bus(ha->pscratch);
4298 #endif
4299                 ha->scratch_busy = FALSE;
4300                 ha->req_first = NULL;
4301                 ha->tid_cnt = MAX_HDRIVES;
4302                 if (max_ids > 0 && max_ids < ha->tid_cnt)
4303                     ha->tid_cnt = max_ids;
4304                 for (i=0; i<GDTH_MAXCMDS; ++i)
4305                     ha->cmd_tab[i].cmnd = UNUSED_CMND;
4306                 ha->scan_mode = rescan ? 0x10 : 0;
4307
4308                 if (ha->pscratch == NULL || !gdth_search_drives(hanum)) {
4309                     printk("GDT-ISA: Error during device scan\n");
4310                     --gdth_ctr_count;
4311                     --gdth_ctr_vcount;
4312                     if (ha->pscratch != NULL) {
4313 #if LINUX_VERSION_CODE >= 0x020400
4314                         pci_free_consistent(ha->pdev, GDTH_SCRATCH, 
4315                                             ha->pscratch, ha->scratch_phys);
4316 #else
4317                         scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
4318 #endif
4319                     }
4320 #if LINUX_VERSION_CODE >= 0x010346 
4321                     free_irq(ha->irq,ha);
4322 #else
4323                     free_irq(ha->irq);
4324 #endif
4325                     scsi_unregister(shp);
4326                     continue;
4327                 }
4328                 if (hdr_channel < 0 || hdr_channel > ha->bus_cnt)
4329                     hdr_channel = ha->bus_cnt;
4330                 ha->virt_bus = hdr_channel;
4331
4332 #if LINUX_VERSION_CODE >= 0x020000
4333                 shp->max_id      = ha->tid_cnt;
4334                 shp->max_lun     = MAXLUN;
4335                 shp->max_channel = virt_ctr ? 0 : ha->bus_cnt;
4336                 if (virt_ctr)  
4337 #endif
4338                 {
4339                     virt_ctr = 1;
4340                     /* register addit. SCSI channels as virtual controllers */
4341                     for (b = 1; b < ha->bus_cnt + 1; ++b) {
4342                         shp = scsi_register(shtp,sizeof(gdth_num_str));
4343                         shp->unchecked_isa_dma = 1;
4344                         shp->irq = ha->irq;
4345                         shp->dma_channel = ha->drq;
4346                         gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
4347                         NUMDATA(shp)->hanum = (ushort)hanum;
4348                         NUMDATA(shp)->busnum = b;
4349                     }
4350                 }  
4351
4352                 GDTH_INIT_LOCK_HA(ha);
4353                 gdth_enable_int(hanum);
4354 #endif /* !__ia64__ */
4355             }
4356         }
4357
4358         /* scanning for EISA controllers */
4359         for (eisa_slot=0x1000; eisa_slot<=0x8000; eisa_slot+=0x1000) {
4360             dma_addr_t scratch_dma_handle;
4361
4362             if (gdth_ctr_count >= MAXHA) 
4363                 break;
4364             if (gdth_search_eisa(eisa_slot)) {      /* controller found */
4365                 shp = scsi_register(shtp,sizeof(gdth_ext_str));
4366                 if (shp == NULL)
4367                     continue;  
4368
4369                 ha = HADATA(shp);
4370                 if (!gdth_init_eisa(eisa_slot,ha)) {
4371                     scsi_unregister(shp);
4372                     continue;
4373                 }
4374                 /* controller found and initialized */
4375                 printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n",
4376                         eisa_slot>>12,ha->irq);
4377
4378 #if LINUX_VERSION_CODE >= 0x010346 
4379                 if (request_irq(ha->irq,gdth_interrupt,SA_INTERRUPT,"gdth",ha))
4380 #else
4381                 if (request_irq(ha->irq,gdth_interrupt,SA_INTERRUPT,"gdth")) 
4382 #endif
4383                 {
4384                     printk("GDT-EISA: Unable to allocate IRQ\n");
4385                     scsi_unregister(shp);
4386                     continue;
4387                 }
4388                 shp->unchecked_isa_dma = 0;
4389                 shp->irq = ha->irq;
4390                 shp->dma_channel = 0xff;
4391                 hanum = gdth_ctr_count;
4392                 gdth_ctr_tab[gdth_ctr_count++] = shp;
4393                 gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
4394
4395                 NUMDATA(shp)->hanum = (ushort)hanum;
4396                 NUMDATA(shp)->busnum= 0;
4397                 TRACE2(("EISA detect Bus 0: hanum %d\n",
4398                         NUMDATA(shp)->hanum));
4399
4400                 ha->pccb = CMDDATA(shp);
4401                 ha->ccb_phys = 0L; 
4402 #if LINUX_VERSION_CODE >= 0x020400
4403                 ha->pdev = NULL;
4404                 ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, 
4405                                                     &scratch_dma_handle);
4406                 ha->scratch_phys = (ulong32) scratch_dma_handle;
4407                 ha->ccb_phys = 
4408                     pci_map_single(ha->pdev,ha->pccb,
4409                                    sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
4410 #else
4411                 ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
4412                 if (ha->pscratch)
4413                     ha->scratch_phys = virt_to_bus(ha->pscratch);
4414                 ha->ccb_phys = virt_to_bus(ha->pccb);
4415 #endif
4416                 ha->scratch_busy = FALSE;
4417                 ha->req_first = NULL;
4418                 ha->tid_cnt = MAX_HDRIVES;
4419                 if (max_ids > 0 && max_ids < ha->tid_cnt)
4420                     ha->tid_cnt = max_ids;
4421                 for (i=0; i<GDTH_MAXCMDS; ++i)
4422                      ha->cmd_tab[i].cmnd = UNUSED_CMND;
4423                 ha->scan_mode = rescan ? 0x10 : 0;
4424
4425                 if (ha->pscratch == NULL || !gdth_search_drives(hanum)) {
4426                     printk("GDT-EISA: Error during device scan\n");
4427                     --gdth_ctr_count;
4428                     --gdth_ctr_vcount;
4429                     if (ha->pscratch != NULL) {
4430 #if LINUX_VERSION_CODE >= 0x020400
4431                         pci_free_consistent(ha->pdev, GDTH_SCRATCH, 
4432                                             ha->pscratch, ha->scratch_phys);
4433                         pci_unmap_single(ha->pdev,ha->ccb_phys,
4434                                          sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
4435 #else
4436                         scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
4437 #endif
4438                     }
4439 #if LINUX_VERSION_CODE >= 0x010346 
4440                     free_irq(ha->irq,ha);
4441 #else
4442                     free_irq(ha->irq);
4443 #endif
4444                     scsi_unregister(shp);
4445                     continue;
4446                 }
4447                 if (hdr_channel < 0 || hdr_channel > ha->bus_cnt)
4448                     hdr_channel = ha->bus_cnt;
4449                 ha->virt_bus = hdr_channel;
4450
4451 #if LINUX_VERSION_CODE >= 0x020000
4452                 shp->max_id      = ha->tid_cnt;
4453                 shp->max_lun     = MAXLUN;
4454                 shp->max_channel = virt_ctr ? 0 : ha->bus_cnt;
4455                 if (virt_ctr)  
4456 #endif
4457                 {
4458                     virt_ctr = 1;
4459                     /* register addit. SCSI channels as virtual controllers */
4460                     for (b = 1; b < ha->bus_cnt + 1; ++b) {
4461                         shp = scsi_register(shtp,sizeof(gdth_num_str));
4462                         shp->unchecked_isa_dma = 0;
4463                         shp->irq = ha->irq;
4464                         shp->dma_channel = 0xff;
4465                         gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
4466                         NUMDATA(shp)->hanum = (ushort)hanum;
4467                         NUMDATA(shp)->busnum = b;
4468                     }
4469                 }  
4470
4471                 GDTH_INIT_LOCK_HA(ha);
4472                 gdth_enable_int(hanum);
4473             }
4474         }
4475     }
4476
4477     /* scanning for PCI controllers */
4478 #if LINUX_VERSION_CODE < 0x2015C
4479     if (pcibios_present())
4480 #endif
4481     {
4482         gdth_pci_str pcistr[MAXHA];
4483
4484         cnt = gdth_search_pci(pcistr);
4485         printk("GDT: Found %d PCI Storage RAID Controllers\n",cnt);
4486         gdth_sort_pci(pcistr,cnt);
4487         for (ctr = 0; ctr < cnt; ++ctr) {
4488             dma_addr_t scratch_dma_handle;
4489
4490             if (gdth_ctr_count >= MAXHA)
4491                 break;
4492             shp = scsi_register(shtp,sizeof(gdth_ext_str));
4493             if (shp == NULL)
4494                 continue;  
4495
4496             ha = HADATA(shp);
4497             if (!gdth_init_pci(&pcistr[ctr],ha)) {
4498                 scsi_unregister(shp);
4499                 continue;
4500             }
4501             /* controller found and initialized */
4502             printk("GDT CTR%d: Configuring GDT-PCI HA at %d/%d IRQ %u\n",
4503                    ctr,pcistr[ctr].bus,PCI_SLOT(pcistr[ctr].device_fn),ha->irq);
4504
4505 #if LINUX_VERSION_CODE >= 0x010346 
4506             if (request_irq(ha->irq, gdth_interrupt,
4507                             SA_INTERRUPT|SA_SHIRQ, "gdth", ha))
4508 #else
4509             if (request_irq(ha->irq, gdth_interrupt,
4510                             SA_INTERRUPT|SA_SHIRQ, "gdth")) 
4511 #endif
4512             {
4513                 printk("GDT-PCI: Unable to allocate IRQ\n");
4514                 scsi_unregister(shp);
4515                 continue;
4516             }
4517             shp->unchecked_isa_dma = 0;
4518             shp->irq = ha->irq;
4519             shp->dma_channel = 0xff;
4520             hanum = gdth_ctr_count;
4521             gdth_ctr_tab[gdth_ctr_count++] = shp;
4522             gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
4523
4524             NUMDATA(shp)->hanum = (ushort)hanum;
4525             NUMDATA(shp)->busnum= 0;
4526
4527             ha->pccb = CMDDATA(shp);
4528             ha->ccb_phys = 0L;
4529 #if LINUX_VERSION_CODE >= 0x020400
4530             ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, 
4531                                                 &scratch_dma_handle);
4532             ha->scratch_phys = (ulong32)scratch_dma_handle;
4533 #else
4534             ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
4535             if (ha->pscratch)
4536                 ha->scratch_phys = virt_to_bus(ha->pscratch);
4537 #endif
4538             ha->scratch_busy = FALSE;
4539             ha->req_first = NULL;
4540             ha->tid_cnt = pcistr[ctr].device_id >= 0x200 ? MAXID : MAX_HDRIVES;
4541             if (max_ids > 0 && max_ids < ha->tid_cnt)
4542                 ha->tid_cnt = max_ids;
4543             for (i=0; i<GDTH_MAXCMDS; ++i)
4544                 ha->cmd_tab[i].cmnd = UNUSED_CMND;
4545             ha->scan_mode = rescan ? 0x10 : 0;
4546
4547             if (ha->pscratch == NULL || !gdth_search_drives(hanum)) {
4548                 printk("GDT-PCI: Error during device scan\n");
4549                 --gdth_ctr_count;
4550                 --gdth_ctr_vcount;
4551                 if (ha->pscratch != NULL) {
4552 #if LINUX_VERSION_CODE >= 0x020400
4553                     pci_free_consistent(ha->pdev, GDTH_SCRATCH, 
4554                                         ha->pscratch, ha->scratch_phys);
4555 #else
4556                     scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
4557 #endif
4558                 }
4559 #if LINUX_VERSION_CODE >= 0x010346 
4560                 free_irq(ha->irq,ha);
4561 #else
4562                 free_irq(ha->irq);
4563 #endif
4564                 scsi_unregister(shp);
4565                 continue;
4566             }
4567             if (hdr_channel < 0 || hdr_channel > ha->bus_cnt)
4568                 hdr_channel = ha->bus_cnt;
4569             ha->virt_bus = hdr_channel;
4570
4571 #if LINUX_VERSION_CODE >= 0x020000
4572             shp->max_id      = ha->tid_cnt;
4573             shp->max_lun     = MAXLUN;
4574             shp->max_channel = virt_ctr ? 0 : ha->bus_cnt;
4575             if (virt_ctr)  
4576 #endif
4577             {
4578                 virt_ctr = 1;
4579                 /* register addit. SCSI channels as virtual controllers */
4580                 for (b = 1; b < ha->bus_cnt + 1; ++b) {
4581                     shp = scsi_register(shtp,sizeof(gdth_num_str));
4582                     shp->unchecked_isa_dma = 0;
4583                     shp->irq = ha->irq;
4584                     shp->dma_channel = 0xff;
4585                     gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
4586                     NUMDATA(shp)->hanum = (ushort)hanum;
4587                     NUMDATA(shp)->busnum = b;
4588                 }
4589             }  
4590
4591             GDTH_INIT_LOCK_HA(ha);
4592             gdth_enable_int(hanum);
4593         }
4594     }
4595
4596     TRACE2(("gdth_detect() %d controller detected\n",gdth_ctr_count));
4597     if (gdth_ctr_count > 0) {
4598 #ifdef GDTH_STATISTICS
4599         TRACE2(("gdth_detect(): Initializing timer !\n"));
4600         init_timer(&gdth_timer);
4601         gdth_timer.expires = jiffies + HZ;
4602         gdth_timer.data = 0L;
4603         gdth_timer.function = gdth_timeout;
4604         add_timer(&gdth_timer);
4605 #endif
4606 #ifdef GDTH_IOCTL_CHRDEV
4607         major = register_chrdev(0,"gdth",&gdth_fops);
4608 #endif
4609 #if LINUX_VERSION_CODE >= 0x020100
4610         register_reboot_notifier(&gdth_notifier);
4611 #endif
4612     }
4613     gdth_polling = FALSE;
4614     return gdth_ctr_vcount;
4615 }
4616
4617
4618 int gdth_release(struct Scsi_Host *shp)
4619 {
4620     int hanum;
4621     gdth_ha_str *ha;
4622
4623     TRACE2(("gdth_release()\n"));
4624     if (NUMDATA(shp)->busnum == 0) {
4625         hanum = NUMDATA(shp)->hanum;
4626         ha    = HADATA(gdth_ctr_tab[hanum]);
4627 #if LINUX_VERSION_CODE >= 0x010300
4628         gdth_flush(hanum);
4629 #endif
4630
4631         if (shp->irq) {
4632 #if LINUX_VERSION_CODE >= 0x010346
4633             free_irq(shp->irq,ha);
4634 #else
4635             free_irq(shp->irq);
4636 #endif
4637         }
4638 #ifndef __ia64__
4639         if (shp->dma_channel != 0xff) {
4640             free_dma(shp->dma_channel);
4641         }
4642 #endif
4643 #if LINUX_VERSION_CODE >= 0x020400
4644         pci_free_consistent(ha->pdev, GDTH_SCRATCH, 
4645             ha->pscratch, ha->scratch_phys);
4646         if (ha->ccb_phys)
4647             pci_unmap_single(ha->pdev,ha->ccb_phys,
4648                              sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
4649 #else
4650         scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
4651 #endif
4652         gdth_ctr_released++;
4653         TRACE2(("gdth_release(): HA %d of %d\n", 
4654                 gdth_ctr_released, gdth_ctr_count));
4655
4656         if (gdth_ctr_released == gdth_ctr_count) {
4657 #ifdef GDTH_STATISTICS
4658             del_timer(&gdth_timer);
4659 #endif
4660 #ifdef GDTH_IOCTL_CHRDEV
4661             unregister_chrdev(major,"gdth");
4662 #endif
4663 #if LINUX_VERSION_CODE >= 0x020100
4664             unregister_reboot_notifier(&gdth_notifier);
4665 #endif
4666         }
4667     }
4668
4669     scsi_unregister(shp);
4670     return 0;
4671 }
4672             
4673
4674 static const char *gdth_ctr_name(int hanum)
4675 {
4676     gdth_ha_str *ha;
4677
4678     TRACE2(("gdth_ctr_name()\n"));
4679
4680     ha    = HADATA(gdth_ctr_tab[hanum]);
4681
4682     if (ha->type == GDT_EISA) {
4683         switch (ha->stype) {
4684           case GDT3_ID:
4685             return("GDT3000/3020");
4686           case GDT3A_ID:
4687             return("GDT3000A/3020A/3050A");
4688           case GDT3B_ID:
4689             return("GDT3000B/3010A");
4690         }
4691     } else if (ha->type == GDT_ISA) {
4692         return("GDT2000/2020");
4693     } else if (ha->type == GDT_PCI) {
4694         switch (ha->stype) {
4695           case PCI_DEVICE_ID_VORTEX_GDT60x0:
4696             return("GDT6000/6020/6050");
4697           case PCI_DEVICE_ID_VORTEX_GDT6000B:
4698             return("GDT6000B/6010");
4699         }
4700     } 
4701     /* new controllers (GDT_PCINEW, GDT_PCIMPR, ..) use board_info IOCTL! */
4702
4703     return("");
4704 }
4705
4706 const char *gdth_info(struct Scsi_Host *shp)
4707 {
4708     int hanum;
4709     gdth_ha_str *ha;
4710
4711     TRACE2(("gdth_info()\n"));
4712     hanum = NUMDATA(shp)->hanum;
4713     ha    = HADATA(gdth_ctr_tab[hanum]);
4714
4715     return ((const char *)ha->binfo.type_string);
4716 }
4717
4718 /* old error handling */
4719 int gdth_abort(Scsi_Cmnd *scp)
4720 {
4721     TRACE2(("gdth_abort() reason %d\n",scp->abort_reason));
4722     return SCSI_ABORT_SNOOZE;
4723 }
4724
4725 #if LINUX_VERSION_CODE >= 0x010346
4726 int gdth_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
4727 #else
4728 int gdth_reset(Scsi_Cmnd *scp)
4729 #endif
4730 {
4731     TRACE2(("gdth_reset()\n"));
4732     return SCSI_RESET_PUNT;
4733 }
4734
4735 #if LINUX_VERSION_CODE >= 0x02015F
4736 /* new error handling */
4737 int gdth_eh_abort(Scsi_Cmnd *scp)
4738 {
4739     TRACE2(("gdth_eh_abort()\n"));
4740     return FAILED;
4741 }
4742
4743 int gdth_eh_device_reset(Scsi_Cmnd *scp)
4744 {
4745     TRACE2(("gdth_eh_device_reset()\n"));
4746     return FAILED;
4747 }
4748
4749 int gdth_eh_bus_reset(Scsi_Cmnd *scp)
4750 {
4751     int i, hanum;
4752     gdth_ha_str *ha;
4753     ulong flags;
4754     Scsi_Cmnd *cmnd;
4755     unchar b;
4756
4757     TRACE2(("gdth_eh_bus_reset()\n"));
4758 #if LINUX_VERSION_CODE >= 0x02053C
4759     hanum = NUMDATA(scp->device->host)->hanum;
4760     b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
4761 #else
4762     hanum = NUMDATA(scp->host)->hanum;
4763     b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
4764 #endif
4765     ha    = HADATA(gdth_ctr_tab[hanum]);
4766
4767     /* clear command tab */
4768     GDTH_LOCK_HA(ha, flags);
4769     for (i = 0; i < GDTH_MAXCMDS; ++i) {
4770         cmnd = ha->cmd_tab[i].cmnd;
4771 #if LINUX_VERSION_CODE >= 0x02053C
4772         if (!SPECIAL_SCP(cmnd) && cmnd->device->channel == b)
4773 #else
4774         if (!SPECIAL_SCP(cmnd) && cmnd->channel == b)
4775 #endif
4776             ha->cmd_tab[i].cmnd = UNUSED_CMND;
4777     }
4778     GDTH_UNLOCK_HA(ha, flags);
4779
4780     if (b == ha->virt_bus) {
4781         /* host drives */
4782         for (i = 0; i < MAX_HDRIVES; ++i) {
4783             if (ha->hdr[i].present) {
4784                 GDTH_LOCK_HA(ha, flags);
4785                 gdth_polling = TRUE;
4786                 while (gdth_test_busy(hanum))
4787                     gdth_delay(0);
4788                 if (gdth_internal_cmd(hanum, CACHESERVICE, 
4789                                       GDT_CLUST_RESET, i, 0, 0))
4790                     ha->hdr[i].cluster_type &= ~CLUSTER_RESERVED;
4791                 gdth_polling = FALSE;
4792                 GDTH_UNLOCK_HA(ha, flags);
4793             }
4794         }
4795     } else {
4796         /* raw devices */
4797         GDTH_LOCK_HA(ha, flags);
4798         for (i = 0; i < MAXID; ++i)
4799             ha->raw[BUS_L2P(ha,b)].io_cnt[i] = 0;
4800         gdth_polling = TRUE;
4801         while (gdth_test_busy(hanum))
4802             gdth_delay(0);
4803         gdth_internal_cmd(hanum, SCSIRAWSERVICE, GDT_RESET_BUS,
4804                           BUS_L2P(ha,b), 0, 0);
4805         gdth_polling = FALSE;
4806         GDTH_UNLOCK_HA(ha, flags);
4807     }
4808     return SUCCESS;
4809 }
4810
4811 int gdth_eh_host_reset(Scsi_Cmnd *scp)
4812 {
4813     TRACE2(("gdth_eh_host_reset()\n"));
4814     return FAILED;
4815 }
4816 #endif
4817
4818
4819 #if LINUX_VERSION_CODE >= 0x020503
4820 int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,sector_t cap,int *ip)
4821 #elif LINUX_VERSION_CODE >= 0x010300
4822 int gdth_bios_param(Disk *disk,kdev_t dev,int *ip)
4823 #else
4824 int gdth_bios_param(Disk *disk,int dev,int *ip)
4825 #endif
4826 {
4827     unchar b, t;
4828     int hanum;
4829     gdth_ha_str *ha;
4830     struct scsi_device *sd;
4831     unsigned capacity;
4832
4833 #if LINUX_VERSION_CODE >= 0x020503
4834     sd = sdev;
4835     capacity = cap;
4836 #else
4837     sd = disk->device;
4838     capacity = disk->capacity;
4839 #endif
4840     hanum = NUMDATA(sd->host)->hanum;
4841     b = virt_ctr ? NUMDATA(sd->host)->busnum : sd->channel;
4842     t = sd->id;
4843     TRACE2(("gdth_bios_param() ha %d bus %d target %d\n", hanum, b, t)); 
4844     ha = HADATA(gdth_ctr_tab[hanum]);
4845
4846     if (b != ha->virt_bus || ha->hdr[t].heads == 0) {
4847         /* raw device or host drive without mapping information */
4848         TRACE2(("Evaluate mapping\n"));
4849         gdth_eval_mapping(capacity,&ip[2],&ip[0],&ip[1]);
4850     } else {
4851         ip[0] = ha->hdr[t].heads;
4852         ip[1] = ha->hdr[t].secs;
4853         ip[2] = capacity / ip[0] / ip[1];
4854     }
4855
4856     TRACE2(("gdth_bios_param(): %d heads, %d secs, %d cyls\n",
4857             ip[0],ip[1],ip[2]));
4858     return 0;
4859 }
4860
4861
4862 int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *))
4863 {
4864     int hanum;
4865     int priority;
4866
4867     TRACE(("gdth_queuecommand() cmd 0x%x\n", scp->cmnd[0]));
4868     
4869     scp->scsi_done = (void *)done;
4870     scp->SCp.have_data_in = 1;
4871     scp->SCp.phase = -1;
4872     scp->SCp.sent_command = -1;
4873     scp->SCp.Status = GDTH_MAP_NONE;
4874     scp->SCp.buffer = (struct scatterlist *)NULL;
4875 #if LINUX_VERSION_CODE >= 0x02053C
4876     hanum = NUMDATA(scp->device->host)->hanum;
4877 #else
4878     hanum = NUMDATA(scp->host)->hanum;
4879 #endif
4880 #ifdef GDTH_STATISTICS
4881     ++act_ios;
4882 #endif
4883
4884     priority = DEFAULT_PRI;
4885 #if LINUX_VERSION_CODE >= 0x010300
4886     if (scp->done == gdth_scsi_done)
4887         priority = scp->SCp.this_residual;
4888 #endif
4889     gdth_update_timeout(hanum, scp, scp->timeout_per_command * 6);
4890     gdth_putq( hanum, scp, priority );
4891     gdth_next( hanum );
4892     return 0;
4893 }
4894
4895 #ifdef GDTH_IOCTL_CHRDEV
4896 static int gdth_open(struct inode *inode, struct file *filep)
4897 {
4898     TRACE(("gdth_open()\n"));
4899     return 0;
4900 }
4901
4902 static int gdth_close(struct inode *inode, struct file *filep)
4903 {
4904     TRACE(("gdth_close()\n"));
4905     return 0;
4906 }
4907
4908 static int ioc_event(unsigned long arg)
4909 {
4910         gdth_ioctl_event evt;
4911         gdth_ha_str *ha;
4912         ulong flags;
4913
4914         if (copy_from_user(&evt, (char *)arg, sizeof(gdth_ioctl_event)) ||
4915             evt.ionode >= gdth_ctr_count)
4916             return -EFAULT;
4917         ha = HADATA(gdth_ctr_tab[evt.ionode]);
4918
4919         if (evt.erase == 0xff) {
4920             if (evt.event.event_source == ES_TEST)
4921                 evt.event.event_data.size=sizeof(evt.event.event_data.eu.test); 
4922             else if (evt.event.event_source == ES_DRIVER)
4923                 evt.event.event_data.size=sizeof(evt.event.event_data.eu.driver); 
4924             else if (evt.event.event_source == ES_SYNC)
4925                 evt.event.event_data.size=sizeof(evt.event.event_data.eu.sync); 
4926             else
4927                 evt.event.event_data.size=sizeof(evt.event.event_data.eu.async);
4928             GDTH_LOCK_HA(ha, flags);
4929             gdth_store_event(ha, evt.event.event_source, evt.event.event_idx,
4930                              &evt.event.event_data);
4931             GDTH_UNLOCK_HA(ha, flags);
4932         } else if (evt.erase == 0xfe) {
4933             gdth_clear_events();
4934         } else if (evt.erase == 0) {
4935             evt.handle = gdth_read_event(ha, evt.handle, &evt.event);
4936         } else {
4937             gdth_readapp_event(ha, evt.erase, &evt.event);
4938         }     
4939         if (copy_to_user((char *)arg, &evt, sizeof(gdth_ioctl_event)))
4940             return -EFAULT;
4941         return 0;
4942 }
4943
4944 static int ioc_lockdrv(unsigned long arg)
4945 {
4946         gdth_ioctl_lockdrv ldrv;
4947         unchar i, j;
4948         ulong flags;
4949         gdth_ha_str *ha;
4950
4951         if (copy_from_user(&ldrv, (char *)arg, sizeof(gdth_ioctl_lockdrv)) ||
4952             ldrv.ionode >= gdth_ctr_count)
4953             return -EFAULT;
4954         ha = HADATA(gdth_ctr_tab[ldrv.ionode]);
4955  
4956         for (i = 0; i < ldrv.drive_cnt && i < MAX_HDRIVES; ++i) {
4957             j = ldrv.drives[i];
4958             if (j >= MAX_HDRIVES || !ha->hdr[j].present)
4959                 continue;
4960             if (ldrv.lock) {
4961                 GDTH_LOCK_HA(ha, flags);
4962                 ha->hdr[j].lock = 1;
4963                 GDTH_UNLOCK_HA(ha, flags);
4964                 gdth_wait_completion(ldrv.ionode, ha->bus_cnt, j); 
4965                 gdth_stop_timeout(ldrv.ionode, ha->bus_cnt, j); 
4966             } else {
4967                 GDTH_LOCK_HA(ha, flags);
4968                 ha->hdr[j].lock = 0;
4969                 GDTH_UNLOCK_HA(ha, flags);
4970                 gdth_start_timeout(ldrv.ionode, ha->bus_cnt, j); 
4971                 gdth_next(ldrv.ionode); 
4972             }
4973         } 
4974         return 0;
4975 }
4976
4977 static int ioc_resetdrv(unsigned long arg, char *cmnd)
4978 {
4979         gdth_ioctl_reset res;
4980         gdth_cmd_str cmd;
4981         int hanum;
4982         gdth_ha_str *ha;
4983 #if LINUX_VERSION_CODE >= 0x020503
4984         Scsi_Request *srp;
4985         Scsi_Device *sdev;
4986 #elif LINUX_VERSION_CODE >= 0x020322
4987         Scsi_Cmnd *scp;
4988         Scsi_Device *sdev;
4989 #else
4990         Scsi_Cmnd scp;
4991         Scsi_Device sdev;
4992 #endif
4993
4994         if (copy_from_user(&res, (char *)arg, sizeof(gdth_ioctl_reset)) ||
4995             res.ionode >= gdth_ctr_count || res.number >= MAX_HDRIVES)
4996             return -EFAULT;
4997         hanum = res.ionode;
4998         ha = HADATA(gdth_ctr_tab[hanum]);
4999  
5000         if (!ha->hdr[res.number].present)
5001             return 0;
5002         cmd.Service = CACHESERVICE;
5003         cmd.OpCode = GDT_CLUST_RESET;
5004         cmd.u.cache.DeviceNo = res.number;
5005 #if LINUX_VERSION_CODE >= 0x020503
5006         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
5007         srp  = scsi_allocate_request(sdev, GFP_KERNEL);
5008         if (!srp)
5009             return -ENOMEM;
5010         srp->sr_cmd_len = 12;
5011         srp->sr_use_sg = 0;
5012         gdth_do_req(srp, &cmd, cmnd, 30);
5013         res.status = (ushort)srp->sr_command->SCp.Status;
5014         scsi_release_request(srp);
5015         scsi_free_host_dev(sdev);
5016 #elif LINUX_VERSION_CODE >= 0x020322
5017         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
5018         scp  = scsi_allocate_device(sdev, 1, FALSE);
5019         if (!scp)
5020             return -ENOMEM;
5021         scp->cmd_len = 12;
5022         scp->use_sg = 0;
5023         gdth_do_cmd(scp, &cmd, cmnd, 30);
5024         res.status = (ushort)scp->SCp.Status;
5025         scsi_release_command(scp);
5026         scsi_free_host_dev(sdev);
5027 #else
5028         memset(&sdev,0,sizeof(Scsi_Device));
5029         memset(&scp, 0,sizeof(Scsi_Cmnd));
5030         sdev.host = scp.host = gdth_ctr_tab[hanum];
5031         sdev.id = scp.target = sdev.host->this_id;
5032         scp.device = &sdev;
5033         gdth_do_cmd(&scp, &cmd, cmnd, 30);
5034         res.status = (ushort)scp.SCp.Status;
5035 #endif
5036         if (copy_to_user((char *)arg, &res, sizeof(gdth_ioctl_reset)))
5037             return -EFAULT;
5038         return 0;
5039 }
5040
5041 static int ioc_general(unsigned long arg, char *cmnd)
5042 {
5043         gdth_ioctl_general gen;
5044         char *buf = NULL;
5045         ulong32 paddr; 
5046         int hanum;
5047         gdth_ha_str *ha; 
5048 #if LINUX_VERSION_CODE >= 0x020503
5049         Scsi_Request *srp;
5050         Scsi_Device *sdev;
5051 #elif LINUX_VERSION_CODE >= 0x020322
5052         Scsi_Cmnd *scp;
5053         Scsi_Device *sdev;
5054 #else
5055         Scsi_Cmnd scp;
5056         Scsi_Device sdev;
5057 #endif
5058         
5059         if (copy_from_user(&gen, (char *)arg, sizeof(gdth_ioctl_general)) ||
5060             gen.ionode >= gdth_ctr_count)
5061             return -EFAULT;
5062         hanum = gen.ionode; 
5063         ha = HADATA(gdth_ctr_tab[hanum]);
5064         if (gen.data_len + gen.sense_len != 0) {
5065             if (!(buf = gdth_ioctl_alloc(hanum, gen.data_len + gen.sense_len, 
5066                                          FALSE, &paddr)))
5067                 return -EFAULT;
5068             if (copy_from_user(buf, (char *)arg + sizeof(gdth_ioctl_general),  
5069                                gen.data_len + gen.sense_len)) {
5070                 gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
5071                 return -EFAULT;
5072             }
5073
5074             if (gen.command.OpCode == GDT_IOCTL) {
5075                 gen.command.u.ioctl.p_param = paddr;
5076             } else if (gen.command.Service == CACHESERVICE) {
5077                 if (ha->cache_feat & SCATTER_GATHER) {
5078                     gen.command.u.cache.DestAddr = 0xffffffff;
5079                     gen.command.u.cache.sg_canz = 1;
5080                     gen.command.u.cache.sg_lst[0].sg_ptr = paddr;
5081                     gen.command.u.cache.sg_lst[0].sg_len = gen.data_len;
5082                     gen.command.u.cache.sg_lst[1].sg_len = 0;
5083                 } else {
5084                     gen.command.u.cache.DestAddr = paddr;
5085                     gen.command.u.cache.sg_canz = 0;
5086                 }
5087             } else if (gen.command.Service == SCSIRAWSERVICE) {
5088                 if (ha->raw_feat & SCATTER_GATHER) {
5089                     gen.command.u.raw.sdata = 0xffffffff;
5090                     gen.command.u.raw.sg_ranz = 1;
5091                     gen.command.u.raw.sg_lst[0].sg_ptr = paddr;
5092                     gen.command.u.raw.sg_lst[0].sg_len = gen.data_len;
5093                     gen.command.u.raw.sg_lst[1].sg_len = 0;
5094                 } else {
5095                     gen.command.u.raw.sdata = paddr;
5096                     gen.command.u.raw.sg_ranz = 0;
5097                 }
5098                 gen.command.u.raw.sense_data = paddr + gen.data_len;
5099
5100             } else {
5101                 gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
5102                 return -EFAULT;
5103             }
5104         }
5105
5106 #if LINUX_VERSION_CODE >= 0x020503
5107         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
5108         srp  = scsi_allocate_request(sdev, GFP_KERNEL);
5109         if (!srp)
5110             return -ENOMEM;
5111         srp->sr_cmd_len = 12;
5112         srp->sr_use_sg = 0;
5113         gdth_do_req(srp, &gen.command, cmnd, gen.timeout);
5114         gen.status = srp->sr_command->SCp.Status;
5115         gen.info = srp->sr_command->SCp.Message;
5116         scsi_release_request(srp);
5117         scsi_free_host_dev(sdev);
5118 #elif LINUX_VERSION_CODE >= 0x020322
5119         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
5120         scp  = scsi_allocate_device(sdev, 1, FALSE);
5121         if (!scp)
5122             return -ENOMEM;
5123         scp->cmd_len = 12;
5124         scp->use_sg = 0;
5125         gdth_do_cmd(scp, &gen.command, cmnd, gen.timeout);
5126         gen.status = scp->SCp.Status;
5127         gen.info = scp->SCp.Message;
5128         scsi_release_command(scp);
5129         scsi_free_host_dev(sdev);
5130 #else
5131         memset(&sdev,0,sizeof(Scsi_Device));
5132         memset(&scp, 0,sizeof(Scsi_Cmnd));
5133         sdev.host = scp.host = gdth_ctr_tab[hanum];
5134         sdev.id = scp.target = sdev.host->this_id;
5135         scp.device = &sdev;
5136         gdth_do_cmd(&scp, &gen.command, cmnd, gen.timeout);
5137         gen.status = scp.SCp.Status;
5138         gen.info = scp.SCp.Message;
5139 #endif
5140
5141         if (copy_to_user((char *)arg + sizeof(gdth_ioctl_general), buf, 
5142                          gen.data_len + gen.sense_len)) {
5143             gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
5144             return -EFAULT; 
5145         } 
5146         if (copy_to_user((char *)arg, &gen, 
5147             sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str))) {
5148             gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
5149             return -EFAULT;
5150         }
5151         gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
5152         return 0;
5153 }
5154  
5155 static int ioc_hdrlist(unsigned long arg, char *cmnd)
5156 {
5157         gdth_ioctl_rescan rsc;
5158         gdth_cmd_str cmd;
5159         gdth_ha_str *ha;
5160         unchar i;
5161         int hanum;
5162 #if LINUX_VERSION_CODE >= 0x020503
5163         Scsi_Request *srp;
5164         Scsi_Device *sdev;
5165 #elif LINUX_VERSION_CODE >= 0x020322
5166         Scsi_Cmnd *scp;
5167         Scsi_Device *sdev;
5168 #else
5169         Scsi_Cmnd scp;
5170         Scsi_Device sdev;
5171 #endif
5172         
5173         if (copy_from_user(&rsc, (char *)arg, sizeof(gdth_ioctl_rescan)) ||
5174             rsc.ionode >= gdth_ctr_count)
5175             return -EFAULT;
5176         hanum = rsc.ionode;
5177         ha = HADATA(gdth_ctr_tab[hanum]);
5178    
5179 #if LINUX_VERSION_CODE >= 0x020503
5180         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
5181         srp  = scsi_allocate_request(sdev, GFP_KERNEL);
5182         if (!srp)
5183             return -ENOMEM;
5184         srp->sr_cmd_len = 12;
5185         srp->sr_use_sg = 0;
5186 #elif LINUX_VERSION_CODE >= 0x020322
5187         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
5188         scp  = scsi_allocate_device(sdev, 1, FALSE);
5189         if (!scp)
5190             return -ENOMEM;
5191         scp->cmd_len = 12;
5192         scp->use_sg = 0;
5193 #else
5194         memset(&sdev,0,sizeof(Scsi_Device));
5195         memset(&scp, 0,sizeof(Scsi_Cmnd));
5196         sdev.host = scp.host = gdth_ctr_tab[hanum];
5197         sdev.id = scp.target = sdev.host->this_id;
5198         scp.device = &sdev;
5199 #endif
5200
5201         for (i = 0; i < MAX_HDRIVES; ++i) { 
5202             if (!ha->hdr[i].present) {
5203                 rsc.hdr_list[i].bus = 0xff; 
5204                 continue;
5205             } 
5206             rsc.hdr_list[i].bus = ha->virt_bus;
5207             rsc.hdr_list[i].target = i;
5208             rsc.hdr_list[i].lun = 0;
5209             rsc.hdr_list[i].cluster_type = ha->hdr[i].cluster_type;
5210             if (ha->hdr[i].cluster_type & CLUSTER_DRIVE) { 
5211                 cmd.Service = CACHESERVICE;
5212                 cmd.OpCode = GDT_CLUST_INFO;
5213                 cmd.u.cache.DeviceNo = i;
5214 #if LINUX_VERSION_CODE >= 0x020503
5215                 gdth_do_req(srp, &cmd, cmnd, 30);
5216                 if (srp->sr_command->SCp.Status == S_OK)
5217                     rsc.hdr_list[i].cluster_type = srp->sr_command->SCp.Message;
5218 #elif LINUX_VERSION_CODE >= 0x020322
5219                 gdth_do_cmd(scp, &cmd, cmnd, 30);
5220                 if (scp->SCp.Status == S_OK)
5221                     rsc.hdr_list[i].cluster_type = scp->SCp.Message;
5222 #else
5223                 gdth_do_cmd(&scp, &cmd, cmnd, 30);
5224                 if (scp.SCp.Status == S_OK)
5225                     rsc.hdr_list[i].cluster_type = scp.SCp.Message;
5226 #endif
5227             }
5228         } 
5229 #if LINUX_VERSION_CODE >= 0x020503
5230         scsi_release_request(srp);
5231         scsi_free_host_dev(sdev);
5232 #elif LINUX_VERSION_CODE >= 0x020322
5233         scsi_release_command(scp);
5234         scsi_free_host_dev(sdev);
5235 #endif       
5236  
5237         if (copy_to_user((char *)arg, &rsc, sizeof(gdth_ioctl_rescan)))
5238             return -EFAULT;
5239         return 0;
5240 }
5241
5242 static int ioc_rescan(unsigned long arg, char *cmnd)
5243 {
5244         gdth_ioctl_rescan rsc;
5245         gdth_cmd_str cmd;
5246         ushort i, status, hdr_cnt;
5247         ulong32 info;
5248         int hanum, cyls, hds, secs;
5249         ulong flags;
5250         gdth_ha_str *ha; 
5251 #if LINUX_VERSION_CODE >= 0x020503
5252         Scsi_Request *srp;
5253         Scsi_Device *sdev;
5254 #elif LINUX_VERSION_CODE >= 0x020322
5255         Scsi_Cmnd *scp;
5256         Scsi_Device *sdev;
5257 #else
5258         Scsi_Cmnd scp;
5259         Scsi_Device sdev;
5260 #endif
5261         
5262         if (copy_from_user(&rsc, (char *)arg, sizeof(gdth_ioctl_rescan)) ||
5263             rsc.ionode >= gdth_ctr_count)
5264             return -EFAULT;
5265         hanum = rsc.ionode;
5266         ha = HADATA(gdth_ctr_tab[hanum]);
5267
5268 #if LINUX_VERSION_CODE >= 0x020503
5269         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
5270         srp  = scsi_allocate_request(sdev, GFP_KERNEL);
5271         if (!srp)
5272             return -ENOMEM;
5273         srp->sr_cmd_len = 12;
5274         srp->sr_use_sg = 0;
5275 #elif LINUX_VERSION_CODE >= 0x020322
5276         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
5277         scp  = scsi_allocate_device(sdev, 1, FALSE);
5278         if (!scp)
5279             return -ENOMEM;
5280         scp->cmd_len = 12;
5281         scp->use_sg = 0;
5282 #else
5283         memset(&sdev,0,sizeof(Scsi_Device));
5284         memset(&scp, 0,sizeof(Scsi_Cmnd));
5285         sdev.host = scp.host = gdth_ctr_tab[hanum];
5286         sdev.id = scp.target = sdev.host->this_id;
5287         scp.device = &sdev;
5288 #endif
5289      
5290         if (rsc.flag == 0) {
5291             /* old method: re-init. cache service */
5292             cmd.Service = CACHESERVICE;
5293             cmd.OpCode = GDT_INIT;
5294             cmd.u.cache.DeviceNo = LINUX_OS;
5295 #if LINUX_VERSION_CODE >= 0x020503
5296             gdth_do_req(srp, &cmd, cmnd, 30);
5297             status = (ushort)srp->sr_command->SCp.Status;
5298             info = (ulong32)srp->sr_command->SCp.Message;
5299 #elif LINUX_VERSION_CODE >= 0x020322
5300             gdth_do_cmd(scp, &cmd, cmnd, 30);
5301             status = (ushort)scp->SCp.Status;
5302             info = (ulong32)scp->SCp.Message;
5303 #else
5304             gdth_do_cmd(&scp, &cmd, cmnd, 30);
5305             status = (ushort)scp.SCp.Status;
5306             info = (ulong32)scp.SCp.Message;
5307 #endif
5308             i = 0;
5309             hdr_cnt = (status == S_OK ? (ushort)info : 0);
5310         } else {
5311             i = rsc.hdr_no;
5312             hdr_cnt = i + 1;
5313         }
5314         for (; i < hdr_cnt && i < MAX_HDRIVES; ++i) {
5315             cmd.Service = CACHESERVICE;
5316             cmd.OpCode = GDT_INFO;
5317             cmd.u.cache.DeviceNo = i;
5318 #if LINUX_VERSION_CODE >= 0x020503
5319             gdth_do_req(srp, &cmd, cmnd, 30);
5320             status = (ushort)srp->sr_command->SCp.Status;
5321             info = (ulong32)srp->sr_command->SCp.Message;
5322 #elif LINUX_VERSION_CODE >= 0x020322
5323             gdth_do_cmd(scp, &cmd, cmnd, 30);
5324             status = (ushort)scp->SCp.Status;
5325             info = (ulong32)scp->SCp.Message;
5326 #else
5327             gdth_do_cmd(&scp, &cmd, cmnd, 30);
5328             status = (ushort)scp.SCp.Status;
5329             info = (ulong32)scp.SCp.Message;
5330 #endif
5331             GDTH_LOCK_HA(ha, flags);
5332             rsc.hdr_list[i].bus = ha->virt_bus;
5333             rsc.hdr_list[i].target = i;
5334             rsc.hdr_list[i].lun = 0;
5335             if (status != S_OK) {
5336                 ha->hdr[i].present = FALSE;
5337             } else {
5338                 ha->hdr[i].present = TRUE;
5339                 ha->hdr[i].size = info;
5340                 /* evaluate mapping */
5341                 ha->hdr[i].size &= ~SECS32;
5342                 gdth_eval_mapping(ha->hdr[i].size,&cyls,&hds,&secs); 
5343                 ha->hdr[i].heads = hds;
5344                 ha->hdr[i].secs = secs;
5345                 /* round size */
5346                 ha->hdr[i].size = cyls * hds * secs;
5347             }
5348             GDTH_UNLOCK_HA(ha, flags);
5349             if (status != S_OK)
5350                 continue; 
5351
5352             /* devtype, cluster info, R/W attribs */
5353             cmd.Service = CACHESERVICE;
5354             cmd.OpCode = GDT_DEVTYPE;
5355             cmd.u.cache.DeviceNo = i;
5356 #if LINUX_VERSION_CODE >= 0x020503
5357             gdth_do_req(srp, &cmd, cmnd, 30);
5358             status = (ushort)srp->sr_command->SCp.Status;
5359             info = (ulong32)srp->sr_command->SCp.Message;
5360 #elif LINUX_VERSION_CODE >= 0x020322
5361             gdth_do_cmd(scp, &cmd, cmnd, 30);
5362             status = (ushort)scp->SCp.Status;
5363             info = (ulong32)scp->SCp.Message;
5364 #else
5365             gdth_do_cmd(&scp, &cmd, cmnd, 30);
5366             status = (ushort)scp.SCp.Status;
5367             info = (ulong32)scp.SCp.Message;
5368 #endif
5369             GDTH_LOCK_HA(ha, flags);
5370             ha->hdr[i].devtype = (status == S_OK ? (ushort)info : 0);
5371             GDTH_UNLOCK_HA(ha, flags);
5372
5373             cmd.Service = CACHESERVICE;
5374             cmd.OpCode = GDT_CLUST_INFO;
5375             cmd.u.cache.DeviceNo = i;
5376 #if LINUX_VERSION_CODE >= 0x020503
5377             gdth_do_req(srp, &cmd, cmnd, 30);
5378             status = (ushort)srp->sr_command->SCp.Status;
5379             info = (ulong32)srp->sr_command->SCp.Message;
5380 #elif LINUX_VERSION_CODE >= 0x020322
5381             gdth_do_cmd(scp, &cmd, cmnd, 30);
5382             status = (ushort)scp->SCp.Status;
5383             info = (ulong32)scp->SCp.Message;
5384 #else
5385             gdth_do_cmd(&scp, &cmd, cmnd, 30);
5386             status = (ushort)scp.SCp.Status;
5387             info = (ulong32)scp.SCp.Message;
5388 #endif
5389             GDTH_LOCK_HA(ha, flags);
5390             ha->hdr[i].cluster_type = 
5391                 ((status == S_OK && !shared_access) ? (ushort)info : 0);
5392             GDTH_UNLOCK_HA(ha, flags);
5393             rsc.hdr_list[i].cluster_type = ha->hdr[i].cluster_type;
5394
5395             cmd.Service = CACHESERVICE;
5396             cmd.OpCode = GDT_RW_ATTRIBS;
5397             cmd.u.cache.DeviceNo = i;
5398 #if LINUX_VERSION_CODE >= 0x020503
5399             gdth_do_req(srp, &cmd, cmnd, 30);
5400             status = (ushort)srp->sr_command->SCp.Status;
5401             info = (ulong32)srp->sr_command->SCp.Message;
5402 #elif LINUX_VERSION_CODE >= 0x020322
5403             gdth_do_cmd(scp, &cmd, cmnd, 30);
5404             status = (ushort)scp->SCp.Status;
5405             info = (ulong32)scp->SCp.Message;
5406 #else
5407             gdth_do_cmd(&scp, &cmd, cmnd, 30);
5408             status = (ushort)scp.SCp.Status;
5409             info = (ulong32)scp.SCp.Message;
5410 #endif
5411             GDTH_LOCK_HA(ha, flags);
5412             ha->hdr[i].rw_attribs = (status == S_OK ? (ushort)info : 0);
5413             GDTH_UNLOCK_HA(ha, flags);
5414         }
5415 #if LINUX_VERSION_CODE >= 0x020503
5416         scsi_release_request(srp);
5417         scsi_free_host_dev(sdev);
5418 #elif LINUX_VERSION_CODE >= 0x020322
5419         scsi_release_command(scp);
5420         scsi_free_host_dev(sdev);
5421 #endif       
5422  
5423         if (copy_to_user((char *)arg, &rsc, sizeof(gdth_ioctl_rescan)))
5424             return -EFAULT;
5425         return 0;
5426 }
5427   
5428 static int gdth_ioctl(struct inode *inode, struct file *filep,
5429                       unsigned int cmd, unsigned long arg)
5430 {
5431     gdth_ha_str *ha; 
5432 #if LINUX_VERSION_CODE >= 0x020503
5433     Scsi_Cmnd *scp;
5434     Scsi_Device *sdev;
5435 #elif LINUX_VERSION_CODE >= 0x020322
5436     Scsi_Cmnd *scp;
5437     Scsi_Device *sdev;
5438 #else
5439     Scsi_Cmnd scp;
5440     Scsi_Device sdev;
5441 #endif
5442     ulong flags;
5443     char cmnd[MAX_COMMAND_SIZE];   
5444
5445     memset(cmnd, 0xff, 12);
5446     
5447     TRACE(("gdth_ioctl() cmd 0x%x\n", cmd));
5448  
5449     switch (cmd) {
5450       case GDTIOCTL_CTRCNT:
5451       { 
5452         int cnt = gdth_ctr_count;
5453         if (put_user(cnt, (int *)arg))
5454                 return -EFAULT;
5455         break;
5456       }
5457
5458       case GDTIOCTL_DRVERS:
5459       { 
5460         int ver = (GDTH_VERSION<<8) | GDTH_SUBVERSION;
5461         if (put_user(ver, (int *)arg))
5462                 return -EFAULT;
5463         break;
5464       }
5465       
5466       case GDTIOCTL_OSVERS:
5467       { 
5468         gdth_ioctl_osvers osv; 
5469
5470         osv.version = (unchar)(LINUX_VERSION_CODE >> 16);
5471         osv.subversion = (unchar)(LINUX_VERSION_CODE >> 8);
5472         osv.revision = (ushort)(LINUX_VERSION_CODE & 0xff);
5473         if (copy_to_user((char *)arg, &osv, sizeof(gdth_ioctl_osvers)))
5474                 return -EFAULT;
5475         break;
5476       }
5477
5478       case GDTIOCTL_CTRTYPE:
5479       { 
5480         gdth_ioctl_ctrtype ctrt;
5481         
5482         if (copy_from_user(&ctrt, (char *)arg, sizeof(gdth_ioctl_ctrtype)) ||
5483             ctrt.ionode >= gdth_ctr_count)
5484             return -EFAULT;
5485         ha = HADATA(gdth_ctr_tab[ctrt.ionode]);
5486         if (ha->type == GDT_ISA || ha->type == GDT_EISA) {
5487             ctrt.type = (unchar)((ha->stype>>20) - 0x10);
5488         } else {
5489             if (ha->type != GDT_PCIMPR) {
5490                 ctrt.type = (unchar)((ha->stype<<4) + 6);
5491             } else {
5492                 ctrt.type = 
5493                     (ha->oem_id == OEM_ID_INTEL ? 0xfd : 0xfe);
5494                 if (ha->stype >= 0x300)
5495                     ctrt.ext_type = 0x6000 | ha->subdevice_id;
5496                 else 
5497                     ctrt.ext_type = 0x6000 | ha->stype;
5498             }
5499             ctrt.device_id = ha->stype;
5500             ctrt.sub_device_id = ha->subdevice_id;
5501         }
5502         ctrt.info = ha->brd_phys;
5503         ctrt.oem_id = ha->oem_id;
5504         if (copy_to_user((char *)arg, &ctrt, sizeof(gdth_ioctl_ctrtype)))
5505             return -EFAULT;
5506         break;
5507       }
5508         
5509       case GDTIOCTL_GENERAL:
5510         return ioc_general(arg, cmnd);
5511
5512       case GDTIOCTL_EVENT:
5513         return ioc_event(arg);
5514
5515       case GDTIOCTL_LOCKDRV:
5516         return ioc_lockdrv(arg);
5517
5518       case GDTIOCTL_LOCKCHN:
5519       {
5520         gdth_ioctl_lockchn lchn;
5521         unchar i, j;
5522
5523         if (copy_from_user(&lchn, (char *)arg, sizeof(gdth_ioctl_lockchn)) ||
5524             lchn.ionode >= gdth_ctr_count)
5525             return -EFAULT;
5526         ha = HADATA(gdth_ctr_tab[lchn.ionode]);
5527         
5528         i = lchn.channel;
5529         if (i < ha->bus_cnt) {
5530             if (lchn.lock) {
5531                 GDTH_LOCK_HA(ha, flags);
5532                 ha->raw[i].lock = 1;
5533                 GDTH_UNLOCK_HA(ha, flags);
5534                 for (j = 0; j < ha->tid_cnt; ++j) {
5535                     gdth_wait_completion(lchn.ionode, i, j); 
5536                     gdth_stop_timeout(lchn.ionode, i, j); 
5537                 }
5538             } else {
5539                 GDTH_LOCK_HA(ha, flags);
5540                 ha->raw[i].lock = 0;
5541                 GDTH_UNLOCK_HA(ha, flags);
5542                 for (j = 0; j < ha->tid_cnt; ++j) {
5543                     gdth_start_timeout(lchn.ionode, i, j); 
5544                     gdth_next(lchn.ionode); 
5545                 }
5546             }
5547         } 
5548         break;
5549       }
5550
5551       case GDTIOCTL_RESCAN:
5552         return ioc_rescan(arg, cmnd);
5553
5554       case GDTIOCTL_HDRLIST:
5555         return ioc_hdrlist(arg, cmnd);
5556
5557       case GDTIOCTL_RESET_BUS:
5558       {
5559         gdth_ioctl_reset res;
5560         int hanum, rval;
5561
5562         if (copy_from_user(&res, (char *)arg, sizeof(gdth_ioctl_reset)) ||
5563             res.ionode >= gdth_ctr_count)
5564             return -EFAULT;
5565         hanum = res.ionode; 
5566
5567         /* Because we need a Scsi_Cmnd struct., we make a scsi_allocate device also for kernels >=2.5.x */        
5568 #if LINUX_VERSION_CODE >= 0x02053C
5569         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
5570         scp  = scsi_get_command(sdev, GFP_KERNEL);
5571         if (!scp)
5572             return -ENOMEM;
5573         scp->cmd_len = 12;
5574         scp->use_sg = 0;
5575         scp->device->channel = virt_ctr ? 0 : res.number;
5576         rval = gdth_eh_bus_reset(scp);
5577         res.status = (rval == SUCCESS ? S_OK : S_GENERR);
5578         scsi_put_command(scp);
5579         scsi_free_host_dev(sdev);
5580 #elif LINUX_VERSION_CODE >= 0x020322
5581         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
5582 #if LINUX_VERSION_CODE >= 0x020503
5583         scp  = scsi_allocate_device(sdev, 1);
5584 #else
5585         scp  = scsi_allocate_device(sdev, 1, FALSE);
5586 #endif
5587         if (!scp)
5588             return -ENOMEM;
5589         scp->cmd_len = 12;
5590         scp->use_sg = 0;
5591         scp->channel = virt_ctr ? 0 : res.number;
5592         rval = gdth_eh_bus_reset(scp);
5593         res.status = (rval == SUCCESS ? S_OK : S_GENERR);
5594         scsi_release_command(scp);
5595         scsi_free_host_dev(sdev);
5596 #elif LINUX_VERSION_CODE >= 0x02015F
5597         memset(&sdev,0,sizeof(Scsi_Device));
5598         memset(&scp, 0,sizeof(Scsi_Cmnd));
5599         sdev.host = scp.host = gdth_ctr_tab[hanum];
5600         sdev.id = scp.target = sdev.host->this_id;
5601         scp.device = &sdev;
5602         scp.channel = virt_ctr ? 0 : res.number;
5603         rval = gdth_eh_bus_reset(&scp);
5604         res.status = (rval == SUCCESS ? S_OK : S_GENERR);
5605 #else
5606         res.status = S_OK;
5607 #endif
5608         if (copy_to_user((char *)arg, &res, sizeof(gdth_ioctl_reset)))
5609             return -EFAULT;
5610         break;
5611       }
5612
5613       case GDTIOCTL_RESET_DRV:
5614         return ioc_resetdrv(arg, cmnd);
5615
5616       default:
5617         break; 
5618     }
5619     return 0;
5620 }
5621 #endif
5622
5623 #if LINUX_VERSION_CODE >= 0x010300
5624 /* flush routine */
5625 static void gdth_flush(int hanum)
5626 {
5627     int             i;
5628     gdth_ha_str     *ha;
5629     gdth_cmd_str    gdtcmd;
5630 #if LINUX_VERSION_CODE >= 0x020503
5631     Scsi_Request    *srp;
5632     Scsi_Device     *sdev;
5633 #elif LINUX_VERSION_CODE >= 0x020322
5634     Scsi_Cmnd       *scp;
5635     Scsi_Device     *sdev;
5636 #else
5637     Scsi_Cmnd       scp;
5638     Scsi_Device     sdev;
5639 #endif
5640     char            cmnd[MAX_COMMAND_SIZE];   
5641     memset(cmnd, 0xff, MAX_COMMAND_SIZE);
5642
5643     TRACE2(("gdth_flush() hanum %d\n",hanum));
5644     ha = HADATA(gdth_ctr_tab[hanum]);
5645
5646 #if LINUX_VERSION_CODE >= 0x020503
5647     sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
5648     srp  = scsi_allocate_request(sdev, GFP_KERNEL);
5649     if (!srp)
5650         return;
5651     srp->sr_cmd_len = 12;
5652     srp->sr_use_sg = 0;
5653 #elif LINUX_VERSION_CODE >= 0x020322
5654     sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
5655     scp  = scsi_allocate_device(sdev, 1, FALSE);
5656     if (!scp)
5657         return;
5658     scp->cmd_len = 12;
5659     scp->use_sg = 0;
5660 #else
5661     memset(&sdev,0,sizeof(Scsi_Device));
5662     memset(&scp, 0,sizeof(Scsi_Cmnd));
5663     sdev.host = scp.host = gdth_ctr_tab[hanum];
5664     sdev.id = scp.target = sdev.host->this_id;
5665     scp.device = &sdev;
5666 #endif
5667
5668     for (i = 0; i < MAX_HDRIVES; ++i) {
5669         if (ha->hdr[i].present) {
5670             gdtcmd.BoardNode = LOCALBOARD;
5671             gdtcmd.Service = CACHESERVICE;
5672             gdtcmd.OpCode = GDT_FLUSH;
5673             gdtcmd.u.cache.DeviceNo = i;
5674             gdtcmd.u.cache.BlockNo = 1;
5675             gdtcmd.u.cache.sg_canz = 0;
5676             TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i));
5677 #if LINUX_VERSION_CODE >= 0x020503
5678             gdth_do_req(srp, &gdtcmd, cmnd, 30);
5679 #elif LINUX_VERSION_CODE >= 0x020322
5680             gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
5681 #else
5682             gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
5683 #endif
5684         }
5685     }
5686 #if LINUX_VERSION_CODE >= 0x020503
5687     scsi_release_request(srp);
5688     scsi_free_host_dev(sdev);
5689 #elif LINUX_VERSION_CODE >= 0x020322
5690     scsi_release_command(scp);
5691     scsi_free_host_dev(sdev);
5692 #endif
5693 }
5694
5695 /* shutdown routine */
5696 #if LINUX_VERSION_CODE >= 0x020100
5697 static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
5698 #else
5699 void gdth_halt(void)
5700 #endif
5701 {
5702     int             hanum;
5703 #ifndef __alpha__
5704     gdth_cmd_str    gdtcmd;
5705 #if LINUX_VERSION_CODE >= 0x020503
5706     Scsi_Request    *srp;
5707     Scsi_Device     *sdev;
5708 #elif LINUX_VERSION_CODE >= 0x020322
5709     Scsi_Cmnd       *scp;
5710     Scsi_Device     *sdev;
5711 #else
5712     Scsi_Cmnd       scp;
5713     Scsi_Device     sdev;
5714 #endif
5715     char            cmnd[MAX_COMMAND_SIZE];   
5716 #endif
5717
5718 #if LINUX_VERSION_CODE >= 0x020100
5719     TRACE2(("gdth_halt() event %d\n",(int)event));
5720     if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
5721         return NOTIFY_DONE;
5722 #else
5723     TRACE2(("gdth_halt()\n"));
5724     if (halt_called) {
5725         TRACE2(("already called\n"));
5726         return;
5727     }
5728     halt_called = TRUE;
5729 #endif
5730
5731     printk("GDT: Flushing all host drives .. ");
5732     for (hanum = 0; hanum < gdth_ctr_count; ++hanum) {
5733         gdth_flush(hanum);
5734
5735 #ifndef __alpha__
5736         /* controller reset */
5737         memset(cmnd, 0xff, MAX_COMMAND_SIZE);
5738         gdtcmd.BoardNode = LOCALBOARD;
5739         gdtcmd.Service = CACHESERVICE;
5740         gdtcmd.OpCode = GDT_RESET;
5741         TRACE2(("gdth_halt(): reset controller %d\n", hanum));
5742 #if LINUX_VERSION_CODE >= 0x020503
5743         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
5744         srp  = scsi_allocate_request(sdev, GFP_KERNEL);
5745         if (!srp) {
5746 #if LINUX_VERSION_CODE >= 0x020100
5747             unregister_reboot_notifier(&gdth_notifier);
5748             return NOTIFY_OK;
5749 #else
5750             return;
5751 #endif
5752         }
5753         srp->sr_cmd_len = 12;
5754         srp->sr_use_sg = 0;
5755         gdth_do_req(srp, &gdtcmd, cmnd, 10);
5756         scsi_release_request(srp);
5757         scsi_free_host_dev(sdev);
5758 #elif LINUX_VERSION_CODE >= 0x020322
5759         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
5760         scp  = scsi_allocate_device(sdev, 1, FALSE);
5761         if (!scp) {
5762 #if LINUX_VERSION_CODE >= 0x020100
5763             unregister_reboot_notifier(&gdth_notifier);
5764             return NOTIFY_OK;
5765 #else
5766             return;
5767 #endif
5768         }
5769         scp->cmd_len = 12;
5770         scp->use_sg = 0;
5771         gdth_do_cmd(scp, &gdtcmd, cmnd, 10);
5772         scsi_release_command(scp);
5773         scsi_free_host_dev(sdev);
5774 #else
5775         memset(&sdev,0,sizeof(Scsi_Device));
5776         memset(&scp, 0,sizeof(Scsi_Cmnd));
5777         sdev.host = scp.host = gdth_ctr_tab[hanum];
5778         sdev.id = scp.target = sdev.host->this_id;
5779         scp.device = &sdev;
5780         gdth_do_cmd(&scp, &gdtcmd, cmnd, 10);
5781 #endif
5782 #endif
5783     }
5784     printk("Done.\n");
5785
5786 #ifdef GDTH_STATISTICS
5787     del_timer(&gdth_timer);
5788 #endif
5789 #if LINUX_VERSION_CODE >= 0x020100
5790     unregister_reboot_notifier(&gdth_notifier);
5791     return NOTIFY_OK;
5792 #endif
5793 }
5794 #endif
5795
5796
5797 #if LINUX_VERSION_CODE < 0x020400 && !defined(MODULE)
5798
5799 GDTH_INITFUNC(void, gdth_setup(char *str,int *ints)) 
5800 {    
5801     TRACE2(("gdth_setup() str %s ints[0] %d\n", 
5802             str ? str:"NULL", ints ? ints[0]:0));
5803     internal_setup(str, ints);
5804 }
5805
5806 #else
5807
5808 static Scsi_Host_Template driver_template = {
5809 #if LINUX_VERSION_CODE >= 0x02015F
5810         .proc_name              = "gdth", 
5811 #else
5812         .proc_dir               = &proc_scsi_gdth,
5813 #endif
5814         .proc_info              = gdth_proc_info,
5815         .name                   = "GDT SCSI Disk Array Controller",
5816         .detect                 = gdth_detect, 
5817         .release                = gdth_release,
5818         .info                   = gdth_info, 
5819         .queuecommand           = gdth_queuecommand,
5820         .eh_abort_handler       = gdth_eh_abort, 
5821         .eh_device_reset_handler = gdth_eh_device_reset,
5822         .eh_bus_reset_handler   = gdth_eh_bus_reset,
5823         .eh_host_reset_handler  = gdth_eh_host_reset,
5824         .bios_param             = gdth_bios_param,
5825         .can_queue              = GDTH_MAXCMDS,
5826         .this_id                = -1,
5827         .sg_tablesize           = GDTH_MAXSG,
5828         .cmd_per_lun            = GDTH_MAXC_P_L,
5829         .unchecked_isa_dma      = 1,
5830         .use_clustering         = ENABLE_CLUSTERING,
5831 #if LINUX_VERSION_CODE < 0x020501
5832         .use_new_eh_code        = 1,
5833 #endif
5834 };
5835
5836 #include "scsi_module.c"
5837 #ifndef MODULE
5838 __setup("gdth=", option_setup);
5839 #endif
5840
5841 #endif