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