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