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