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