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