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