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