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