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