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