netdev
[Top] [All Lists]

[PATCH] remove iph5526 driver

To: netdev@xxxxxxxxxxx, linux-scsi@xxxxxxxxxxxxxxx
Subject: [PATCH] remove iph5526 driver
From: Christoph Hellwig <hch@xxxxxx>
Date: Mon, 6 Sep 2004 12:10:14 +0200
Sender: netdev-bounce@xxxxxxxxxxx
User-agent: Mutt/1.3.28i
This driver is for totally obsolete early fibrechannel hardware and
doesn't compile anymore since early 2.5.x.  In addition it'll require
a major rewrite to fit into the current framework for fc drivers.


--- 1.91/drivers/net/Kconfig    2004-09-03 11:08:21 +02:00
+++ edited/drivers/net/Kconfig  2004-09-06 11:56:04 +02:00
@@ -2618,15 +2618,6 @@
          adaptor below. You also should have said Y to "SCSI support" and
          "SCSI generic support".
 
-config IPHASE5526
-       tristate "Interphase 5526 Tachyon chipset based adapter support"
-       depends on NET_FC && SCSI && PCI && BROKEN
-       help
-         Say Y here if you have a Fibre Channel adaptor of this kind.
-
-         To compile this driver as a module, choose M here: the module
-         will be called iph5526.
-
 config SHAPER
        tristate "Traffic Shaper (EXPERIMENTAL)"
        depends on NETDEVICES && EXPERIMENTAL
===== drivers/net/fc/Makefile 1.5 vs edited =====
--- 1.5/drivers/net/fc/Makefile 2002-12-14 13:38:56 +01:00
+++ edited/drivers/net/fc/Makefile      2004-09-06 11:54:26 +02:00
@@ -1,8 +0,0 @@
-#
-# Makefile for linux/drivers/net/fc
-#
-# 9 Aug 2000, Christoph Hellwig <hch@xxxxxxxxxxxxx>
-# Rewritten to use lists instead of if-statements.
-#
-
-obj-$(CONFIG_IPHASE5526)       += iph5526.o
===== drivers/net/fc/iph5526.c 1.35 vs edited =====
--- 1.35/drivers/net/fc/iph5526.c       2004-06-19 17:54:02 +02:00
+++ edited/drivers/net/fc/iph5526.c     2004-09-06 11:53:59 +02:00
@@ -1,4645 +0,0 @@
-/**********************************************************************
- * iph5526.c: IP/SCSI driver for the Interphase 5526 PCI Fibre Channel
- *                       Card.
- * Copyright (C) 1999 Vineet M Abraham <vmabraham@xxxxxxxxxxx>
- *
- * This program is free software; you can redistribute it and/or 
- * modify it under the terms of the GNU General Public License as 
- * published by the Free Software Foundation; either version 2, or 
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *********************************************************************/
-/**********************************************************************
-Log:
-Vineet M Abraham
-02.12.99 Support multiple cards.
-03.15.99 Added Fabric support.
-04.04.99 Added N_Port support.
-04.15.99 Added SCSI support.
-06.18.99 Added ABTS Protocol.
-06.24.99 Fixed data corruption when multiple XFER_RDYs are received.
-07.07.99 Can be loaded as part of the Kernel. Changed semaphores. Added
-         more checks before invalidating SEST entries.
-07.08.99 Added Broadcast IP stuff and fixed an unicast timeout bug.
-***********************************************************************/
-/* TODO:
-       R_T_TOV set to 15msec in Loop topology. Need to be 100 msec.
-    SMP testing.
-       Fix ADISC Tx before completing FLOGI. 
-*/     
-
-static const char *version =
-    "iph5526.c:v1.0 07.08.99 Vineet Abraham (vmabraham@xxxxxxxxxxx)\n";
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/timer.h>
-#include <linux/spinlock.h>
-#include <linux/netdevice.h>
-#include <linux/fcdevice.h> /* had the declarations for init_fcdev among
-                              others + includes if_fcdevice.h */
-
-#include "../../scsi/scsi.h"
-#include <scsi/scsi_host.h>
-#include "../../fc4/fcp.h"
-
-#include <asm/system.h>
-#include <asm/io.h>
-
-/* driver specific header files */
-#include "tach.h"
-#include "tach_structs.h"
-#include "iph5526_ip.h"
-#include "iph5526_scsi.h"
-#include "iph5526_novram.c"
-
-#define RUN_AT(x) (jiffies + (x))
-
-#define DEBUG_5526_0 0
-#define DEBUG_5526_1 0
-#define DEBUG_5526_2 0
-
-#if DEBUG_5526_0
-#define DPRINTK(format, a...) {printk("%s: ", fi->name); \
-                                                          printk(format, ##a); 
\
-                                                          printk("\n");}
-#define ENTER(x)       {printk("%s: ", fi->name); \
-                                        printk("iph5526.c : entering %s()\n", 
x);}
-#define LEAVE(x)       {printk("%s: ", fi->name); \
-                                        printk("iph5526.c : leaving 
%s()\n",x);}
-
-#else
-#define DPRINTK(format, a...) {}
-#define ENTER(x)       {}
-#define LEAVE(x)       {}
-#endif
-
-#if DEBUG_5526_1
-#define DPRINTK1(format, a...) {printk("%s: ", fi->name); \
-                                                          printk(format, ##a); 
\
-                                                          printk("\n");}
-#else
-#define DPRINTK1(format, a...) {}
-#endif
-
-#if DEBUG_5526_2
-#define DPRINTK2(format, a...) {printk("%s: ", fi->name); \
-                                                          printk(format, ##a); 
\
-                                                          printk("\n");}
-#else
-#define DPRINTK2(format, a...) {}
-#endif
-
-#define T_MSG(format, a...) {printk("%s: ", fi->name); \
-                                                        printk(format, ##a);\
-                                                        printk("\n");}
-
-#define ALIGNED_SFS_ADDR(addr) ((((unsigned long)(addr) + (SFS_BUFFER_SIZE - 
1)) & ~(SFS_BUFFER_SIZE - 1)) - (unsigned long)(addr))
-#define ALIGNED_ADDR(addr, len) ((((unsigned long)(addr) + (len - 1)) & ~(len 
- 1)) - (unsigned long)(addr))
-
-
-static struct pci_device_id iph5526_pci_tbl[] = {
-       { PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_5526, PCI_ANY_ID, 
PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_55x6, PCI_ANY_ID, 
PCI_ANY_ID, },
-       { }                     /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(pci, iph5526_pci_tbl);
-
-MODULE_LICENSE("GPL");
-
-#define MAX_FC_CARDS 2
-static struct fc_info *fc[MAX_FC_CARDS+1];
-static unsigned int pci_irq_line;
-static struct {
-       unsigned short vendor_id;
-       unsigned short device_id;
-       char *name;
-}
-clone_list[] __initdata  = {
-       {PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_5526, "Interphase 
Fibre Channel HBA"},
-       {PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_55x6, "Interphase 
Fibre Channel HBA"},
-       {0,}
-};
-
-static irqreturn_t tachyon_interrupt(int irq, void *dev_id, struct pt_regs 
*regs);
-static void tachyon_interrupt_handler(int irq, void* dev_id, struct pt_regs* 
regs);
-
-static int initialize_register_pointers(struct fc_info *fi);
-void clean_up_memory(struct fc_info *fi);
-
-static int tachyon_init(struct fc_info *fi);
-static int build_queues(struct fc_info *fi);
-static void build_tachyon_header(struct fc_info *fi, u_int my_id, u_int r_ctl, 
u_int d_id, u_int type, u_char seq_id, u_char df_ctl, u_short ox_id, u_short 
rx_id, char *data);
-static int get_free_header(struct fc_info *fi);
-static void build_EDB(struct fc_info *fi, char *data, u_short flags, u_short 
len);
-static int get_free_EDB(struct fc_info *fi);
-static void build_ODB(struct fc_info *fi, u_char seq_id, u_int d_id, u_int 
len, u_int cntl, u_short mtu, u_short ox_id, u_short rx_id, int NW_header, int 
int_required, u_int frame_class);
-static void write_to_tachyon_registers(struct fc_info *fi);
-static void reset_latch(struct fc_info *fi);
-static void reset_tachyon(struct fc_info *fi, u_int value);
-static void take_tachyon_offline(struct fc_info *fi);
-static void read_novram(struct fc_info *fi);
-static void reset_ichip(struct fc_info *fi);
-static void update_OCQ_indx(struct fc_info *fi);
-static void update_IMQ_indx(struct fc_info *fi, int count);
-static void update_SFSBQ_indx(struct fc_info *fi);
-static void update_MFSBQ_indx(struct fc_info *fi, int count);
-static void update_tachyon_header_indx(struct fc_info *fi);
-static void update_EDB_indx(struct fc_info *fi);
-static void handle_FM_interrupt(struct fc_info *fi);
-static void handle_MFS_interrupt(struct fc_info *fi);
-static void handle_OOO_interrupt(struct fc_info *fi);
-static void handle_SFS_interrupt(struct fc_info *fi);
-static void handle_OCI_interrupt(struct fc_info *fi);
-static void handle_SFS_BUF_WARN_interrupt(struct fc_info *fi);
-static void handle_MFS_BUF_WARN_interrupt(struct fc_info *fi);
-static void handle_IMQ_BUF_WARN_interrupt(struct fc_info *fi);
-static void handle_Unknown_Frame_interrupt(struct fc_info *fi);
-static void handle_Busied_Frame_interrupt(struct fc_info *fi);
-static void handle_Bad_SCSI_Frame_interrupt(struct fc_info *fi);
-static void handle_Inbound_SCSI_Status_interrupt(struct fc_info *fi);
-static void handle_Inbound_SCSI_Command_interrupt(struct fc_info *fi);
-static void completion_message_handler(struct fc_info *fi, u_int imq_int_type);
-static void fill_login_frame(struct fc_info *fi, u_int logi);
-
-static int tx_exchange(struct fc_info *fi, char *data, u_int len, u_int r_ctl, 
u_int type, u_int d_id, u_int mtu, int int_required, u_short ox_id, u_int 
frame_class);
-static int tx_sequence(struct fc_info *fi, char *data, u_int len, u_int mtu, 
u_int d_id, u_short ox_id, u_short rx_id, u_char seq_id, int NW_flag, int 
int_required, u_int frame_class);
-static int validate_login(struct fc_info *fi, u_int *base_ptr);
-static void add_to_address_cache(struct fc_info *fi, u_int *base_ptr);
-static void remove_from_address_cache(struct fc_info *fi, u_int *data, u_int 
cmnd_code);
-static int node_logged_in_prev(struct fc_info *fi, u_int *buff_addr);
-static int sid_logged_in(struct fc_info *fi, u_int s_id);
-static struct fc_node_info *look_up_cache(struct fc_info *fi, char *data);
-static int display_cache(struct fc_info *fi);
-
-static void tx_logi(struct fc_info *fi, u_int logi, u_int d_id);
-static void tx_logi_acc(struct fc_info *fi, u_int logi, u_int d_id, u_short 
received_ox_id);
-static void tx_prli(struct fc_info *fi, u_int command_code, u_int d_id, 
u_short received_ox_id);
-static void tx_logo(struct fc_info *fi, u_int d_id, u_short received_ox_id);
-static void tx_adisc(struct fc_info *fi, u_int cmnd_code, u_int d_id, u_short 
received_ox_id);
-static void tx_ls_rjt(struct fc_info *fi, u_int d_id, u_short received_ox_id, 
u_short reason_code, u_short expln_code);
-static u_int plogi_ok(struct fc_info *fi, u_int *buff_addr, int size);
-static void tx_acc(struct fc_info *fi, u_int d_id, u_short received_ox_id);
-static void tx_name_server_req(struct fc_info *fi, u_int req);
-static void rscn_handler(struct fc_info *fi, u_int node_id);
-static void tx_scr(struct fc_info *fi);
-static void scr_timer(unsigned long data);
-static void explore_fabric(struct fc_info *fi, u_int *buff_addr);
-static void perform_adisc(struct fc_info *fi);
-static void local_port_discovery(struct fc_info *fi);
-static void add_to_ox_id_list(struct fc_info *fi, u_int transaction_id, u_int 
cmnd_code);
-static u_int remove_from_ox_id_list(struct fc_info *fi, u_short 
received_ox_id);
-static void add_display_cache_timer(struct fc_info *fi);
-
-/* Timers... */
-static void nos_ols_timer(unsigned long data);
-static void loop_timer(unsigned long data);
-static void fabric_explore_timer(unsigned long data);
-static void port_discovery_timer(unsigned long data);
-static void display_cache_timer(unsigned long data);
-
-/* SCSI Stuff */
-static int add_to_sest(struct fc_info *fi, Scsi_Cmnd *Cmnd, struct 
fc_node_info *ni);
-static struct fc_node_info *resolve_target(struct fc_info *fi, u_char target);
-static void update_FCP_CMND_indx(struct fc_info *fi);
-static int get_free_SDB(struct fc_info *fi);
-static void update_SDB_indx(struct fc_info *fi);
-static void mark_scsi_sid(struct fc_info *fi, u_int *buff_addr, u_char action);
-static void invalidate_SEST_entry(struct fc_info *fi, u_short received_ox_id);
-static int abort_exchange(struct fc_info *fi, u_short ox_id);
-static void flush_tachyon_cache(struct fc_info *fi, u_short ox_id);
-static int get_scsi_oxid(struct fc_info *fi);
-static void update_scsi_oxid(struct fc_info *fi);
-
-static Scsi_Host_Template driver_template = IPH5526_SCSI_FC;
-
-static void iph5526_timeout(struct net_device *dev);
-
-static int iph5526_probe_pci(struct net_device *dev);
-
-int __init iph5526_probe(struct net_device *dev)
-{
-       if (iph5526_probe_pci(dev) == 0)
-               return 0;
-       return -ENODEV;
-}
-
-static int __init iph5526_probe_pci(struct net_device *dev)
-{
-       struct fc_info *fi = dev->priv;
-       fi->dev = dev;
-       dev->base_addr = fi->base_addr;
-       dev->irq = fi->irq;
-       if (dev->priv == NULL) 
-               dev->priv = fi; 
-       fcdev_init(dev);
-       /* Assign ur MAC address.
-        */
-       dev->dev_addr[0] = (fi->g.my_port_name_high & 0x0000FF00) >> 8;
-       dev->dev_addr[1] = fi->g.my_port_name_high;
-       dev->dev_addr[2] = (fi->g.my_port_name_low & 0xFF000000) >> 24;
-       dev->dev_addr[3] = (fi->g.my_port_name_low & 0x00FF0000) >> 16;
-       dev->dev_addr[4] = (fi->g.my_port_name_low & 0x0000FF00) >> 8;
-       dev->dev_addr[5] = fi->g.my_port_name_low;
-       display_cache(fi);
-       return 0;
-}
-
-static int __init fcdev_init(struct net_device *dev)
-{
-       SET_MODULE_OWNER(dev);
-       dev->open = iph5526_open;
-       dev->stop = iph5526_close;
-       dev->hard_start_xmit = iph5526_send_packet;
-       dev->get_stats = iph5526_get_stats;
-       dev->set_multicast_list = NULL;
-       dev->change_mtu = iph5526_change_mtu; 
-       dev->tx_timeout = iph5526_timeout;
-       dev->watchdog_timeo = 5*HZ;
-       return 0;
-}
-
-/* initialize tachyon and take it OnLine */
-static int tachyon_init(struct fc_info *fi)
-{
-       ENTER("tachyon_init");
-       if (build_queues(fi) == 0) {
-               T_MSG("build_queues() failed");
-               return 0;
-       }
-
-       /* Retrieve your port/node name.
-        */
-       read_novram(fi);
-
-       reset_ichip(fi);
-
-       reset_tachyon(fi, SOFTWARE_RESET);
-
-       LEAVE("tachyon_init");
-       return 1;
-}
-
-/* Build the 4 Qs - IMQ, OCQ, MFSBQ, SFSBQ */
-/* Lots of dma_pages needed as Tachyon DMAs almost everything into 
- * host memory.
- */
-static int build_queues(struct fc_info *fi)
-{
-int i,j;
-u_char *addr;
-       ENTER("build_queues");
-       /* Initializing Queue Variables.
-        */
-       fi->q.ptr_host_ocq_cons_indx = NULL;
-       fi->q.ptr_host_hpcq_cons_indx = NULL;
-       fi->q.ptr_host_imq_prod_indx = NULL;
-
-       fi->q.ptr_ocq_base = NULL;
-       fi->q.ocq_len = 0;
-       fi->q.ocq_end = 0;
-       fi->q.ocq_prod_indx = 0;
-
-       fi->q.ptr_imq_base = NULL;
-       fi->q.imq_len = 0;
-       fi->q.imq_end = 0;
-       fi->q.imq_cons_indx = 0;
-       fi->q.imq_prod_indx = 0;
-
-       fi->q.ptr_mfsbq_base = NULL;
-       fi->q.mfsbq_len = 0;
-       fi->q.mfsbq_end = 0;
-       fi->q.mfsbq_prod_indx = 0;
-       fi->q.mfsbq_cons_indx = 0;
-       fi->q.mfsbuff_len = 0;
-       fi->q.mfsbuff_end = 0;
-       fi->g.mfs_buffer_count = 0;
-
-       fi->q.ptr_sfsbq_base = NULL;
-       fi->q.sfsbq_len = 0;
-       fi->q.sfsbq_end = 0;
-       fi->q.sfsbq_prod_indx = 0;
-       fi->q.sfsbq_cons_indx = 0;
-       fi->q.sfsbuff_len = 0;
-       fi->q.sfsbuff_end = 0;
-
-       fi->q.sdb_indx = 0;
-       fi->q.fcp_cmnd_indx = 0;
-
-       fi->q.ptr_edb_base = NULL;
-       fi->q.edb_buffer_indx = 0;
-       fi->q.ptr_tachyon_header_base = NULL;
-       fi->q.tachyon_header_indx = 0;
-       fi->node_info_list = NULL;
-       fi->ox_id_list = NULL;
-       fi->g.loop_up = FALSE;
-       fi->g.ptp_up = FALSE;
-       fi->g.link_up = FALSE;
-       fi->g.fabric_present = FALSE;
-       fi->g.n_port_try = FALSE;
-       fi->g.dont_init = FALSE;
-       fi->g.nport_timer_set = FALSE;
-       fi->g.lport_timer_set = FALSE;
-       fi->g.no_of_targets = 0;
-       fi->g.sem = 0;
-       fi->g.perform_adisc = FALSE;
-       fi->g.e_i = 0;
-
-       /* build OCQ */
-       if ( (fi->q.ptr_ocq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 
0) {
-               T_MSG("failed to get OCQ page");
-               return 0;
-       }
-       /* set up the OCQ structures */
-       for (i = 0; i < OCQ_LENGTH; i++)
-               fi->q.ptr_odb[i] = fi->q.ptr_ocq_base + NO_OF_ENTRIES*i;
-
-       /* build IMQ */
-       if ( (fi->q.ptr_imq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 
0) {
-               T_MSG("failed to get IMQ page");
-               return 0;
-       }
-       for (i = 0; i < IMQ_LENGTH; i++)
-               fi->q.ptr_imqe[i] = fi->q.ptr_imq_base + NO_OF_ENTRIES*i;
-
-       /* build MFSBQ */
-       if ( (fi->q.ptr_mfsbq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) 
== 0) {
-               T_MSG("failed to get MFSBQ page");
-               return 0;
-       }
-       memset((char *)fi->q.ptr_mfsbq_base, 0, MFSBQ_LENGTH * 32);
-       /* Allocate one huge chunk of memory... helps while reassembling
-        * frames.
-        */
-       if ( (addr = (u_char *)__get_free_pages(GFP_KERNEL, 5) ) == 0) {
-               T_MSG("failed to get MFSBQ page");
-               return 0;
-       }
-       /* fill in addresses of empty buffers */
-       for (i = 0; i < MFSBQ_LENGTH; i++) {
-               for (j = 0; j < NO_OF_ENTRIES; j++) {
-                               *(fi->q.ptr_mfsbq_base + i*NO_OF_ENTRIES + j) = 
htonl(virt_to_bus(addr));
-                               addr += MFS_BUFFER_SIZE;
-               }
-       }
-
-       /* The number of entries in each MFS buffer is 8. There are 8
-        * MFS buffers. That leaves us with 4096-256 bytes. We use them
-        * as temporary space for ELS frames. This is done to make sure that
-        * the addresses are aligned.
-        */
-       fi->g.els_buffer[0] = fi->q.ptr_mfsbq_base + MFSBQ_LENGTH*NO_OF_ENTRIES;
-       for (i = 1; i < MAX_PENDING_FRAMES; i++)
-               fi->g.els_buffer[i] = fi->g.els_buffer[i-1] + 64;
-       
-       /* build SFSBQ */
-       if ( (fi->q.ptr_sfsbq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) 
== 0) {
-               T_MSG("failed to get SFSBQ page");
-               return 0;
-       }
-       memset((char *)fi->q.ptr_sfsbq_base, 0, SFSBQ_LENGTH * 32);
-       /* fill in addresses of empty buffers */
-       for (i = 0; i < SFSBQ_LENGTH; i++)
-               for (j = 0; j < NO_OF_ENTRIES; j++){
-                       addr = kmalloc(SFS_BUFFER_SIZE*2, GFP_KERNEL);
-                       if (addr == NULL){ 
-                               T_MSG("ptr_sfs_buffer : memory not allocated");
-                               return 0;
-                       }
-                       else {
-                       int offset = ALIGNED_SFS_ADDR(addr);
-                               memset((char *)addr, 0, SFS_BUFFER_SIZE);
-                               fi->q.ptr_sfs_buffers[i*NO_OF_ENTRIES +j] = 
(u_int *)addr;
-                               addr += offset;
-                               *(fi->q.ptr_sfsbq_base + i*NO_OF_ENTRIES + j) = 
htonl(virt_to_bus(addr));
-                       }
-               }
-
-       /* The number of entries in each SFS buffer is 8. There are 8
-        * MFS buffers. That leaves us with 4096-256 bytes. We use them
-        * as temporary space for ARP frames. This is done inorder to 
-        * support HW_Types of 0x1 and 0x6. 
-        */
-       fi->g.arp_buffer = (char *)fi->q.ptr_sfsbq_base + 
SFSBQ_LENGTH*NO_OF_ENTRIES*4;
-       
-       /* build EDB */
-       if ((fi->q.ptr_edb_base = (u_int *)__get_free_pages(GFP_KERNEL, 5) ) == 
0) {
-               T_MSG("failed to get EDB page");
-               return 0;
-       }
-       for (i = 0; i < EDB_LEN; i++)
-               fi->q.ptr_edb[i] = fi->q.ptr_edb_base + 2*i;
-
-       /* build SEST */
-
-       /* OX_IDs range from 0x0 - 0x4FFF.
-        */
-       if ((fi->q.ptr_sest_base = (u_int *)__get_free_pages(GFP_KERNEL, 5)) == 
0) {
-               T_MSG("failed to get SEST page");
-               return 0;
-       }
-       for (i = 0; i < SEST_LENGTH; i++)
-               fi->q.ptr_sest[i] = fi->q.ptr_sest_base + NO_OF_ENTRIES*i;
-       
-       if ((fi->q.ptr_sdb_base = (u_int *)__get_free_pages(GFP_KERNEL, 5)) == 
0) {
-               T_MSG("failed to get SDB page");
-               return 0;
-       }
-       for (i = 0 ; i < NO_OF_SDB_ENTRIES; i++)
-               fi->q.ptr_sdb_slot[i] = fi->q.ptr_sdb_base + (SDB_SIZE/4)*i;
-
-       if ((fi->q.ptr_fcp_cmnd_base = (u_int *)__get_free_pages(GFP_KERNEL, 
0)) == 0) {
-               T_MSG("failed to get FCP_CMND page");
-               return 0;
-       }
-       for (i = 0; i < NO_OF_FCP_CMNDS; i++)
-               fi->q.ptr_fcp_cmnd[i] = fi->q.ptr_fcp_cmnd_base + 
NO_OF_ENTRIES*i;
-
-       /* Allocate space for Tachyon Header as well... 
-        */
-       if ((fi->q.ptr_tachyon_header_base = (u_int 
*)__get_free_pages(GFP_KERNEL, 0) ) == 0) {
-               T_MSG("failed to get tachyon_header page");
-               return 0;
-       }
-       for (i = 0; i < NO_OF_TACH_HEADERS; i++) 
-               fi->q.ptr_tachyon_header[i] = fi->q.ptr_tachyon_header_base + 
16*i;
-       
-       /* Allocate memory for indices.
-        * Indices should be aligned on 32 byte boundaries. 
-        */
-       fi->q.host_ocq_cons_indx = kmalloc(2*32, GFP_KERNEL);
-       if (fi->q.host_ocq_cons_indx == NULL){ 
-               T_MSG("fi->q.host_ocq_cons_indx : memory not allocated");
-               return 0;
-       }
-       fi->q.ptr_host_ocq_cons_indx = fi->q.host_ocq_cons_indx; 
-       if ((u_long)(fi->q.host_ocq_cons_indx) % 32)
-               fi->q.host_ocq_cons_indx++;
-       
-       fi->q.host_hpcq_cons_indx = kmalloc(2*32, GFP_KERNEL);
-       if (fi->q.host_hpcq_cons_indx == NULL){ 
-               T_MSG("fi->q.host_hpcq_cons_indx : memory not allocated");
-               return 0;
-       }
-       fi->q.ptr_host_hpcq_cons_indx= fi->q.host_hpcq_cons_indx;
-       if ((u_long)(fi->q.host_hpcq_cons_indx) % 32)
-               fi->q.host_hpcq_cons_indx++;
-
-       fi->q.host_imq_prod_indx = kmalloc(2*32, GFP_KERNEL);
-       if (fi->q.host_imq_prod_indx == NULL){ 
-               T_MSG("fi->q.host_imq_prod_indx : memory not allocated");
-               return 0;
-       }
-       fi->q.ptr_host_imq_prod_indx = fi->q.host_imq_prod_indx;
-       if ((u_long)(fi->q.host_imq_prod_indx) % 32)
-               fi->q.host_imq_prod_indx++;
-
-       LEAVE("build_queues");
-       return 1;
-}
-
-
-static void write_to_tachyon_registers(struct fc_info *fi)
-{
-u_int bus_addr, bus_indx_addr, i;
-
-       ENTER("write_to_tachyon_registers");
-
-       /* Clear Queues each time Tachyon is reset */
-       memset((char *)fi->q.ptr_ocq_base, 0, OCQ_LENGTH * 32);
-       memset((char *)fi->q.ptr_imq_base, 0, IMQ_LENGTH * 32);
-       memset((char *)fi->q.ptr_edb_base, 0, EDB_LEN * 8);
-       memset((char *)fi->q.ptr_sest_base, 0, SEST_LENGTH * 32);
-       memset((char *)fi->q.ptr_sdb_base, 0, NO_OF_SDB_ENTRIES * SDB_SIZE);
-       memset((char *)fi->q.ptr_tachyon_header_base, 0xFF, NO_OF_TACH_HEADERS 
* TACH_HEADER_SIZE);
-       for (i = 0; i < SEST_LENGTH; i++)
-               fi->q.free_scsi_oxid[i] = OXID_AVAILABLE;
-       for (i = 0; i < NO_OF_SDB_ENTRIES; i++)
-               fi->q.sdb_slot_status[i] = SDB_FREE;
-
-       take_tachyon_offline(fi);
-       writel(readl(fi->t_r.ptr_tach_config_reg) | SCSI_ENABLE | 
WRITE_STREAM_SIZE | READ_STREAM_SIZE | PARITY_EVEN | OOO_REASSEMBLY_DISABLE, 
fi->t_r.ptr_tach_config_reg);
-
-       /* Write OCQ registers */
-       fi->q.ocq_prod_indx = 0;
-       *(fi->q.host_ocq_cons_indx) = 0;
-       
-       /* The Tachyon needs to be passed the "real" address */
-       bus_addr = virt_to_bus(fi->q.ptr_ocq_base);
-       writel(bus_addr, fi->t_r.ptr_ocq_base_reg);
-       writel(OCQ_LENGTH - 1, fi->t_r. ptr_ocq_len_reg);
-       bus_indx_addr = virt_to_bus(fi->q.host_ocq_cons_indx);
-       writel(bus_indx_addr, fi->t_r.ptr_ocq_cons_indx_reg);
-
-       /* Write IMQ registers */
-       fi->q.imq_cons_indx = 0;
-       *(fi->q.host_imq_prod_indx) = 0;
-       bus_addr = virt_to_bus(fi->q.ptr_imq_base);
-       writel(bus_addr, fi->t_r.ptr_imq_base_reg);
-       writel(IMQ_LENGTH - 1, fi->t_r.ptr_imq_len_reg);
-       bus_indx_addr = virt_to_bus(fi->q.host_imq_prod_indx);
-       writel(bus_indx_addr, fi->t_r.ptr_imq_prod_indx_reg);
-       
-       /* Write MFSBQ registers */
-       fi->q.mfsbq_prod_indx = MFSBQ_LENGTH - 1;
-       fi->q.mfsbuff_end = MFS_BUFFER_SIZE - 1;
-       fi->q.mfsbq_cons_indx = 0;
-       bus_addr = virt_to_bus(fi->q.ptr_mfsbq_base);
-       writel(bus_addr, fi->t_r.ptr_mfsbq_base_reg);
-       writel(MFSBQ_LENGTH - 1, fi->t_r.ptr_mfsbq_len_reg);
-       writel(fi->q.mfsbuff_end, fi->t_r.ptr_mfsbuff_len_reg);
-       /* Do this last as tachyon will prefetch the 
-        * first entry as soon as we write to it.
-        */
-       writel(fi->q.mfsbq_prod_indx, fi->t_r.ptr_mfsbq_prod_reg);
-
-       /* Write SFSBQ registers */
-       fi->q.sfsbq_prod_indx = SFSBQ_LENGTH - 1;
-       fi->q.sfsbuff_end = SFS_BUFFER_SIZE - 1;
-       fi->q.sfsbq_cons_indx = 0;
-       bus_addr = virt_to_bus(fi->q.ptr_sfsbq_base);
-       writel(bus_addr, fi->t_r.ptr_sfsbq_base_reg);
-       writel(SFSBQ_LENGTH - 1, fi->t_r.ptr_sfsbq_len_reg);
-       writel(fi->q.sfsbuff_end, fi->t_r.ptr_sfsbuff_len_reg);
-       /* Do this last as tachyon will prefetch the first 
-        * entry as soon as we write to it. 
-        */
-       writel(fi->q.sfsbq_prod_indx, fi->t_r.ptr_sfsbq_prod_reg);
-
-       /* Write SEST registers */
-       bus_addr = virt_to_bus(fi->q.ptr_sest_base);
-       writel(bus_addr, fi->t_r.ptr_sest_base_reg);
-       writel(SEST_LENGTH - 1, fi->t_r.ptr_sest_len_reg);
-       /* the last 2 bits _should_ be 1 */
-       writel(SEST_BUFFER_SIZE - 1, fi->t_r.ptr_scsibuff_len_reg);
-
-       /* write AL_TIME & E_D_TOV into the registers */
-       writel(TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
-       /* Tell Tachyon to pick a Soft Assigned AL_PA */
-       writel(LOOP_INIT_SOFT_ADDRESS, fi->t_r.ptr_fm_config_reg);
-
-       /* Read the WWN from EEPROM . But, for now we assign it here. */
-       writel(WORLD_WIDE_NAME_LOW, fi->t_r.ptr_fm_wwn_low_reg);
-       writel(WORLD_WIDE_NAME_HIGH, fi->t_r.ptr_fm_wwn_hi_reg);
-
-       DPRINTK1("TACHYON initializing as L_Port...\n");
-       writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
-                       
-       LEAVE("write_to_tachyon_registers");
-}
-
-
-static irqreturn_t tachyon_interrupt(int irq, void* dev_id, struct pt_regs* 
regs)
-{
-struct Scsi_Host *host = dev_id;
-struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
-struct fc_info *fi = hostdata->fi; 
-u_long flags;
-       spin_lock_irqsave(&fi->fc_lock, flags);
-       tachyon_interrupt_handler(irq, dev_id, regs);
-       spin_unlock_irqrestore(&fi->fc_lock, flags);
-       return IRQ_HANDLED;
-}
-
-static void tachyon_interrupt_handler(int irq, void* dev_id, struct pt_regs* 
regs)
-{
-struct Scsi_Host *host = dev_id;
-struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
-struct fc_info *fi = hostdata->fi; 
-u_int *ptr_imq_entry;
-u_int imq_int_type, current_IMQ_index = 0, prev_IMQ_index;
-int index, no_of_entries = 0;
-
-       DPRINTK("\n");
-       ENTER("tachyon_interrupt");
-       if (fi->q.host_imq_prod_indx != NULL) {
-               current_IMQ_index =  ntohl(*(fi->q.host_imq_prod_indx));
-       }
-       else {
-               /* _Should not_ happen */
-               T_MSG("IMQ_indx NULL. DISABLING INTERRUPTS!!!\n");
-               writel(0x0, fi->i_r.ptr_ichip_hw_control_reg);
-       }
-
-       if (current_IMQ_index > fi->q.imq_cons_indx)
-               no_of_entries = current_IMQ_index - fi->q.imq_cons_indx;
-       else
-       if (current_IMQ_index < fi->q.imq_cons_indx)
-               no_of_entries = IMQ_LENGTH - (fi->q.imq_cons_indx - 
current_IMQ_index);
-
-       if (no_of_entries == 0) {
-       u_int ichip_status;
-               ichip_status = readl(fi->i_r.ptr_ichip_hw_status_reg);
-               if (ichip_status & 0x20) {
-                       /* Should _never_ happen. Might require a hard reset */
-                       T_MSG("Too bad... PCI Bus Error. Resetting (i)chip"); 
-                       reset_ichip(fi);
-                       T_MSG("DISABLING INTERRUPTS!!!\n");
-                       writel(0x0, fi->i_r.ptr_ichip_hw_control_reg);
-               }
-       }
-
-       prev_IMQ_index = current_IMQ_index;
-       for (index = 0; index < no_of_entries; index++) {
-               ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
-               imq_int_type = ntohl(*ptr_imq_entry);
-
-               completion_message_handler(fi, imq_int_type);
-               if ((fi->g.link_up == FALSE) && ((imq_int_type == MFS_BUF_WARN) 
|| (imq_int_type == SFS_BUF_WARN) || (imq_int_type == IMQ_BUF_WARN))) 
-                       break;
-               update_IMQ_indx(fi, 1);
-       
-               /* Check for more entries */
-               current_IMQ_index =  ntohl(*(fi->q.host_imq_prod_indx));
-               if (current_IMQ_index != prev_IMQ_index) {
-                       no_of_entries++;
-                       prev_IMQ_index = current_IMQ_index;
-               }
-       } /*end of for loop*/           
-       LEAVE("tachyon_interrupt");
-       return;
-}
-
-
-static void handle_SFS_BUF_WARN_interrupt(struct fc_info *fi)
-{
-int i;
-       ENTER("handle_SFS_BUF_WARN_interrupt");
-       if (fi->g.link_up == FALSE) {
-               reset_tachyon(fi, SOFTWARE_RESET);
-               return;
-       }
-       /* Free up all but one entry in the Q. 
-        */
-       for (i = 0; i < ((SFSBQ_LENGTH - 1) * NO_OF_ENTRIES); i++) {
-               handle_SFS_interrupt(fi);
-               update_IMQ_indx(fi, 1);
-       }
-       LEAVE("handle_SFS_BUF_WARN_interrupt");
-}
-
-/* Untested_Code_Begin */ 
-static void handle_MFS_BUF_WARN_interrupt(struct fc_info *fi)
-{
-int i;
-       ENTER("handle_MFS_BUF_WARN_interrupt");
-       if (fi->g.link_up == FALSE) {
-               reset_tachyon(fi, SOFTWARE_RESET);
-               return;
-       }
-       /* FIXME: freeing up 8 entries. 
-        */
-       for (i = 0; i < NO_OF_ENTRIES; i++) {
-               handle_MFS_interrupt(fi);
-               update_IMQ_indx(fi, 1);
-       }
-       LEAVE("handle_MFS_BUF_WARN_interrupt");
-}
-/*Untested_Code_End */
-
-static void handle_IMQ_BUF_WARN_interrupt(struct fc_info *fi)
-{
-u_int *ptr_imq_entry;
-u_int imq_int_type, current_IMQ_index = 0, temp_imq_cons_indx;
-int index, no_of_entries = 0;
-
-       ENTER("handle_IMQ_BUF_WARN_interrupt");
-       if (fi->g.link_up == FALSE) {
-               reset_tachyon(fi, SOFTWARE_RESET);
-               return;
-       }
-       current_IMQ_index =  ntohl(*(fi->q.host_imq_prod_indx));
-
-       if (current_IMQ_index > fi->q.imq_cons_indx)
-               no_of_entries = current_IMQ_index - fi->q.imq_cons_indx;
-       else
-               if (current_IMQ_index < fi->q.imq_cons_indx)
-                       no_of_entries = IMQ_LENGTH - (fi->q.imq_cons_indx - 
current_IMQ_index);
-       /* We don't want to look at the same IMQ entry again. 
-        */
-       temp_imq_cons_indx = fi->q.imq_cons_indx + 1;
-       if (no_of_entries != 0)
-               no_of_entries -= 1;
-       for (index = 0; index < no_of_entries; index++) {
-               ptr_imq_entry = fi->q.ptr_imqe[temp_imq_cons_indx];
-               imq_int_type = ntohl(*ptr_imq_entry);
-               if (imq_int_type != IMQ_BUF_WARN)
-                       completion_message_handler(fi, imq_int_type);
-               temp_imq_cons_indx++;
-               if (temp_imq_cons_indx == IMQ_LENGTH)
-                       temp_imq_cons_indx = 0;
-       } /*end of for loop*/   
-       if (no_of_entries != 0)
-               update_IMQ_indx(fi, no_of_entries);
-       LEAVE("handle_IMQ_BUF_WARN_interrupt");
-}
-
-static void completion_message_handler(struct fc_info *fi, u_int imq_int_type)
-{
-       switch(imq_int_type) {
-               case OUTBOUND_COMPLETION:
-                       DPRINTK("OUTBOUND_COMPLETION message received");
-                       break;
-               case OUTBOUND_COMPLETION_I:
-                       DPRINTK("OUTBOUND_COMPLETION_I message received");
-                       handle_OCI_interrupt(fi);
-                       break;
-               case OUT_HI_PRI_COMPLETION:
-                       DPRINTK("OUT_HI_PRI_COMPLETION message received");
-                       break;
-               case OUT_HI_PRI_COMPLETION_I:
-                       DPRINTK("OUT_HI_PRI_COMPLETION_I message received");
-                       break;
-               case INBOUND_MFS_COMPLETION:
-                       DPRINTK("INBOUND_MFS_COMPLETION message received");
-                       handle_MFS_interrupt(fi);
-                       break;
-               case INBOUND_OOO_COMPLETION:
-                       DPRINTK("INBOUND_OOO_COMPLETION message received");
-                       handle_OOO_interrupt(fi);
-                       break;
-               case INBOUND_SFS_COMPLETION:
-                       DPRINTK("INBOUND_SFS_COMPLETION message received");
-                       handle_SFS_interrupt(fi);
-                       break;
-               case INBOUND_UNKNOWN_FRAME_I:
-                       DPRINTK("INBOUND_UNKNOWN_FRAME message received");
-                       handle_Unknown_Frame_interrupt(fi);
-                       break;
-               case INBOUND_BUSIED_FRAME:
-                       DPRINTK("INBOUND_BUSIED_FRAME message received");
-                       handle_Busied_Frame_interrupt(fi);
-                       break;
-               case FRAME_MGR_INTERRUPT:
-                       DPRINTK("FRAME_MGR_INTERRUPT message received");
-                       handle_FM_interrupt(fi);
-                       break;
-               case READ_STATUS:
-                       DPRINTK("READ_STATUS message received");
-                       break;
-               case SFS_BUF_WARN:
-                       DPRINTK("SFS_BUF_WARN message received");
-                       handle_SFS_BUF_WARN_interrupt(fi);
-                       break;
-               case MFS_BUF_WARN:
-                       DPRINTK("MFS_BUF_WARN message received");
-                       handle_MFS_BUF_WARN_interrupt(fi);
-                       break;
-               case IMQ_BUF_WARN:
-                       DPRINTK("IMQ_BUF_WARN message received");
-                       handle_IMQ_BUF_WARN_interrupt(fi);
-                       break;
-               case INBOUND_C1_TIMEOUT:
-                       DPRINTK("INBOUND_C1_TIMEOUT message received");
-                       break;
-               case BAD_SCSI_FRAME:
-                       DPRINTK("BAD_SCSI_FRAME message received");
-                       handle_Bad_SCSI_Frame_interrupt(fi);
-                       break;
-               case INB_SCSI_STATUS_COMPLETION:
-                       DPRINTK("INB_SCSI_STATUS_COMPL message received");
-                       handle_Inbound_SCSI_Status_interrupt(fi);
-                       break;
-               case INBOUND_SCSI_COMMAND:
-                       DPRINTK("INBOUND_SCSI_COMMAND message received");
-                       handle_Inbound_SCSI_Command_interrupt(fi);
-                       break;
-               case INBOUND_SCSI_DATA_COMPLETION:
-                       DPRINTK("INBOUND_SCSI_DATA message received");
-                       /* Only for targets */
-                       break;
-               default:                
-                       T_MSG("DEFAULT message received, type = %x", 
imq_int_type);
-                       return;
-       }
-       reset_latch(fi);
-}
-
-static void handle_OCI_interrupt(struct fc_info *fi)
-{
-u_int *ptr_imq_entry;
-u_long transaction_id = 0;
-unsigned short status, seq_count, transmitted_ox_id;
-struct Scsi_Host *host = fi->host;
-struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
-Scsi_Cmnd *Cmnd;
-u_int tag;
-
-       ENTER("handle_OCI_interrupt");
-       ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
-       transaction_id = ntohl(*(ptr_imq_entry + 1));
-       status = ntohl(*(ptr_imq_entry + 2)) >> 16;
-       seq_count = ntohl(*(ptr_imq_entry + 3));
-       DPRINTK("transaction_id= %x", (u_int)transaction_id);
-       tag = transaction_id & 0xFFFF0000;
-       transmitted_ox_id = transaction_id;
-
-       /* The INT could be either due to TIME_OUT | BAD_ALPA. 
-        * But we check only for TimeOuts. Bad AL_PA will 
-        * caught by FM_interrupt handler. 
-        */
-
-       if ((status == OCM_TIMEOUT_OR_BAD_ALPA) && (!fi->g.port_discovery) && 
(!fi->g.perform_adisc)){
-               DPRINTK("Frame TimeOut on OX_ID = %x", (u_int)transaction_id);
-
-               /* Is it a SCSI frame that is timing out ? Not a very good 
check... 
-                */
-               if ((transmitted_ox_id <= MAX_SCSI_OXID) && ((tag == 
FC_SCSI_BAD_TARGET) || (tag < 0x00FF0000))) {
-                       /* If it is a Bad AL_PA, we report it as BAD_TARGET.
-                        * Else, we allow the command to time-out. A Link
-                        * re-initialization could be taking place.
-                        */
-                       if (tag == FC_SCSI_BAD_TARGET) {
-                               Cmnd = hostdata->cmnd_handler[transmitted_ox_id 
& MAX_SCSI_XID];
-                               hostdata->cmnd_handler[transmitted_ox_id & 
MAX_SCSI_XID] = NULL;
-                               if (Cmnd != NULL) {
-                                       Cmnd->result = DID_BAD_TARGET << 16;
-                                       (*Cmnd->scsi_done) (Cmnd);
-                               }
-                               else
-                                       T_MSG("NULL Command out of handler!");
-                       } /* if Bad Target */
-                       else {
-                       u_char missing_target = tag >> 16;
-                       struct fc_node_info *q = fi->node_info_list;
-                               /* A Node that we thought was logged in has gone
-                                * away. We are the optimistic kind and we keep
-                                * hoping that our dear little Target will come 
back
-                                * to us. For now we log him out.
-                                */
-                               DPRINTK2("Missing Target = %d", missing_target);
-                               while (q != NULL) {
-                                       if (q->target_id == missing_target) {
-                                               T_MSG("Target %d Logged out", 
q->target_id);
-                                               q->login = LOGIN_ATTEMPTED;
-                                               if (fi->num_nodes > 0)
-                                                       fi->num_nodes--;
-                                               tx_logi(fi, ELS_PLOGI, q->d_id);
-                                               break;
-                                       }
-                                       else
-                                               q = q->next;
-                               }
-                       }
-               } /* End of SCSI frame timing out. */
-               else {
-                       if (seq_count > 1) {
-                               /* An IP frame was transmitted to a Bad AL_PA. 
Free up
-                                * the skb used.
-                                */
-                               dev_kfree_skb_irq((struct sk_buff 
*)(bus_to_virt(transaction_id)));
-                               netif_wake_queue(fi->dev);
-                       }
-               } /* End of IP frame timing out. */
-       } /* End of frame timing out. */
-       else {
-               /* Frame was transmitted successfully. Check if it was an ELS
-                * frame or an IP frame or a Bad_Target_Notification frame (in
-                * case of a ptp_link). Ugly!
-                */
-               if ((status == 0) && (seq_count == 0)) {
-               u_int tag = transaction_id & 0xFFFF0000;
-               /* Continue with port discovery after an ELS is successfully 
-                * transmitted. (status == 0). 
-                */
-                       DPRINTK("tag = %x", tag);
-                       switch(tag) {
-                               case ELS_FLOGI:
-                                       /* Letz use the Name Server instead */
-                                       fi->g.explore_fabric = TRUE;
-                                       fi->g.port_discovery = FALSE;
-                                       fi->g.alpa_list_index = MAX_NODES;
-                                       add_to_ox_id_list(fi, transaction_id, 
tag);
-                                       break;
-                               case ELS_PLOGI:
-                                       if (fi->g.fabric_present && 
(fi->g.name_server == FALSE))
-                                               
add_to_ox_id_list(fi,transaction_id,ELS_NS_PLOGI);
-                                       else
-                                               add_to_ox_id_list(fi, 
transaction_id, tag);
-                                       break;
-                               case FC_SCSI_BAD_TARGET:
-                                       Cmnd = 
hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID];
-                                       
hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID] = NULL;
-                                       if (Cmnd != NULL) {
-                                               Cmnd->result = DID_BAD_TARGET 
<< 16;
-                                               (*Cmnd->scsi_done) (Cmnd);
-                                       }
-                                       else
-                                               T_MSG("NULL Command out of 
handler!");
-                                       break;
-                               default:
-                                       add_to_ox_id_list(fi, transaction_id, 
tag);
-                       }
-               
-                       if (fi->g.alpa_list_index >= MAX_NODES) {
-                               if (fi->g.port_discovery == TRUE) {
-                                       fi->g.port_discovery = FALSE;
-                                       add_display_cache_timer(fi);
-                               }
-                               fi->g.alpa_list_index = MAX_NODES;
-                       }
-                       if (fi->g.port_discovery == TRUE) 
-                               local_port_discovery(fi);
-               }
-               else {
-                       /* An IP frame has been successfully transmitted.
-                        * Free the skb that was used for this IP frame.
-                        */
-                       if ((status == 0) && (seq_count > 1)) {
-                               dev_kfree_skb_irq((struct sk_buff 
*)(bus_to_virt(transaction_id)));
-                               netif_wake_queue(fi->dev);
-                       }
-               }
-       }
-       LEAVE("handle_OCI_interrupt");
-}
-
-/* Right now we discard OOO frames */
-static void handle_OOO_interrupt(struct fc_info *fi)
-{
-u_int *ptr_imq_entry;
-int queue_indx, offset, payload_size;
-int no_of_buffers = 1; /* header is in a separate buffer */
-       ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
-       offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
-       queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
-       queue_indx = queue_indx >> 16;
-       payload_size = ntohl(*(ptr_imq_entry + 2)) - TACHYON_HEADER_LEN;
-       /* Calculate total number of buffers */
-       no_of_buffers += payload_size / MFS_BUFFER_SIZE;
-       if (payload_size % MFS_BUFFER_SIZE)
-               no_of_buffers++;
-
-       /* provide Tachyon will another set of buffers */
-       fi->g.mfs_buffer_count += no_of_buffers;
-       if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) {
-       int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES;
-               fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count;
-               update_MFSBQ_indx(fi, count);
-       }
-}
-
-static void handle_MFS_interrupt(struct fc_info *fi)
-{
-u_int *ptr_imq_entry, *buff_addr;
-u_int type_of_frame, s_id;
-int queue_indx, offset, payload_size, starting_indx, starting_offset;
-u_short received_ox_id;
-int no_of_buffers = 1; /* header is in a separate buffer */
-struct sk_buff *skb;
-int wrap_around = FALSE, no_of_wrap_buffs = NO_OF_ENTRIES - 1;
-       ENTER("handle_MFS_interrupt");
-       ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
-       offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
-       queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
-       queue_indx = queue_indx >> 16;
-       DPRINTK("queue_indx = %d, offset  = %d\n", queue_indx, offset);
-       payload_size = ntohl(*(ptr_imq_entry + 2)) - TACHYON_HEADER_LEN;
-       DPRINTK("payload_size = %d", payload_size);
-       /* Calculate total number of buffers */
-       no_of_buffers += payload_size / MFS_BUFFER_SIZE;
-       if (payload_size % MFS_BUFFER_SIZE)
-               no_of_buffers++;
-       DPRINTK("no_of_buffers = %d", no_of_buffers);
-
-       if ((no_of_buffers - 1) <= offset) {
-               starting_offset = offset - (no_of_buffers - 1);
-               starting_indx = queue_indx;
-       }
-       else {
-       int temp = no_of_buffers - (offset + 1);
-       int no_of_queues = temp / NO_OF_ENTRIES;
-               starting_offset = temp % NO_OF_ENTRIES;
-               if (starting_offset != 0) {
-                       no_of_wrap_buffs = starting_offset - 1; //exclude header
-                       starting_offset = NO_OF_ENTRIES - starting_offset;
-                       no_of_queues++;
-               }
-               starting_indx = queue_indx - no_of_queues;
-               if (starting_indx < 0) {
-                       no_of_wrap_buffs -= (starting_indx + 1) * 
NO_OF_ENTRIES; 
-                       starting_indx = MFSBQ_LENGTH + starting_indx;
-                       wrap_around = TRUE;
-               }
-       }
-       
-       DPRINTK("starting_indx = %d, starting offset = %d no_of_wrap_buffs = 
%d\n", starting_indx, starting_offset, no_of_wrap_buffs);
-       /* Get Tachyon Header from first buffer */
-       buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_mfsbq_base + 
starting_indx*NO_OF_ENTRIES + starting_offset)));
-       
-
-       /* extract Type of Frame */
-       type_of_frame = (u_int)ntohl(*(buff_addr + 4)) & 0xFF000000;
-       s_id = (u_int)ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
-       received_ox_id = ntohl(*(buff_addr + 6)) >> 16;
-       buff_addr += MFS_BUFFER_SIZE/4;
-       DPRINTK("type_of_frame = %x, s_id = %x, ox_id = %x", type_of_frame, 
s_id, received_ox_id);
-
-       switch(type_of_frame) {
-         case TYPE_LLC_SNAP:
-               skb = dev_alloc_skb(payload_size);
-               if (skb == NULL) {
-                       printk(KERN_NOTICE "%s: In handle_MFS_interrupt() 
Memory squeeze, dropping packet.\n", fi->name);
-                       fi->fc_stats.rx_dropped++;
-                       fi->g.mfs_buffer_count += no_of_buffers;
-                       if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) {
-                               int count = fi->g.mfs_buffer_count / 
NO_OF_ENTRIES;
-                               fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count;
-                               update_MFSBQ_indx(fi, count);
-                       }
-                       return;
-               }
-               if (wrap_around) {
-               int wrap_size = no_of_wrap_buffs * MFS_BUFFER_SIZE;
-               int tail_size = payload_size - wrap_size;
-                       DPRINTK("wrap_size = %d, tail_size = %d\n", wrap_size, 
tail_size);
-                       if (no_of_wrap_buffs) 
-                               memcpy(skb_put(skb, wrap_size), buff_addr, 
wrap_size);
-                       buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_mfsbq_base)));
-                       memcpy(skb_put(skb, tail_size), buff_addr, tail_size);
-               }
-               else
-                       memcpy(skb_put(skb, payload_size), buff_addr, 
payload_size);
-               rx_net_mfs_packet(fi, skb);
-               break;
-       default:
-               T_MSG("Unknown Frame Type received. Type = %x", type_of_frame);
-       }
-
-       /* provide Tachyon will another set of buffers */
-       fi->g.mfs_buffer_count += no_of_buffers;
-       if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) {
-       int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES;
-               fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count;
-               update_MFSBQ_indx(fi, count);
-       }
-       LEAVE("handle_MFS_interrupt");
-}
-
-static void handle_Unknown_Frame_interrupt(struct fc_info *fi)
-{
-u_int *ptr_imq_entry;
-int queue_indx, offset;
-       ENTER("handle_Unknown_Frame_interrupt");
-       ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
-       offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
-       queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
-       queue_indx = queue_indx >> 16;
-       /* We discard the "unknown" frame */
-       /* provide Tachyon will another set of buffers */
-       if (offset == (NO_OF_ENTRIES - 1))
-               update_SFSBQ_indx(fi);
-       LEAVE("handle_Unknown_Frame_interrupt");
-}
-
-static void handle_Busied_Frame_interrupt(struct fc_info *fi)
-{
-u_int *ptr_imq_entry;
-int queue_indx, offset;
-       ENTER("handle_Busied_Frame_interrupt");
-       ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
-       offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
-       queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
-       queue_indx = queue_indx >> 16;
-       /* We discard the "busied" frame */
-       /* provide Tachyon will another set of buffers */
-       if (offset == (NO_OF_ENTRIES - 1))
-               update_SFSBQ_indx(fi);
-       LEAVE("handle_Busied_Frame_interrupt");
-}
-
-static void handle_Bad_SCSI_Frame_interrupt(struct fc_info *fi)
-{
-u_int *ptr_imq_entry, *buff_addr, *tach_header, *ptr_edb;
-u_int s_id, rctl, frame_class, burst_len, transfered_len, len = 0;
-int queue_indx, offset, payload_size, i;
-u_short ox_id, rx_id, x_id, mtu = 512;
-u_char target_id = 0xFF;
-
-       ENTER("handle_Bad_SCSI_Frame_interrupt");
-       ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
-       offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
-       queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
-       queue_indx = queue_indx >> 16;
-       payload_size = ntohl(*(ptr_imq_entry + 2));
-
-       buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + 
queue_indx*NO_OF_ENTRIES + offset)));
-
-       rctl = ntohl(*(buff_addr + 2)) & 0xFF000000;
-       s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
-       ox_id = ntohl(*(buff_addr + 6)) >> 16;
-       rx_id = ntohl(*(buff_addr + 6));
-       x_id = ox_id & MAX_SCSI_XID;
-
-       /* Any frame that comes in with OX_ID that matches an OX_ID 
-        * that has been allocated for SCSI, will be called a Bad
-        * SCSI frame if the Exchange is not valid any more.
-        *
-        * We will also get a Bad SCSI frame interrupt if we receive
-        * a XFER_RDY with offset != 0. Tachyon washes its hands off
-        * this Exchange. We have to take care of ourselves. Grrr...
-        */
-       if (rctl == DATA_DESCRIPTOR) {
-       struct fc_node_info *q = fi->node_info_list;
-               while (q != NULL) {
-                       if (q->d_id == s_id) {
-                               target_id = q->target_id;
-                               mtu = q->mtu;
-                               break;
-                       }
-                       else
-                               q = q->next;
-               }
-               frame_class = target_id;
-               transfered_len = ntohl(*(buff_addr + 8));
-               burst_len = ntohl(*(buff_addr + 9));
-
-               build_ODB(fi, fi->g.seq_id, s_id, burst_len, 0, mtu, ox_id, 
rx_id, 0, 0, frame_class << 16);
-               /* Update the SEQ_ID and Relative Offset in the 
-                * Tachyon Header Structure.
-                */
-               tach_header = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 5)));
-               *(tach_header + 5) = htonl(fi->g.seq_id << 24);
-               *(tach_header + 7) = htonl(transfered_len);
-               fi->g.odb.hdr_addr = *(fi->q.ptr_sest[x_id] + 5);
-
-               /* Invalidate the EDBs used 
-                */
-               ptr_edb = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 7)));
-
-               for (i = 0; i < EDB_LEN; i++)
-                       if (fi->q.ptr_edb[i] == ptr_edb)
-                               break;
-               ptr_edb--;      
-               
-               if (i < EDB_LEN) {
-               int j;
-                       do {
-                               ptr_edb += 2;
-                               len += (htonl(*ptr_edb) & 0xFFFF);
-                               j = i;
-                               fi->q.free_edb_list[i++] = EDB_FREE;
-                               if (i == EDB_LEN) {
-                                       i = 0;
-                                       ptr_edb = fi->q.ptr_edb_base - 1;
-                               }
-                       } while (len < transfered_len);
-                       if (len > transfered_len) {
-                               ptr_edb--;
-                               fi->q.free_edb_list[j] = EDB_BUSY;
-                       }
-                       else
-                               ptr_edb++;
-               }
-               else {
-                       T_MSG("EDB not found while freeing");
-                       if (offset == (NO_OF_ENTRIES - 1))
-                               update_SFSBQ_indx(fi);
-                       return;
-               }
-
-               /* Update the EDB pointer in the ODB.
-                */
-               fi->g.odb.edb_addr = htonl(virt_to_bus(ptr_edb));
-               memcpy(fi->q.ptr_odb[fi->q.ocq_prod_indx], &(fi->g.odb), 
sizeof(ODB));
-               /* Update the EDB pointer in the SEST entry. We might need
-                * this if get another XFER_RDY for the same Exchange.
-                */
-               *(fi->q.ptr_sest[x_id] + 7) = htonl(virt_to_bus(ptr_edb));
-
-               update_OCQ_indx(fi);
-               if (fi->g.seq_id == MAX_SEQ_ID)
-                       fi->g.seq_id = 0;
-               else
-                       fi->g.seq_id++;
-       }
-       else 
-       /* Could be a BA_ACC or a BA_RJT.
-        */
-       if (rctl == RCTL_BASIC_ACC) {
-       u_int bls_type = remove_from_ox_id_list(fi, ox_id);
-               DPRINTK1("BA_ACC received from S_ID 0x%x with OX_ID = %x in 
response to %x", s_id, ox_id, bls_type);
-               if (bls_type == RCTL_BASIC_ABTS) {
-               u_int STE_bit;
-                       /* Invalidate resources for that Exchange.
-                        */
-                       STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
-                       if (STE_bit & SEST_V) {
-                               *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
-                               invalidate_SEST_entry(fi, ox_id);
-                       }
-               }
-       }
-       else
-       if (rctl == RCTL_BASIC_RJT) {
-       u_int bls_type = remove_from_ox_id_list(fi, ox_id);
-               DPRINTK1("BA_RJT received from S_ID 0x%x with OX_ID = %x in 
response to %x", s_id, ox_id, bls_type);
-               if (bls_type == RCTL_BASIC_ABTS) {
-               u_int STE_bit;
-                       /* Invalidate resources for that Exchange.
-                        */
-                       STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
-                       if (STE_bit & SEST_V) {
-                               *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
-                               invalidate_SEST_entry(fi, ox_id);
-                       }
-               }
-       }
-       else
-               DPRINTK1("Frame with R_CTL = %x received from S_ID 0x%x with 
OX_ID %x", rctl, s_id, ox_id);
-
-       /* Else, discard the "Bad" SCSI frame.
-        */
-
-       /* provide Tachyon will another set of buffers 
-        */
-       if (offset == (NO_OF_ENTRIES - 1))
-               update_SFSBQ_indx(fi);
-       LEAVE("handle_Bad_SCSI_Frame_interrupt");
-}
-
-static void handle_Inbound_SCSI_Status_interrupt(struct fc_info *fi)
-{
-struct Scsi_Host *host = fi->host;
-struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
-u_int *ptr_imq_entry, *buff_addr, *ptr_rsp_info, *ptr_sense_info = NULL;
-int queue_indx, offset, payload_size;
-u_short received_ox_id, x_id;
-Scsi_Cmnd *Cmnd;
-u_int fcp_status, fcp_rsp_info_len = 0, fcp_sense_info_len = 0, s_id;
-       ENTER("handle_SCSI_status_interrupt");
-
-       ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
-       offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
-       queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
-       queue_indx = queue_indx >> 16;
-       buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + 
queue_indx*NO_OF_ENTRIES + offset)));
-       payload_size = ntohl(*(ptr_imq_entry + 2));
-       received_ox_id = ntohl(*(buff_addr + 6)) >> 16;
-
-       buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + 
queue_indx*NO_OF_ENTRIES + offset)));
-
-       fcp_status = ntohl(*(buff_addr + 10));
-       ptr_rsp_info = buff_addr + 14;
-       if (fcp_status & FCP_STATUS_RSP_LEN)
-               fcp_rsp_info_len = ntohl(*(buff_addr + 13));
-               
-       if (fcp_status & FCP_STATUS_SENSE_LEN) {
-               ptr_sense_info = ptr_rsp_info + fcp_rsp_info_len / 4;
-               fcp_sense_info_len = ntohl(*(buff_addr + 12));
-               DPRINTK("sense_info = %x", (u_int)ntohl(*ptr_sense_info));
-       }
-       DPRINTK("fcp_status = %x, fcp_rsp_len = %x", fcp_status, 
fcp_rsp_info_len);
-       x_id = received_ox_id & MAX_SCSI_XID;
-       Cmnd = hostdata->cmnd_handler[x_id];
-       hostdata->cmnd_handler[x_id] = NULL;
-       if (Cmnd != NULL) {
-               memset(Cmnd->sense_buffer, 0, sizeof(Cmnd->sense_buffer));
-               /* Check if there is a Sense field */
-               if (fcp_status & FCP_STATUS_SENSE_LEN) {
-               int size = sizeof(Cmnd->sense_buffer);
-                       if (fcp_sense_info_len < size)
-                               size = fcp_sense_info_len;
-                       memcpy(Cmnd->sense_buffer, (char *)ptr_sense_info, 
size);
-               }
-               Cmnd->result = fcp_status & FCP_STATUS_MASK;
-               (*Cmnd->scsi_done) (Cmnd);
-       }
-       else
-               T_MSG("NULL Command out of handler!");
-
-       invalidate_SEST_entry(fi, received_ox_id);
-       s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
-       fi->q.free_scsi_oxid[x_id] = OXID_AVAILABLE;
-
-       /* provide Tachyon will another set of buffers */
-       if (offset == (NO_OF_ENTRIES - 1))
-               update_SFSBQ_indx(fi);
-       LEAVE("handle_SCSI_status_interrupt");
-}
-
-static void invalidate_SEST_entry(struct fc_info *fi, u_short received_ox_id)
-{
-u_short x_id = received_ox_id & MAX_SCSI_XID;
-       /* Invalidate SEST entry if it is an OutBound SEST Entry 
-        */
-       if (!(received_ox_id & SCSI_READ_BIT)) {
-       u_int *ptr_tach_header, *ptr_edb;
-       u_short temp_ox_id = NOT_SCSI_XID;
-       int i;
-               *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
-
-               /* Invalidate the Tachyon Header structure 
-                */
-               ptr_tach_header = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 
5)));
-               for (i = 0; i < NO_OF_TACH_HEADERS; i++) 
-                       if(fi->q.ptr_tachyon_header[i] == ptr_tach_header)
-                               break;
-               if (i < NO_OF_TACH_HEADERS) 
-                       memset(ptr_tach_header, 0xFF, 32);
-               else
-                       T_MSG("Tachyon Header not found while freeing in 
invalidate_SEST_entry()");
-
-               /* Invalidate the EDB used 
-                */
-               ptr_edb = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 7)));
-               for (i = 0; i < EDB_LEN; i++)
-                       if (fi->q.ptr_edb[i] == ptr_edb)
-                               break;
-               ptr_edb--;      
-               if (i < EDB_LEN) {
-                       do {
-                               ptr_edb += 2;
-                               fi->q.free_edb_list[i++] = EDB_FREE;
-                               if (i == EDB_LEN) {
-                                       i = 0;
-                                       ptr_edb = fi->q.ptr_edb_base - 1;
-                               }
-                       } while ((htonl(*ptr_edb) & 0x80000000) != 0x80000000);
-               }
-               else
-                       T_MSG("EDB not found while freeing in 
invalidate_SEST_entry()");
-               
-               /* Search for its other header structure and destroy it! 
-                */
-               if ((ptr_tach_header + 16) < (fi->q.ptr_tachyon_header_base + 
(MY_PAGE_SIZE/4)))
-                       ptr_tach_header += 16;
-               else
-                       ptr_tach_header = fi->q.ptr_tachyon_header_base;
-               while (temp_ox_id != x_id) {
-                       temp_ox_id = ntohl(*(ptr_tach_header + 6)) >> 16;
-                       if (temp_ox_id == x_id) {
-                               /* Paranoid checking...
-                                */
-                               for (i = 0; i < NO_OF_TACH_HEADERS; i++) 
-                                       if(fi->q.ptr_tachyon_header[i] == 
ptr_tach_header)
-                                               break;
-                               if (i < NO_OF_TACH_HEADERS)
-                                       memset(ptr_tach_header, 0xFF, 32);
-                               else
-                                       T_MSG("Tachyon Header not found while 
freeing in invalidate_SEST_entry()");
-                               break;
-                       }
-                       else {
-                               if ((ptr_tach_header + 16) < 
(fi->q.ptr_tachyon_header_base + (MY_PAGE_SIZE/4)))
-                                       ptr_tach_header += 16;
-                               else
-                                       ptr_tach_header = 
fi->q.ptr_tachyon_header_base;
-                       }
-               }
-       }
-       else {
-       u_short sdb_table_indx;
-               /* An Inbound Command has completed or needs to be Aborted. 
-                * Clear up the SDB buffers.
-                */
-               sdb_table_indx = *(fi->q.ptr_sest[x_id] + 5);
-               fi->q.sdb_slot_status[sdb_table_indx] = SDB_FREE;
-       }
-}
-
-static void handle_Inbound_SCSI_Command_interrupt(struct fc_info *fi)
-{
-u_int *ptr_imq_entry;
-int queue_indx, offset;
-       ENTER("handle_Inbound_SCSI_Command_interrupt");
-       ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
-       offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
-       queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
-       queue_indx = queue_indx >> 16;
-       /* We discard the SCSI frame as we shouldn't be receiving
-        * a SCSI Command in the first place 
-        */
-       /* provide Tachyon will another set of buffers */
-       if (offset == (NO_OF_ENTRIES - 1))
-               update_SFSBQ_indx(fi);
-       LEAVE("handle_Inbound_SCSI_Command_interrupt");
-}
-
-static void handle_SFS_interrupt(struct fc_info *fi)
-{
-u_int *ptr_imq_entry, *buff_addr;
-u_int class_of_frame, type_of_frame, s_id, els_type = 0, rctl;
-int queue_indx, offset, payload_size, login_state;
-u_short received_ox_id, fs_cmnd_code;
-       ENTER("handle_SFS_interrupt");
-       ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];
-       offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;
-       queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;
-       queue_indx = queue_indx >> 16;
-       DPRINTK("queue_indx = %d, offset  = %d\n", queue_indx, offset);
-       payload_size = ntohl(*(ptr_imq_entry + 2));
-       DPRINTK("payload_size = %d", payload_size);
-
-       buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + 
queue_indx*NO_OF_ENTRIES + offset)));
-
-       /* extract Type of Frame */
-       type_of_frame = ntohl(*(buff_addr + 4)) & 0xFF000000;
-       s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
-       received_ox_id = ntohl(*(buff_addr + 6)) >> 16;
-       switch(type_of_frame) {
-               case TYPE_BLS:
-                       rctl = ntohl(*(buff_addr + 2)) & 0xFF000000;
-                       switch(rctl) {
-                               case RCTL_BASIC_ABTS:
-                                       /* As an Initiator, we should never be 
receiving 
-                                        * this.
-                                        */
-                                       DPRINTK1("ABTS received from S_ID 0x%x 
with OX_ID = %x", s_id, received_ox_id);
-                                       break;
-                       }
-                       break;
-               case TYPE_ELS:
-                       class_of_frame = ntohl(*(buff_addr + 8));
-                       login_state = sid_logged_in(fi, s_id);
-                       switch(class_of_frame & 0xFF000000) {
-                               case ELS_PLOGI:
-                                       if (s_id != fi->g.my_id) {
-                                               u_int ret_code;
-                                               DPRINTK1("PLOGI received from 
D_ID 0x%x with 0X_ID = %x", s_id, received_ox_id);
-                                               if ((ret_code = plogi_ok(fi, 
buff_addr, payload_size)) == 0){
-                                                       tx_logi_acc(fi, 
ELS_ACC, s_id, received_ox_id);
-                                                       
add_to_address_cache(fi, buff_addr);
-                                               }
-                                               else {
-                                                       u_short cmnd_code = 
ret_code >> 16;
-                                                       u_short expln_code =  
ret_code;
-                                                       tx_ls_rjt(fi, s_id, 
received_ox_id, cmnd_code, expln_code);
-                                               }
-                                       }
-                                       break;
-                               case ELS_ACC:
-                                       els_type = remove_from_ox_id_list(fi, 
received_ox_id);
-                                       DPRINTK1("ELS_ACC received from D_ID 
0x%x in response to ELS %x", s_id, els_type);
-                                       switch(els_type) {
-                                               case ELS_PLOGI:
-                                                       
add_to_address_cache(fi, buff_addr);
-                                                       tx_prli(fi, ELS_PRLI, 
s_id, OX_ID_FIRST_SEQUENCE);
-                                                       break;
-                                               case ELS_FLOGI:
-                                                       
add_to_address_cache(fi, buff_addr);
-                                                       fi->g.my_id = 
ntohl(*(buff_addr + 2)) & 0x00FFFFFF;
-                                                       fi->g.fabric_present = 
TRUE;
-                                                       fi->g.my_ddaa = 
fi->g.my_id & 0xFFFF00;
-                                                       /* Login to the Name 
Server 
-                                                        */
-                                                       tx_logi(fi, ELS_PLOGI, 
DIRECTORY_SERVER); 
-                                                       break;
-                                               case ELS_NS_PLOGI:
-                                                       fi->g.name_server = 
TRUE;
-                                                       
add_to_address_cache(fi, buff_addr);
-                                                       tx_name_server_req(fi, 
FCS_RFC_4);
-                                                       tx_scr(fi);
-                                                       /* Some devices have a 
delay before 
-                                                        * registering with the 
Name Server 
-                                                        */
-                                                       udelay(500); 
-                                                       tx_name_server_req(fi, 
FCS_GP_ID4);
-                                                       break;
-                                               case ELS_PRLI:
-                                                       mark_scsi_sid(fi, 
buff_addr, ADD_ENTRY);
-                                                       break;
-                                               case ELS_ADISC:
-                                                       if 
(!(validate_login(fi, buff_addr)))
-                                                               tx_logo(fi, 
s_id, OX_ID_FIRST_SEQUENCE);
-                                                       break;
-                                       }
-                                       break;
-                               case ELS_PDISC:
-                                       DPRINTK1("ELS_PDISC received from D_ID 
0x%x", s_id);
-                                       tx_logo(fi, s_id, received_ox_id);
-                                       break;
-                               case ELS_ADISC:
-                                       DPRINTK1("ELS_ADISC received from D_ID 
0x%x", s_id);
-                                       if (node_logged_in_prev(fi, buff_addr))
-                                               tx_adisc(fi, ELS_ACC, s_id, 
received_ox_id);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_PRLI:
-                                       DPRINTK1("ELS_PRLI received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN)) {
-                                               tx_prli(fi, ELS_ACC, s_id, 
received_ox_id);
-                                               mark_scsi_sid(fi, buff_addr, 
ADD_ENTRY);
-                                       }
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_PRLO:
-                                       DPRINTK1("ELS_PRLO received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_OUT) || 
(login_state == NODE_NOT_PRESENT))
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       else
-                                       if (login_state == NODE_LOGGED_IN)
-
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                       if (login_state == 
NODE_PROCESS_LOGGED_IN) {
-                                               tx_prli(fi, ELS_ACC, s_id, 
received_ox_id);
-                                               mark_scsi_sid(fi, buff_addr, 
DELETE_ENTRY);
-                                       }
-                                       break;
-                               case ELS_LS_RJT:
-                                       els_type = remove_from_ox_id_list(fi, 
received_ox_id);
-                                       DPRINTK1("ELS_LS_RJT received from D_ID 
0x%x in response to %x", s_id, els_type);
-                                       /* We should be chking the reason code.
-                                        */
-                                       switch (els_type) {
-                                               case ELS_ADISC:
-                                                       tx_logi(fi, ELS_PLOGI, 
s_id);
-                                                       break;
-                                       }               
-                                       break;
-                               case ELS_LOGO:
-                                       els_type = remove_from_ox_id_list(fi, 
received_ox_id);
-                                       DPRINTK1("ELS_LOGO received from D_ID 
0x%x in response to %x", s_id, els_type);
-                                       remove_from_address_cache(fi, 
buff_addr, ELS_LOGO);
-                                       tx_acc(fi, s_id, received_ox_id);
-                                       if (els_type == ELS_ADISC)
-                                               tx_logi(fi, ELS_PLOGI, s_id);
-                                       break;
-                               case ELS_RSCN:
-                                       DPRINTK1("ELS_RSCN received from D_ID 
0x%x", s_id);
-                                       tx_acc(fi, s_id, received_ox_id);
-                                       remove_from_address_cache(fi, 
buff_addr, ELS_RSCN);
-                                       break;
-                               case ELS_FARP_REQ:
-                                       /* We do not support FARP.
-                                          So, silently discard it */
-                                       DPRINTK1("ELS_FARP_REQ received from 
D_ID 0x%x", s_id);
-                                       break;
-                               case ELS_ABTX:
-                                       DPRINTK1("ELS_ABTX received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_FLOGI:
-                                       DPRINTK1("ELS_FLOGI received from D_ID 
0x%x", s_id);
-                                       if (fi->g.ptp_up == TRUE) {
-                                               /* The node could have come up 
as an N_Port
-                                                * in a Loop! So,try 
initializing as an NL_port
-                                                */
-                                               take_tachyon_offline(fi);
-                                               /* write AL_TIME & E_D_TOV into 
the registers */
-                                               writel(TOV_VALUES, 
fi->t_r.ptr_fm_tov_reg);
-                                               writel(LOOP_INIT_SOFT_ADDRESS, 
fi->t_r.ptr_fm_config_reg);
-                                               DPRINTK1("FLOGI received, 
TACHYON initializing as L_Port...\n");
-                                               writel(INITIALIZE, 
fi->t_r.ptr_fm_control_reg);
-                                       }
-                                       else {
-                                               if ((login_state == 
NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
-                                                       tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                               else
-                                                       tx_logo(fi, s_id, 
received_ox_id);
-                                       }
-                                       break;
-                               case ELS_ADVC:
-                                       DPRINTK1("ELS_ADVC received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_ECHO:
-                                       DPRINTK1("ELS_ECHO received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_ESTC:
-                                       DPRINTK1("ELS_ESTC received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_ESTS:
-                                       DPRINTK1("ELS_ESTS received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_RCS:
-                                       DPRINTK1("ELS_RCS received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_RES:
-                                       DPRINTK1("ELS_RES received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_RLS:
-                                       DPRINTK1("ELS_RLS received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_RRQ:
-                                       DPRINTK1("ELS_RRQ received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_RSS:
-                                       DPRINTK1("ELS_RSS received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_RTV:
-                                       DPRINTK1("ELS_RTV received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_RSI:
-                                       DPRINTK1("ELS_RSI received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_TEST:
-                                       /* No reply sequence */
-                                       DPRINTK1("ELS_TEST received from D_ID 
0x%x", s_id);
-                                       break;
-                               case ELS_RNC:
-                                       DPRINTK1("ELS_RNC received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_RVCS:
-                                       DPRINTK1("ELS_RVCS received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_TPLS:
-                                       DPRINTK1("ELS_TPLS received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_GAID:
-                                       DPRINTK1("ELS_GAID received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_FACT:
-                                       DPRINTK1("ELS_FACT received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_FAN:
-                                       /* Hmmm... You don't support FAN ??? */
-                                       DPRINTK1("ELS_FAN received from D_ID 
0x%x", s_id);
-                                       tx_ls_rjt(fi, s_id, received_ox_id, 
CMND_NOT_SUPP, NO_EXPLN);
-                                       break;
-                               case ELS_FDACT:
-                                       DPRINTK1("ELS_FDACT received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_NACT:
-                                       DPRINTK1("ELS_NACT received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_NDACT:
-                                       DPRINTK1("ELS_NDACT received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_QoSR:
-                                       DPRINTK1("ELS_QoSR received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               case ELS_FDISC:
-                                       DPRINTK1("ELS_FDISC received from D_ID 
0x%x", s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                               default:
-                                       DPRINTK1("ELS Frame %x received from 
D_ID 0x%x", class_of_frame, s_id);
-                                       if ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN))
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
-                                       else
-                                               tx_logo(fi, s_id, 
received_ox_id);
-                                       break;
-                       }
-                       break;
-               case TYPE_FC_SERVICES:
-                       fs_cmnd_code = (ntohl(*(buff_addr + 10)) & 0xFFFF0000) 
>>16;
-                       switch(fs_cmnd_code) {
-                               case FCS_ACC:
-                                       els_type = remove_from_ox_id_list(fi, 
received_ox_id);
-                                       DPRINTK1("FCS_ACC received from D_ID 
0x%x in response to %x", s_id, els_type);
-                                       if (els_type == FCS_GP_ID4) 
-                                               explore_fabric(fi, buff_addr);
-                                       break;
-                               case FCS_REJECT:
-                                       DPRINTK1("FCS_REJECT received from D_ID 
0x%x in response to %x", s_id, els_type);
-                                       break;
-                       }
-                       break;
-               case TYPE_LLC_SNAP:
-                       rx_net_packet(fi, (u_char *)buff_addr, payload_size);
-                       break;
-               default:
-                       T_MSG("Frame Type %x received from %x", type_of_frame, 
s_id);
-       }
-
-       /* provide Tachyon will another set of buffers */
-       if (offset == (NO_OF_ENTRIES - 1))
-               update_SFSBQ_indx(fi);
-       LEAVE("handle_SFS_interrupt");
-}
-
-static void handle_FM_interrupt(struct fc_info *fi)
-{
-u_int fm_status;
-u_int tachyon_status;
-
-       ENTER("handle_FM_interrupt");
-       fm_status = readl(fi->t_r.ptr_fm_status_reg);
-       tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
-       DPRINTK("FM_status = %x, Tachyon_status = %x", fm_status, 
tachyon_status);
-       if (fm_status & LINK_DOWN) {
-               T_MSG("Fibre Channel Link DOWN");
-               fm_status = readl(fi->t_r.ptr_fm_status_reg);
-               
-               del_timer(&fi->explore_timer);
-               del_timer(&fi->nport_timer);
-               del_timer(&fi->lport_timer);
-               del_timer(&fi->display_cache_timer);
-               fi->g.link_up = FALSE;
-               if (fi->g.ptp_up == TRUE)
-                       fi->g.n_port_try = FALSE;
-               fi->g.ptp_up = FALSE;
-               fi->g.port_discovery = FALSE;
-               fi->g.explore_fabric = FALSE;
-               fi->g.perform_adisc = FALSE;
-
-               /* Logout will all nodes */
-               if (fi->node_info_list) {
-                       struct fc_node_info *temp_list = fi->node_info_list;
-                               while(temp_list) {
-                                       temp_list->login = LOGIN_ATTEMPTED;
-                                       temp_list = temp_list->next;
-                               }
-                               fi->num_nodes = 0;
-               }
-
-               if ((fi->g.n_port_try == FALSE) && (fi->g.dont_init == FALSE)){
-                       take_tachyon_offline(fi);
-                       /* write AL_TIME & E_D_TOV into the registers */
-                       writel(TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
-                       
-                       if ((fi->g.fabric_present == TRUE) && (fi->g.loop_up == 
TRUE)) {
-                       u_int al_pa = fi->g.my_id & 0xFF;
-                               writel((al_pa << 24) | LOOP_INIT_FABRIC_ADDRESS 
| LOOP_INIT_PREVIOUS_ADDRESS, fi->t_r.ptr_fm_config_reg);
-                       }
-                       else 
-                       if (fi->g.loop_up == TRUE) {
-                       u_int al_pa = fi->g.my_id & 0xFF;
-                               writel((al_pa << 24) | 
LOOP_INIT_PREVIOUS_ADDRESS, fi->t_r.ptr_fm_config_reg);
-                       }
-                       else 
-                               writel(LOOP_INIT_SOFT_ADDRESS, 
fi->t_r.ptr_fm_config_reg);
-                       fi->g.loop_up = FALSE;
-                       DPRINTK1("In LDWN TACHYON initializing as L_Port...\n");
-                       writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
-               }
-       }
-
-    if (fm_status & NON_PARTICIPATING) {
-               T_MSG("Did not acquire an AL_PA. I am not participating");
-    }
-       else
-       if ((fm_status & LINK_UP) && ((fm_status & LINK_DOWN) == 0)) {
-         T_MSG("Fibre Channel Link UP");
-         if ((fm_status & NON_PARTICIPATING) != TRUE) {
-               fi->g.link_up = TRUE;
-               if (tachyon_status & OSM_FROZEN) {
-                       reset_tachyon(fi, ERROR_RELEASE);
-                       reset_tachyon(fi, OCQ_RESET);
-               }
-               init_timer(&fi->explore_timer);
-               init_timer(&fi->nport_timer);
-               init_timer(&fi->lport_timer);
-               init_timer(&fi->display_cache_timer);
-               if ((fm_status & OLD_PORT) == 0) {
-                       fi->g.loop_up = TRUE;
-                       fi->g.ptp_up = FALSE;
-                       fi->g.my_id = readl(fi->t_r.ptr_fm_config_reg) >> 24;
-                       DPRINTK1("My AL_PA = %x", fi->g.my_id);
-                       fi->g.port_discovery = TRUE;
-                       fi->g.explore_fabric = FALSE;
-               }
-               else
-               if (((fm_status & 0xF0) == OLD_PORT) && ((fm_status & 0x0F) == 
PORT_STATE_ACTIVE)) {
-                       fi->g.loop_up = FALSE;
-                       fi->g.my_id = 0x0;
-                       /* In a point-to-point configuration, we expect to be
-                        * connected to an F_Port. This driver does not yet 
support
-                        * a configuration where it is connected to another 
N_Port
-                        * directly.
-                        */
-                       fi->g.explore_fabric = TRUE;
-                       fi->g.port_discovery = FALSE;
-                       if (fi->g.n_port_try == FALSE) {
-                               take_tachyon_offline(fi);
-                               /* write R_T_TOV & E_D_TOV into the registers */
-                               writel(PTP_TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
-                               writel(BB_CREDIT | NPORT, 
fi->t_r.ptr_fm_config_reg);
-                               fi->g.n_port_try = TRUE;
-                               DPRINTK1("In LUP TACHYON initializing as 
N_Port...\n");
-                               writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
-                       }
-                       else {
-                               fi->g.ptp_up = TRUE;
-                               tx_logi(fi, ELS_FLOGI, F_PORT); 
-                       }
-               }
-               fi->g.my_ddaa = 0x0;
-               fi->g.fabric_present = FALSE; 
-               /* We havn't sent out any Name Server Reqs */
-               fi->g.name_server = FALSE;
-               fi->g.alpa_list_index = 0;
-               fi->g.ox_id = NOT_SCSI_XID;
-               fi->g.my_mtu = TACH_FRAME_SIZE;
-               
-               /* Implicitly LOGO with all logged-in nodes. 
-                */
-               if (fi->node_info_list) {
-               struct fc_node_info *temp_list = fi->node_info_list;
-                       while(temp_list) {
-                               temp_list->login = LOGIN_ATTEMPTED;
-                               temp_list = temp_list->next;
-                       }
-                       fi->num_nodes = 0;
-                       fi->g.perform_adisc = TRUE;
-                       //fi->g.perform_adisc = FALSE;
-                       fi->g.port_discovery = FALSE;
-                       tx_logi(fi, ELS_FLOGI, F_PORT); 
-               }
-               else { 
-                       /* If Link coming up for the _first_ time or no nodes
-                        * were logged in before...
-                        */
-                       fi->g.scsi_oxid = 0;
-                       fi->g.seq_id = 0x00;
-                       fi->g.perform_adisc = FALSE;
-               }
-
-               /* reset OX_ID table */
-               while (fi->ox_id_list) {
-               struct ox_id_els_map *temp = fi->ox_id_list;
-                       fi->ox_id_list = fi->ox_id_list->next;
-                       kfree(temp);
-               }
-               fi->ox_id_list = NULL;
-         } /* End of if partipating */
-       }
-
-       if (fm_status & ELASTIC_STORE_ERROR) {
-               /* Too much junk on the Link 
-                */
-               /* Trying to clear it up by Txing PLOGI to urself */
-               if (fi->g.link_up == TRUE)
-                       tx_logi(fi, ELS_PLOGI, fi->g.my_id); 
-       }
-
-       if (fm_status & LOOP_UP) {
-               if (tachyon_status & OSM_FROZEN) {
-                       reset_tachyon(fi, ERROR_RELEASE);
-                       reset_tachyon(fi, OCQ_RESET);
-               }
-       }
-       
-       if (fm_status & NOS_OLS_RECEIVED){
-               if (fi->g.nport_timer_set == FALSE) {
-                       DPRINTK("NOS/OLS Received");
-                       DPRINTK("FM_status = %x", fm_status);
-                       fi->nport_timer.function = nos_ols_timer;
-                       fi->nport_timer.data = (unsigned long)fi;
-                       fi->nport_timer.expires = RUN_AT((3*HZ)/100); /* 30 
msec */
-                       init_timer(&fi->nport_timer);
-                       add_timer(&fi->nport_timer);
-                       fi->g.nport_timer_set = TRUE;
-               }
-       }
-
-       if (((fm_status & 0xF0) == OLD_PORT) && (((fm_status & 0x0F) == 
PORT_STATE_LF1) || ((fm_status & 0x0F) == PORT_STATE_LF2))) {
-               DPRINTK1("Link Fail-I in OLD-PORT.");
-               take_tachyon_offline(fi);
-               reset_tachyon(fi, SOFTWARE_RESET);
-       }
-
-       if (fm_status & LOOP_STATE_TIMEOUT){
-               if ((fm_status & 0xF0) == ARBITRATING) 
-                       DPRINTK1("ED_TOV timesout.In ARBITRATING state...");
-               if ((fm_status & 0xF0) == ARB_WON)
-                       DPRINTK1("ED_TOV timesout.In ARBITRATION WON state...");
-               if ((fm_status & 0xF0) == OPEN)
-                       DPRINTK1("ED_TOV timesout.In OPEN state...");
-               if ((fm_status & 0xF0) == OPENED)
-                       DPRINTK1("ED_TOV timesout.In OPENED state...");
-               if ((fm_status & 0xF0) == TX_CLS)
-                       DPRINTK1("ED_TOV timesout.In XMITTED CLOSE state...");
-               if ((fm_status & 0xF0) == RX_CLS)
-                       DPRINTK1("ED_TOV timesout.In RECEIVED CLOSE state...");
-               if ((fm_status & 0xF0) == INITIALIZING)
-                       DPRINTK1("ED_TOV timesout.In INITIALIZING state...");
-               DPRINTK1("Initializing Loop...");
-               writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
-       }
-       
-       if ((fm_status & BAD_ALPA) && (fi->g.loop_up == TRUE)) {
-       u_char bad_alpa = (readl(fi->t_r.ptr_fm_rx_al_pa_reg) & 0xFF00) >> 8;
-               if (tachyon_status & OSM_FROZEN) {
-                       reset_tachyon(fi, ERROR_RELEASE);
-                       reset_tachyon(fi, OCQ_RESET);
-               }
-               /* Fix for B34 */
-               tx_logi(fi, ELS_PLOGI, fi->g.my_id); 
-
-               if (!fi->g.port_discovery && !fi->g.perform_adisc) {
-                       if (bad_alpa != 0xFE)
-                               DPRINTK("Bad AL_PA = %x", bad_alpa);
-               }
-               else {
-                       if ((fi->g.perform_adisc == TRUE) && (bad_alpa == 
0x00)) {
-                               DPRINTK1("Performing ADISC...");
-                               fi->g.fabric_present = FALSE;
-                               perform_adisc(fi);
-                       }
-               }
-       }
-       
-       if (fm_status & LIPF_RECEIVED){
-               DPRINTK("LIP(F8) Received");
-       }
-
-       if (fm_status & LINK_FAILURE) {
-               if (fm_status & LOSS_OF_SIGNAL)
-                       DPRINTK1("Detected Loss of Signal.");
-               if (fm_status & OUT_OF_SYNC)
-                       DPRINTK1("Detected Loss of Synchronization.");
-       }
-
-       if (fm_status & TRANSMIT_PARITY_ERROR) {
-               /* Bad! Should not happen. Solution-> Hard Reset.
-                */
-               T_MSG("Parity Error. Perform Hard Reset!");
-       }
-
-       if (fi->g.alpa_list_index >= MAX_NODES){
-               if (fi->g.port_discovery == TRUE) {
-                       fi->g.port_discovery = FALSE;
-                       add_display_cache_timer(fi);
-               }
-               fi->g.alpa_list_index = MAX_NODES;
-       }
-
-       if (fi->g.port_discovery == TRUE) 
-               local_port_discovery(fi);
-
-       LEAVE("handle_FM_interrupt");
-       return;
-}
-
-static void local_port_discovery(struct fc_info *fi)
-{
-       if (fi->g.loop_up == TRUE) {
-               /* If this is not here, some of the Bad AL_PAs are missed. 
-                */
-               udelay(20); 
-               if ((fi->g.alpa_list_index == 0) && (fi->g.fabric_present == 
FALSE)){
-                       tx_logi(fi, ELS_FLOGI, F_PORT); 
-               }
-               else {
-               int login_state = sid_logged_in(fi, fi->g.my_ddaa | 
alpa_list[fi->g.alpa_list_index]);
-                       while ((fi->g.alpa_list_index == 0) || 
((fi->g.alpa_list_index < MAX_NODES) && ((login_state == NODE_LOGGED_IN) || 
(login_state == NODE_PROCESS_LOGGED_IN) || (alpa_list[fi->g.alpa_list_index] == 
(fi->g.my_id & 0xFF)))))
-                               fi->g.alpa_list_index++;
-                       if (fi->g.alpa_list_index < MAX_NODES)
-                               tx_logi(fi, ELS_PLOGI, 
alpa_list[fi->g.alpa_list_index]); 
-               }
-               fi->g.alpa_list_index++;
-               if (fi->g.alpa_list_index >= MAX_NODES){
-                       if (fi->g.port_discovery == TRUE) {
-                               fi->g.port_discovery = FALSE;
-                               add_display_cache_timer(fi);
-                       }
-                       fi->g.alpa_list_index = MAX_NODES;
-               }
-       }
-}
-
-static void nos_ols_timer(unsigned long data)
-{
-struct fc_info *fi = (struct fc_info*)data;
-u_int fm_status;
-       fm_status = readl(fi->t_r.ptr_fm_status_reg);
-       DPRINTK1("FM_status in timer= %x", fm_status);
-       fi->g.nport_timer_set = FALSE;
-       del_timer(&fi->nport_timer);
-       if ((fi->g.ptp_up == TRUE) || (fi->g.loop_up == TRUE))
-               return;
-       if (((fm_status & 0xF0) == OLD_PORT) && (((fm_status & 0x0F) == 
PORT_STATE_ACTIVE) || ((fm_status & 0x0F) == PORT_STATE_OFFLINE))) {
-               DPRINTK1("In OLD-PORT after E_D_TOV.");
-               take_tachyon_offline(fi);
-               /* write R_T_TOV & E_D_TOV into the registers */
-               writel(PTP_TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
-               writel(BB_CREDIT | NPORT, fi->t_r.ptr_fm_config_reg);
-               fi->g.n_port_try = TRUE;
-               DPRINTK1("In timer, TACHYON initializing as N_Port...\n");
-               writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
-       }
-       else
-       if ((fi->g.lport_timer_set == FALSE) && ((fm_status & 0xF0) == 
LOOP_FAIL)) {
-               DPRINTK1("Loop Fail after E_D_TOV.");
-               fi->lport_timer.function = loop_timer;
-               fi->lport_timer.data = (unsigned long)fi;
-               fi->lport_timer.expires = RUN_AT((8*HZ)/100); 
-               init_timer(&fi->lport_timer);
-               add_timer(&fi->lport_timer);
-               fi->g.lport_timer_set = TRUE;
-               take_tachyon_offline(fi);
-               reset_tachyon(fi, SOFTWARE_RESET);
-       }
-       else
-       if (((fm_status & 0xF0) == OLD_PORT) && (((fm_status & 0x0F) == 
PORT_STATE_LF1) || ((fm_status & 0x0F) == PORT_STATE_LF2))) {
-               DPRINTK1("Link Fail-II in OLD-PORT.");
-               take_tachyon_offline(fi);
-               reset_tachyon(fi, SOFTWARE_RESET);
-       }
-}
-
-static void loop_timer(unsigned long data)
-{
-struct fc_info *fi = (struct fc_info*)data;
-       fi->g.lport_timer_set = FALSE;
-       del_timer(&fi->lport_timer);
-       if ((fi->g.ptp_up == TRUE) || (fi->g.loop_up == TRUE))
-               return;
-}
-
-static void add_display_cache_timer(struct fc_info *fi)
-{
-       fi->display_cache_timer.function = display_cache_timer;
-       fi->display_cache_timer.data = (unsigned long)fi;
-       fi->display_cache_timer.expires = RUN_AT(fi->num_nodes * HZ); 
-       init_timer(&fi->display_cache_timer);
-       add_timer(&fi->display_cache_timer);
-}
-
-static void display_cache_timer(unsigned long data)
-{
-struct fc_info *fi = (struct fc_info*)data;
-       del_timer(&fi->display_cache_timer);
-       display_cache(fi);
-       return;
-}
-
-static void reset_tachyon(struct fc_info *fi, u_int value)
-{
-u_int tachyon_status, reset_done = OCQ_RESET_STATUS | SCSI_FREEZE_STATUS;
-int not_done = 1, i = 0;
-       writel(value, fi->t_r.ptr_tach_control_reg);
-       if (value == OCQ_RESET) 
-               fi->q.ocq_prod_indx = 0;
-       tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
-
-       /* Software resets are immediately done, whereas other aren't. It 
-       about 30 clocks to do the reset */
-       if (value != SOFTWARE_RESET) {
-               while(not_done) {
-                       if (i++ > 100000) {
-                               T_MSG("Reset was unsuccessful! Tachyon Status = 
%x", tachyon_status);
-                               break;
-                       }
-                       tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
-                       if ((tachyon_status & reset_done) == 0)
-                               not_done = 0;
-               }
-       }
-       else {
-               write_to_tachyon_registers(fi);
-       }
-}
-
-static void take_tachyon_offline(struct fc_info *fi)
-{
-u_int fm_status = readl(fi->t_r.ptr_fm_status_reg);
-
-       /* The first two conditions will never be true. The Manual and
-        * the errata say this. But the current implementation is
-        * decently stable.
-        */      
-       //if ((fm_status & 0xF0) == LOOP_FAIL) {
-       if (fm_status == LOOP_FAIL) {
-               // workaround as in P. 89 
-               writel(HOST_CONTROL, fi->t_r.ptr_fm_control_reg);
-               if (fi->g.loop_up == TRUE)
-                       writel(SOFTWARE_RESET, fi->t_r.ptr_tach_control_reg);
-               else {
-                       writel(OFFLINE, fi->t_r.ptr_fm_control_reg);
-                       writel(EXIT_HOST_CONTROL, fi->t_r.ptr_fm_control_reg);
-               }
-       }
-       else
-       //if ((fm_status & LOOP_UP) == LOOP_UP) {
-       if (fm_status == LOOP_UP) {
-               writel(SOFTWARE_RESET, fi->t_r.ptr_tach_control_reg);
-       }
-       else
-               writel(OFFLINE, fi->t_r.ptr_fm_control_reg);
-}
-
-
-static void read_novram(struct fc_info *fi)
-{
-int off = 0;
-       fi->n_r.ptr_novram_hw_control_reg = fi->i_r.ptr_ichip_hw_control_reg; 
-       fi->n_r.ptr_novram_hw_status_reg = fi->i_r.ptr_ichip_hw_status_reg; 
-       iph5526_nr_do_init(fi);
-       if (fi->clone_id == PCI_VENDOR_ID_INTERPHASE)
-               off = 32;
-       
-       fi->g.my_node_name_high = (fi->n_r.data[off] << 16) | 
fi->n_r.data[off+1];
-       fi->g.my_node_name_low = (fi->n_r.data[off+2] << 16) | 
fi->n_r.data[off+3];
-       fi->g.my_port_name_high = (fi->n_r.data[off+4] << 16) | 
fi->n_r.data[off+5];
-       fi->g.my_port_name_low = (fi->n_r.data[off+6] << 16) | 
fi->n_r.data[off+7];
-       DPRINTK("node_name = %x %x", fi->g.my_node_name_high, 
fi->g.my_node_name_low);
-       DPRINTK("port_name = %x %x", fi->g.my_port_name_high, 
fi->g.my_port_name_low);
-}
-
-static void reset_ichip(struct fc_info *fi)
-{
-       /* (i)chip reset */
-       writel(ICHIP_HCR_RESET, fi->i_r.ptr_ichip_hw_control_reg);
-       /*wait for chip to get reset */
-       mdelay(10);
-       /*de-assert reset */
-       writel(ICHIP_HCR_DERESET, fi->i_r.ptr_ichip_hw_control_reg);
-       
-       /* enable INT lines on the (i)chip */
-       writel(ICHIP_HCR_ENABLE_INTA , fi->i_r.ptr_ichip_hw_control_reg);
-       /* enable byte swap */
-       writel(ICHIP_HAMR_BYTE_SWAP_ADDR_TR, 
fi->i_r.ptr_ichip_hw_addr_mask_reg);
-}
-
-static void tx_logi(struct fc_info *fi, u_int logi, u_int d_id)
-{
-int int_required = 1;
-u_short ox_id = OX_ID_FIRST_SEQUENCE;
-u_int r_ctl = RCTL_ELS_UCTL;
-u_int type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
-u_int my_mtu = fi->g.my_mtu;
-       ENTER("tx_logi");
-       /* We don't want interrupted for our own logi. 
-        * It screws up the port discovery process. 
-        */
-       if (d_id == fi->g.my_id)
-               int_required = 0;
-       fill_login_frame(fi, logi);     
-       fi->g.type_of_frame = FC_ELS;
-       memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.login, sizeof(LOGIN));
-       tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),sizeof(LOGIN), 
r_ctl, type, d_id, my_mtu, int_required, ox_id, logi);
-       fi->g.e_i++;
-       if (fi->g.e_i == MAX_PENDING_FRAMES)
-               fi->g.e_i = 0;
-       LEAVE("tx_logi");
-       return;
-}
-
-static void tx_logi_acc(struct fc_info *fi, u_int logi, u_int d_id, u_short 
received_ox_id)
-{
-int int_required = 0;
-u_int r_ctl = RCTL_ELS_SCTL;
-u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE;
-u_int my_mtu = fi->g.my_mtu;
-       ENTER("tx_logi_acc");
-       fill_login_frame(fi, logi);     
-       fi->g.type_of_frame = FC_ELS;
-       memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.login, sizeof(LOGIN));
-       tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),sizeof(LOGIN), 
r_ctl, type, d_id, my_mtu, int_required, received_ox_id, logi);
-       fi->g.e_i++;
-       if (fi->g.e_i == MAX_PENDING_FRAMES)
-               fi->g.e_i = 0;
-       LEAVE("tx_logi_acc");
-       return;
-}
-
-static void tx_prli(struct fc_info *fi, u_int command_code, u_int d_id, 
u_short received_ox_id)
-{
-int int_required = 1;
-u_int r_ctl = RCTL_ELS_UCTL;
-u_int type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
-u_int my_mtu = fi->g.my_mtu;
-       ENTER("tx_prli");
-       if (command_code == ELS_PRLI)
-               fi->g.prli.cmnd_code = htons((ELS_PRLI | PAGE_LEN) >> 16);
-       else {
-               fi->g.prli.cmnd_code = htons((ELS_ACC | PAGE_LEN) >> 16);
-               int_required = 0;
-               type  = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE;
-               r_ctl = RCTL_ELS_SCTL;
-       }
-       fi->g.prli.payload_length = htons(PRLI_LEN);
-       fi->g.prli.type_code = htons(FCP_TYPE_CODE);
-       fi->g.prli.est_image_pair = htons(IMAGE_PAIR);
-       fi->g.prli.responder_pa = 0;
-       fi->g.prli.originator_pa = 0;
-       fi->g.prli.service_params = htonl(INITIATOR_FUNC | 
READ_XFER_RDY_DISABLED);
-       fi->g.type_of_frame = FC_ELS;
-       memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.prli, sizeof(PRLI));
-       tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]), sizeof(PRLI), 
r_ctl, type, d_id, my_mtu, int_required, received_ox_id, command_code);
-       fi->g.e_i++;
-       if (fi->g.e_i == MAX_PENDING_FRAMES)
-               fi->g.e_i = 0;
-       LEAVE("tx_prli");
-       return;
-}
-
-static void tx_logo(struct fc_info *fi, u_int d_id, u_short received_ox_id)
-{
-int int_required = 1;
-u_int r_ctl = RCTL_ELS_UCTL;
-u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | SEQUENCE_RESPONDER | 
FIRST_SEQUENCE | END_SEQUENCE | SEQUENCE_INITIATIVE;
-int size = sizeof(LOGO);
-char fc_id[3];
-u_int my_mtu = fi->g.my_mtu;
-       ENTER("tx_logo");
-       fi->g.logo.logo_cmnd = htonl(ELS_LOGO);
-       fi->g.logo.reserved = 0;
-       memcpy(fc_id, &(fi->g.my_id), 3);
-       fi->g.logo.n_port_id_0 = fc_id[0];
-       fi->g.logo.n_port_id_1 = fc_id[1];
-       fi->g.logo.n_port_id_2 = fc_id[2];
-       fi->g.logo.port_name_up = htonl(N_PORT_NAME_HIGH);
-       fi->g.logo.port_name_low = htonl(N_PORT_NAME_LOW);
-       fi->g.type_of_frame = FC_ELS;
-       memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.logo, sizeof(LOGO));
-       tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, 
type, d_id, my_mtu, int_required, received_ox_id, ELS_LOGO);
-       fi->g.e_i++;
-       if (fi->g.e_i == MAX_PENDING_FRAMES)
-               fi->g.e_i = 0;
-       LEAVE("tx_logo");
-}
-
-static void tx_adisc(struct fc_info *fi, u_int cmnd_code, u_int d_id, u_short 
received_ox_id)
-{
-int int_required = 0;
-u_int r_ctl = RCTL_ELS_SCTL;
-u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | SEQUENCE_RESPONDER | 
FIRST_SEQUENCE | END_SEQUENCE;
-int size = sizeof(ADISC);
-u_int my_mtu = fi->g.my_mtu;
-       fi->g.adisc.ls_cmnd_code = htonl(cmnd_code);
-       fi->g.adisc.hard_address = htonl(0);
-       fi->g.adisc.port_name_high = htonl(N_PORT_NAME_HIGH);   
-       fi->g.adisc.port_name_low = htonl(N_PORT_NAME_LOW);     
-       fi->g.adisc.node_name_high = htonl(NODE_NAME_HIGH);     
-       fi->g.adisc.node_name_low = htonl(NODE_NAME_LOW);       
-       fi->g.adisc.n_port_id = htonl(fi->g.my_id);
-       if (cmnd_code == ELS_ADISC) {
-               int_required = 1;
-               r_ctl = RCTL_ELS_UCTL;
-               type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
-       }
-       fi->g.type_of_frame = FC_ELS;
-       memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.adisc, size);
-       tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, 
type, d_id, my_mtu, int_required, received_ox_id, cmnd_code);
-       fi->g.e_i++;
-       if (fi->g.e_i == MAX_PENDING_FRAMES)
-               fi->g.e_i = 0;
-}
-
-static void tx_ls_rjt(struct fc_info *fi, u_int d_id, u_short received_ox_id, 
u_short reason_code, u_short expln_code)
-{
-int int_required = 0;
-u_int r_ctl = RCTL_ELS_SCTL;
-u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE;
-int size = sizeof(LS_RJT);
-u_int my_mtu = fi->g.my_mtu;
-       ENTER("tx_ls_rjt");
-       fi->g.ls_rjt.cmnd_code = htonl(ELS_LS_RJT);
-       fi->g.ls_rjt.reason_code = htonl((reason_code << 16) | expln_code); 
-       fi->g.type_of_frame = FC_ELS;
-       memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.ls_rjt, size);
-       tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, 
type, d_id, my_mtu, int_required, received_ox_id, ELS_LS_RJT);
-       fi->g.e_i++;
-       if (fi->g.e_i == MAX_PENDING_FRAMES)
-               fi->g.e_i = 0;
-       LEAVE("tx_ls_rjt");
-}
-
-static void tx_abts(struct fc_info *fi, u_int d_id, u_short ox_id)
-{
-int int_required = 1;
-u_int r_ctl = RCTL_BASIC_ABTS;
-u_int type  = TYPE_BLS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
-int size = 0;
-u_int my_mtu = fi->g.my_mtu;
-       ENTER("tx_abts");
-       fi->g.type_of_frame = FC_BLS;
-       tx_exchange(fi, NULL, size, r_ctl, type, d_id, my_mtu, int_required, 
ox_id, RCTL_BASIC_ABTS);
-       LEAVE("tx_abts");
-}
-
-static u_int plogi_ok(struct fc_info *fi, u_int *buff_addr, int size)
-{
-int ret_code = 0;
-u_short mtu = ntohl(*(buff_addr + 10)) & 0x00000FFF;
-u_short class3 = ntohl(*(buff_addr + 25)) >> 16;
-u_short class3_conc_seq = ntohl(*(buff_addr + 27)) >> 16;
-u_short open_seq = ntohl(*(buff_addr + 28)) >> 16;
-       DPRINTK1("mtu = %x class3 = %x conc_seq = %x open_seq = %x", mtu, 
class3, class3_conc_seq, open_seq);   
-       size -= TACHYON_HEADER_LEN;
-       if (!(class3 & 0x8000)) {
-               DPRINTK1("Received PLOGI with class3 = %x", class3);
-               ret_code = (LOGICAL_ERR << 16) | NO_EXPLN;
-               return ret_code;
-       }
-       if (mtu < 256) {
-               DPRINTK1("Received PLOGI with MTU set to %x", mtu);
-               ret_code = (LOGICAL_ERR << 16) | RECV_FIELD_SIZE;
-               return ret_code;
-       }
-       if (size != PLOGI_LEN) {        
-               DPRINTK1("Received PLOGI of size %x", size);
-               ret_code = (LOGICAL_ERR << 16) | INV_PAYLOAD_LEN;
-               return ret_code;
-       }
-       if (class3_conc_seq == 0) {     
-               DPRINTK1("Received PLOGI with conc_seq == 0");
-               ret_code = (LOGICAL_ERR << 16) | CONC_SEQ;
-               return ret_code;
-       }
-       if (open_seq == 0) {    
-               DPRINTK1("Received PLOGI with open_seq == 0");
-               ret_code = (LOGICAL_ERR << 16) | NO_EXPLN;
-               return ret_code;
-       }
-
-       /* Could potentially check for more fields, but might end up
-          not talking to most of the devices. ;-) */
-       /* Things that could get checked are:
-          common_features = 0x8800
-          total_concurrent_seq = at least 1
-       */
-       return ret_code;
-}
-
-static void tx_acc(struct fc_info *fi, u_int d_id, u_short received_ox_id)
-{
-int int_required = 0;
-u_int r_ctl = RCTL_ELS_SCTL;
-u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE;
-int size = sizeof(ACC);
-u_int my_mtu = fi->g.my_mtu;
-       ENTER("tx_acc");
-       fi->g.acc.cmnd_code = htonl(ELS_ACC);
-       fi->g.type_of_frame = FC_ELS;
-       memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.acc, size);
-       tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, 
type, d_id, my_mtu, int_required, received_ox_id, ELS_ACC);
-       fi->g.e_i++;
-       if (fi->g.e_i == MAX_PENDING_FRAMES)
-               fi->g.e_i = 0;
-       LEAVE("tx_acc");
-}
-
-
-static void tx_name_server_req(struct fc_info *fi, u_int req)
-{
-int int_required = 1, i, size = 0;
-u_short ox_id = OX_ID_FIRST_SEQUENCE;
-u_int type  = TYPE_FC_SERVICES | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
-u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_CONTROL;
-u_int my_mtu = fi->g.my_mtu, d_id = DIRECTORY_SERVER;
-CT_HDR ct_hdr;
-       ENTER("tx_name_server_req");
-       /* Fill up CT_Header */
-       ct_hdr.rev_in_id = htonl(FC_CT_REV);
-       ct_hdr.fs_type = DIRECTORY_SERVER_APP;
-       ct_hdr.fs_subtype = NAME_SERVICE;
-       ct_hdr.options = 0;
-       ct_hdr.resv1 = 0;
-       ct_hdr.cmnd_resp_code = htons(req >> 16);
-       ct_hdr.max_res_size = 0;
-       ct_hdr.resv2 = 0;
-       ct_hdr.reason_code = 0;
-       ct_hdr.expln_code = 0;
-       ct_hdr.vendor_unique = 0;
-       
-       fi->g.type_of_frame = FC_ELS;
-       switch(req) {
-               case FCS_RFC_4:
-                       memcpy(&(fi->g.rfc_4.ct_hdr), &ct_hdr, sizeof(CT_HDR));
-                       fi->g.rfc_4.s_id = htonl(fi->g.my_id);
-                       for (i = 0; i < 32; i++)
-                               fi->g.rfc_4.bit_map[i] = 0;
-                       /* We support IP & SCSI */
-                       fi->g.rfc_4.bit_map[2] = 0x01;
-                       fi->g.rfc_4.bit_map[3] = 0x20;
-                       size = sizeof(RFC_4);
-                       memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.rfc_4, size);
-                       tx_exchange(fi, (char 
*)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, 
ox_id, req);
-                       break;
-               case FCS_GP_ID4:
-                       memcpy(&(fi->g.gp_id4.ct_hdr), &ct_hdr, sizeof(CT_HDR));
-                       fi->g.gp_id4.port_type = htonl(PORT_TYPE_NX_PORTS);
-                       size = sizeof(GP_ID4);
-                       memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.gp_id4, 
size);
-                       tx_exchange(fi, (char 
*)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, 
ox_id, req);
-                       break;
-       }
-       fi->g.e_i++;
-       if (fi->g.e_i == MAX_PENDING_FRAMES)
-               fi->g.e_i = 0;
-       LEAVE("tx_name_server_req");
-}
-
-static void tx_scr(struct fc_info *fi)
-{
-int int_required = 1, size = sizeof(SCR);
-u_short ox_id = OX_ID_FIRST_SEQUENCE;
-u_int type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
-u_int r_ctl = RCTL_ELS_UCTL;
-u_int my_mtu = fi->g.my_mtu, d_id = FABRIC_CONTROLLER;
-       ENTER("tx_scr");
-       fi->g.scr.cmnd_code = htonl(ELS_SCR);
-       fi->g.scr.reg_function = htonl(FULL_REGISTRATION);
-       fi->g.type_of_frame = FC_ELS;
-       memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.scr, size);
-       tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, 
type, d_id, my_mtu, int_required, ox_id, ELS_SCR);
-       fi->g.e_i++;
-       if (fi->g.e_i == MAX_PENDING_FRAMES)
-               fi->g.e_i = 0;
-       LEAVE("tx_scr");
-}
-
-static void perform_adisc(struct fc_info *fi)
-{
-int count = 0;
-       /* Will be set to TRUE when timer expires in a PLDA environment. 
-        */
-       fi->g.port_discovery = FALSE;
-
-       if (fi->node_info_list) {
-               struct fc_node_info *temp_list = fi->node_info_list;
-               while(temp_list) {
-                       /* Tx ADISC to all non-fabric based 
-                        * entities.
-                        */
-                       if ((temp_list->d_id & 0xFF0000) != 0xFF0000)
-                               tx_adisc(fi, ELS_ADISC, temp_list->d_id, 
OX_ID_FIRST_SEQUENCE);
-                       temp_list = temp_list->next;
-                       udelay(20);
-                       count++;
-               }
-       }
-       /* Perform Port Discovery after timer expires.
-        * We are giving time for the ADISCed nodes to respond
-        * so that we don't have to perform PLOGI to those whose
-        * login are _still_ valid.
-        */
-       fi->explore_timer.function = port_discovery_timer;
-       fi->explore_timer.data = (unsigned long)fi;
-       fi->explore_timer.expires = RUN_AT((count*3*HZ)/100); 
-       init_timer(&fi->explore_timer);
-       add_timer(&fi->explore_timer);
-}
-
-static void explore_fabric(struct fc_info *fi, u_int *buff_addr)
-{
-u_int *addr = buff_addr + 12; /* index into payload */
-u_char control_code;
-u_int d_id;
-int count = 0;
-       ENTER("explore_fabric");
-       DPRINTK1("entering explore_fabric");
-
-       /*fi->g.perform_adisc = TRUE;
-       fi->g.explore_fabric = TRUE;
-       perform_adisc(fi);*/
-       
-       do {
-               d_id = ntohl(*addr) & 0x00FFFFFF;
-               if (d_id != fi->g.my_id) {
-                       if (sid_logged_in(fi, d_id) == NODE_NOT_PRESENT)
-                               tx_logi(fi, ELS_PLOGI, d_id); 
-                       else
-                       if (sid_logged_in(fi, d_id) == NODE_LOGGED_OUT)
-                               tx_adisc(fi, ELS_ADISC, d_id, 
OX_ID_FIRST_SEQUENCE); 
-                       count++;
-               }
-               control_code = (ntohl(*addr) & 0xFF000000) >> 24;
-               addr++;
-               DPRINTK1("cc = %x, d_id = %x", control_code, d_id);
-       } while (control_code != 0x80);
-       
-       fi->explore_timer.function = fabric_explore_timer;
-       fi->explore_timer.data = (unsigned long)fi;
-       /* We give 30 msec for each device to respond and then send out
-        * our SCSI enquiries. 
-        */
-       fi->explore_timer.expires = RUN_AT((count*3*HZ)/100); 
-       init_timer(&fi->explore_timer);
-       add_timer(&fi->explore_timer);
-
-       DPRINTK1("leaving explore_fabric");
-       LEAVE("explore_fabric");
-}
-
-static void fabric_explore_timer(unsigned long data)
-{
-struct fc_info *fi = (struct fc_info*)data;
-       del_timer(&fi->explore_timer);
-
-       if ((fi->g.loop_up == TRUE) && (fi->g.ptp_up == FALSE)) {
-               /* Initiate Local Port Discovery on the Local Loop.
-                */
-               fi->g.port_discovery = TRUE;
-               fi->g.alpa_list_index = 1;
-               local_port_discovery(fi);
-       }
-       fi->g.explore_fabric = FALSE;
-       return;
-}
-
-static void port_discovery_timer(unsigned long data)
-{
-struct fc_info *fi = (struct fc_info*)data;
-       del_timer(&fi->explore_timer);
-       
-       if ((fi->g.loop_up == TRUE) && (fi->g.explore_fabric != TRUE)) {
-               fi->g.port_discovery = TRUE;
-               fi->g.alpa_list_index = 1;
-               local_port_discovery(fi);
-       }
-       fi->g.perform_adisc = FALSE;
-       return;
-}
-
-static void add_to_ox_id_list(struct fc_info *fi, u_int transaction_id, u_int 
cmnd_code)
-{
-struct ox_id_els_map *p, *q = fi->ox_id_list, *r = NULL;
-int size = sizeof(struct ox_id_els_map);
-       while (q != NULL) {
-               r = q;
-               q = q->next;
-       }
-       p = (struct ox_id_els_map *)kmalloc(size, GFP_ATOMIC);
-       if (p == NULL) {
-               T_MSG("kmalloc failed in add_to_ox_id_list()");
-               return;
-       }
-       p->ox_id = transaction_id;
-       p->els = cmnd_code;
-       p->next = NULL;
-       if (fi->ox_id_list == NULL)
-               fi->ox_id_list = p;
-       else
-               r->next = p;
-       return;
-}
-
-static u_int remove_from_ox_id_list(struct fc_info *fi, u_short received_ox_id)
-{
-struct ox_id_els_map *p = fi->ox_id_list, *q = fi->ox_id_list;
-u_int els_type;
-       while (q != NULL) {
-               if (q->ox_id == received_ox_id) {
-
-                       if (q == fi->ox_id_list) 
-                               fi->ox_id_list = fi->ox_id_list->next;
-                       else
-                               if (q->next == NULL) 
-                                       p->next = NULL;
-                       else 
-                                       p->next = q->next;
-
-                       els_type = q->els;
-                       kfree(q);
-                       return els_type;
-               }
-               p = q;
-               q = q->next;
-       }
-       if (q == NULL)
-               DPRINTK2("Could not find ox_id %x in ox_id_els_map", 
received_ox_id);
-       return 0;
-}
-
-static void build_tachyon_header(struct fc_info *fi, u_int my_id, u_int r_ctl, 
u_int d_id, u_int type, u_char seq_id, u_char df_ctl, u_short ox_id, u_short 
rx_id, char *data)
-{
-u_char alpa = d_id & 0x0000FF;
-u_int dest_ddaa = d_id &0xFFFF00;
-
-       ENTER("build_tachyon_header");
-       DPRINTK("d_id = %x, my_ddaa = %x", d_id, fi->g.my_ddaa);
-       /* Does it have to go to/thru a Fabric? */
-       if ((dest_ddaa != 0) && ((d_id == F_PORT) || (fi->g.fabric_present && 
(dest_ddaa != fi->g.my_ddaa))))
-               alpa = 0x00;
-       fi->g.tach_header.resv = 0x00000000;
-       fi->g.tach_header.sof_and_eof = SOFI3 | EOFN;
-       fi->g.tach_header.dest_alpa = alpa;
-       /* Set LCr properly to have enuff credit */
-       if (alpa == REPLICATE)
-               fi->g.tach_header.lcr_and_time_stamp = htons(0xC00);/* LCr=3 */
-       else
-               fi->g.tach_header.lcr_and_time_stamp = 0;
-       fi->g.tach_header.r_ctl_and_d_id = htonl(r_ctl | d_id);
-       fi->g.tach_header.vc_id_and_s_id = htonl(my_id);
-       fi->g.tach_header.type_and_f_cntl = htonl(type);
-       fi->g.tach_header.seq_id = seq_id;
-       fi->g.tach_header.df_cntl = df_ctl;
-       fi->g.tach_header.seq_cnt = 0;
-       fi->g.tach_header.ox_id = htons(ox_id);
-       fi->g.tach_header.rx_id = htons(rx_id);
-       fi->g.tach_header.ro = 0;
-       if (data) {
-               /* We use the Seq_Count to keep track of IP frames in the
-                * OCI_interrupt handler. Initial Seq_Count of IP frames is 1.
-                */
-               if (fi->g.type_of_frame == FC_BROADCAST)
-                       fi->g.tach_header.seq_cnt = htons(0x1);
-               else
-                       fi->g.tach_header.seq_cnt = htons(0x2);
-               fi->g.tach_header.nw_header.d_naa = htons(0x1000);
-               fi->g.tach_header.nw_header.s_naa = htons(0x1000);
-               memcpy(&(fi->g.tach_header.nw_header.dest_high), data, 2);
-               memcpy(&(fi->g.tach_header.nw_header.dest_low), data + 2, 4);
-               memcpy(&(fi->g.tach_header.nw_header.source_high), data + 6, 2);
-               memcpy(&(fi->g.tach_header.nw_header.source_low), data + 8, 4);
-       }
-       LEAVE("build_tachyon_header");
-}
-
-static void build_EDB(struct fc_info *fi, char *data, u_short flags, u_short 
len)
-{
-       fi->g.edb.buf_addr = ntohl((u_int)virt_to_bus(data));
-       fi->g.edb.ehf = ntohs(flags);
-       if (len % 4)
-               len += (4 - (len % 4));
-       fi->g.edb.buf_len = ntohs(len);
-}
-
-static void build_ODB(struct fc_info *fi, u_char seq_id, u_int d_id, u_int 
len, u_int cntl, u_short mtu, u_short ox_id, u_short rx_id, int NW_header, int 
int_required, u_int frame_class)
-{
-       fi->g.odb.seq_d_id = htonl(seq_id << 24 | d_id);
-       fi->g.odb.tot_len = len;
-       if (NW_header)
-               fi->g.odb.tot_len += NW_HEADER_LEN;
-       if (fi->g.odb.tot_len % 4)
-               fi->g.odb.tot_len += (4 - (fi->g.odb.tot_len % 4));
-       fi->g.odb.tot_len = htonl(fi->g.odb.tot_len);
-       switch(int_required) {
-               case NO_COMP_AND_INT:
-                       fi->g.odb.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | 
ODB_NO_INT | ODB_NO_COMP | cntl);
-                       break;
-               case INT_AND_COMP_REQ:
-                       fi->g.odb.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | 
cntl);
-                       break;
-               case NO_INT_COMP_REQ:
-                       fi->g.odb.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | 
ODB_NO_INT | cntl);
-                       break;
-       }
-       fi->g.odb.rx_id = htons(rx_id);
-       fi->g.odb.cs_enable = 0;
-       fi->g.odb.cs_seed = htons(1);
-
-       fi->g.odb.hdr_addr = 
htonl(virt_to_bus(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx]));
-       fi->g.odb.frame_len = htons(mtu);
-
-       if (NW_header) {
-               /* The pointer to the sk_buff is in here. Freed up when the
-                * OCI_interrupt is received.
-                */
-               fi->g.odb.trans_id = htonl(frame_class);
-               fi->g.odb.hdr_len = TACHYON_HEADER_LEN + NW_HEADER_LEN;
-       }
-       else {
-               /* helps in tracking transmitted OX_IDs */
-               fi->g.odb.trans_id = htonl((frame_class & 0xFFFF0000) | ox_id);
-               fi->g.odb.hdr_len = TACHYON_HEADER_LEN;
-       }
-       fi->g.odb.hdr_len = htons(fi->g.odb.hdr_len);
-               
-       fi->g.odb.edb_addr = 
htonl(virt_to_bus(fi->q.ptr_edb[fi->q.edb_buffer_indx]));
-}
-
-static void fill_login_frame(struct fc_info *fi, u_int logi)
-{
-int i;
-       fi->g.login.ls_cmnd_code= htonl(logi);
-       fi->g.login.fc_ph_version = htons(PH_VERSION);
-       if (fi->g.loop_up)
-               fi->g.login.buff_to_buff_credit = htons(LOOP_BB_CREDIT);
-       else
-       if (fi->g.ptp_up)
-               fi->g.login.buff_to_buff_credit = htons(PT2PT_BB_CREDIT);
-       if ((logi != ELS_FLOGI) || (logi == ELS_ACC))
-               fi->g.login.common_features = htons(PLOGI_C_F);
-       else
-       if (logi == ELS_FLOGI)
-               fi->g.login.common_features = htons(FLOGI_C_F);
-       fi->g.login.recv_data_field_size = htons(TACH_FRAME_SIZE);
-       fi->g.login.n_port_total_conc_seq = htons(CONCURRENT_SEQUENCES);
-       fi->g.login.rel_off_by_info_cat = htons(RO_INFO_CATEGORY);
-       fi->g.login.ED_TOV = htonl(E_D_TOV);
-       fi->g.login.n_port_name_high = htonl(N_PORT_NAME_HIGH);
-       fi->g.login.n_port_name_low = htonl(N_PORT_NAME_LOW);
-       fi->g.login.node_name_high = htonl(NODE_NAME_HIGH);
-       fi->g.login.node_name_low = htonl(NODE_NAME_LOW);
-       
-       /* Fill Class 1 parameters */
-       fi->g.login.c_of_s[0].service_options = htons(0);
-       fi->g.login.c_of_s[0].initiator_ctl = htons(0);
-       fi->g.login.c_of_s[0].recipient_ctl = htons(0);
-       fi->g.login.c_of_s[0].recv_data_field_size = htons(0);
-       fi->g.login.c_of_s[0].concurrent_sequences = htons(0);
-       fi->g.login.c_of_s[0].n_port_end_to_end_credit = htons(0);
-       fi->g.login.c_of_s[0].open_seq_per_exchange = htons(0);
-       fi->g.login.c_of_s[0].resv = htons(0);
-
-       /* Fill Class 2 parameters */
-       fi->g.login.c_of_s[1].service_options = htons(0);
-       fi->g.login.c_of_s[1].initiator_ctl = htons(0);
-       fi->g.login.c_of_s[1].recipient_ctl = htons(0);
-       fi->g.login.c_of_s[1].recv_data_field_size = htons(0);
-       fi->g.login.c_of_s[1].concurrent_sequences = htons(0);
-       fi->g.login.c_of_s[1].n_port_end_to_end_credit = htons(0);
-       fi->g.login.c_of_s[1].open_seq_per_exchange = htons(0);
-       fi->g.login.c_of_s[1].resv = htons(0);
-
-       /* Fill Class 3 parameters */
-       if (logi == ELS_FLOGI)
-               fi->g.login.c_of_s[2].service_options  = htons(SERVICE_VALID | 
SEQUENCE_DELIVERY);
-       else
-               fi->g.login.c_of_s[2].service_options  = htons(SERVICE_VALID);
-       fi->g.login.c_of_s[2].initiator_ctl = htons(0);
-       fi->g.login.c_of_s[2].recipient_ctl = htons(0);
-       fi->g.login.c_of_s[2].recv_data_field_size = htons(TACH_FRAME_SIZE);
-       fi->g.login.c_of_s[2].concurrent_sequences = 
htons(CLASS3_CONCURRENT_SEQUENCE);
-       fi->g.login.c_of_s[2].n_port_end_to_end_credit = htons(0);
-       fi->g.login.c_of_s[2].open_seq_per_exchange = 
htons(CLASS3_OPEN_SEQUENCE);
-       fi->g.login.c_of_s[2].resv = htons(0);
-       
-       for(i = 0; i < 4; i++) {
-               fi->g.login.resv[i] = 0;
-               fi->g.login.vendor_version_level[i] = 0;
-       }
-}
-
-
-/* clear the Interrupt Latch on the (i)chip, so that you can receive 
- * Interrupts from Tachyon in future 
- */
-static void reset_latch(struct fc_info *fi)
-{
-       writel(readl(fi->i_r.ptr_ichip_hw_status_reg) | ICHIP_HSR_INT_LATCH, 
fi->i_r.ptr_ichip_hw_status_reg);
-}
-
-static void update_OCQ_indx(struct fc_info *fi)
-{
-       fi->q.ocq_prod_indx++;
-       if (fi->q.ocq_prod_indx == OCQ_LENGTH)
-               fi->q.ocq_prod_indx = 0;
-       writel(fi->q.ocq_prod_indx, fi->t_r.ptr_ocq_prod_indx_reg);
-}
-
-static void update_IMQ_indx(struct fc_info *fi, int count)
-{
-       fi->q.imq_cons_indx += count;
-       if (fi->q.imq_cons_indx >= IMQ_LENGTH)
-               fi->q.imq_cons_indx -= IMQ_LENGTH;
-       writel(fi->q.imq_cons_indx, fi->t_r.ptr_imq_cons_indx_reg);
-}
-
-static void update_SFSBQ_indx(struct fc_info *fi)
-{
-       fi->q.sfsbq_prod_indx++;
-       if (fi->q.sfsbq_prod_indx == SFSBQ_LENGTH)
-               fi->q.sfsbq_prod_indx = 0;
-       writel(fi->q.sfsbq_prod_indx, fi->t_r.ptr_sfsbq_prod_reg);
-}
-
-static void update_MFSBQ_indx(struct fc_info *fi, int count)
-{
-       fi->q.mfsbq_prod_indx += count;
-       if (fi->q.mfsbq_prod_indx >= MFSBQ_LENGTH)
-               fi->q.mfsbq_prod_indx -= MFSBQ_LENGTH;
-       writel(fi->q.mfsbq_prod_indx, fi->t_r.ptr_mfsbq_prod_reg);
-}
-
-
-static void update_tachyon_header_indx(struct fc_info *fi)
-{
-       fi->q.tachyon_header_indx++;
-       if (fi->q.tachyon_header_indx == NO_OF_TACH_HEADERS)
-               fi->q.tachyon_header_indx = 0;
-}
-
-static void update_EDB_indx(struct fc_info *fi)
-{
-       fi->q.edb_buffer_indx++;
-       if (fi->q.edb_buffer_indx == EDB_LEN)
-               fi->q.edb_buffer_indx = 0;
-}
-
-static int iph5526_open(struct net_device *dev)
-{
-       netif_start_queue(dev);
-       return 0;
-}
-
-static int iph5526_close(struct net_device *dev)
-{
-       netif_stop_queue(dev);
-       return 0;
-}
-
-static void iph5526_timeout(struct net_device *dev)
-{
-       struct fc_info *fi = dev->priv;
-       printk(KERN_WARNING "%s: timed out on send.\n", dev->name);
-       fi->fc_stats.tx_dropped++;
-       dev->trans_start = jiffies;
-       netif_wake_queue(dev);
-}
-
-static int iph5526_send_packet(struct sk_buff *skb, struct net_device *dev)
-{
-       struct fc_info *fi = dev->priv;
-       int status = 0;
-       short type = 0;
-       u_long flags;
-       struct fcllc *fcllc;
-       
-       ENTER("iph5526_send_packet");
-       
-       netif_stop_queue(dev);
-       /* Strip off the pseudo header.
-        */
-       skb->data = skb->data + 2*FC_ALEN; 
-       skb->len = skb->len - 2*FC_ALEN;
-       fcllc = (struct fcllc *)skb->data;
-       type = ntohs(fcllc->ethertype);
-
-       spin_lock_irqsave(&fi->fc_lock, flags);
-       switch(type) {
-               case ETH_P_IP:
-                       status = tx_ip_packet(skb, skb->len, fi);
-                       break;
-               case ETH_P_ARP:
-                       status = tx_arp_packet(skb->data, skb->len, fi);
-                       break;
-               default:
-                       T_MSG("WARNING!!! Received Unknown Packet Type... 
Discarding...");
-                       fi->fc_stats.rx_dropped++;
-                       break;
-       }
-       spin_unlock_irqrestore(&fi->fc_lock, flags);
-
-       if (status) {
-               fi->fc_stats.tx_bytes += skb->len;
-               fi->fc_stats.tx_packets++;
-       }
-       else
-               fi->fc_stats.tx_dropped++;
-       dev->trans_start = jiffies;
-       /* We free up the IP buffers in the OCI_interrupt handler.
-        * status == 0 implies that the frame was not transmitted. So the
-        * skb is freed here.
-        */
-       if ((type == ETH_P_ARP) || (status == 0))
-               dev_kfree_skb(skb);
-       netif_wake_queue(dev);
-       LEAVE("iph5526_send_packet");
-       return 0;
-}
-
-static int iph5526_change_mtu(struct net_device *dev, int mtu)
-{
-       return 0;
-}
-
-static int tx_ip_packet(struct sk_buff *skb, unsigned long len, struct fc_info 
*fi)
-{
-u_int d_id;
-int int_required = 1;
-u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_DATA;
-u_int type = TYPE_LLC_SNAP;
-u_short ox_id = OX_ID_FIRST_SEQUENCE;
-u_int mtu;
-struct fc_node_info *q;
-
-       ENTER("tx_ip_packet");
-       q = look_up_cache(fi, skb->data - 2*FC_ALEN);
-       if (q != NULL) {
-               d_id = q->d_id;
-               DPRINTK("Look-Up Cache Succeeded for d_id = %x", d_id);
-               mtu = q->mtu;
-               if (q->login == LOGIN_COMPLETED){
-                       fi->g.type_of_frame = FC_IP;
-                       return tx_exchange(fi, skb->data, len, r_ctl, type, 
d_id, mtu, int_required, ox_id, virt_to_bus(skb));
-               }
-               
-               if (q->d_id == BROADCAST) {
-               struct fc_node_info *p = fi->node_info_list;
-               int return_value = FALSE;
-                       fi->g.type_of_frame = FC_BROADCAST;
-                       /* Do unicast to local nodes.
-                        */
-                       int_required = 0;
-                       while(p != NULL) {
-                               d_id = p->d_id;
-                               if ((d_id & 0xFFFF00) == fi->g.my_ddaa)
-                                       return_value |= tx_exchange(fi, 
skb->data, len, r_ctl, type, d_id, fi->g.my_mtu, int_required, ox_id, 
TYPE_LLC_SNAP);
-                               p = p->next;
-                       }
-                       kfree(q);
-                       return return_value;
-               }
-               
-               if (q->login != LOGIN_COMPLETED) {      
-                       DPRINTK1("Node not logged in... Txing PLOGI to %x", 
d_id);
-                       /* FIXME: we are dumping the frame here */
-                       tx_logi(fi, ELS_PLOGI, d_id); 
-               }
-       }
-       DPRINTK2("Look-Up Cache Failed");
-       LEAVE("tx_ip_packet");
-       return 0;
-}
-
-static int tx_arp_packet(char *data, unsigned long len, struct fc_info *fi)
-{
-u_int opcode = data[ARP_OPCODE_0]; 
-u_int d_id;
-int int_required = 0, return_value = FALSE;
-u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_DATA;
-u_int type = TYPE_LLC_SNAP;
-u_short ox_id = OX_ID_FIRST_SEQUENCE;
-u_int my_mtu = fi->g.my_mtu;
-       ENTER("tx_arp_packet");
-
-       opcode = opcode << 8 | data[ARP_OPCODE_1];
-       fi->g.type_of_frame = FC_IP;
-
-       if (opcode == ARPOP_REQUEST) {
-       struct fc_node_info *q = fi->node_info_list;
-               d_id = BROADCAST;
-               return_value |= tx_exchange(fi, data, len, r_ctl, type, d_id, 
my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
-               /* Some devices support HW_TYPE 0x01 */
-               memcpy(fi->g.arp_buffer, data - 2*FC_ALEN, len + 2*FC_ALEN);
-               fi->g.arp_buffer[9 + 2*FC_ALEN] = 0x01;
-               return_value |= tx_exchange(fi, (char *)(fi->g.arp_buffer + 
2*FC_ALEN), len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
-
-               /* Do unicast to local nodes.
-                */
-               while(q != NULL) {
-                       fi->g.type_of_frame = FC_BROADCAST;
-                       d_id = q->d_id;
-                       if ((d_id & 0xFFFF00) == fi->g.my_ddaa) {
-                               return_value |= tx_exchange(fi, data, len, 
r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
-                               // Some devices support HW_TYPE 0x01
-                               memcpy(fi->g.arp_buffer, data - 2*FC_ALEN, len 
+ 2*FC_ALEN);
-                               fi->g.arp_buffer[9 + 2*FC_ALEN] = 0x01;
-                               return_value |= tx_exchange(fi, (char 
*)(fi->g.arp_buffer + 2*FC_ALEN), len, r_ctl, type, d_id, my_mtu, int_required, 
ox_id, TYPE_LLC_SNAP);
-                       }
-                       q = q->next;
-               }
-               return return_value;
-       }
-       else
-       if (opcode == ARPOP_REPLY) {
-       struct fc_node_info *q; u_int mtu;
-               DPRINTK("We are sending out an ARP reply");
-               q = look_up_cache(fi, data - 2*FC_ALEN);
-               if (q != NULL) {
-                       d_id = q->d_id;
-                       DPRINTK("Look-Up Cache Succeeded for d_id = %x", d_id);
-                       mtu = q->mtu;
-                       if (q->login == LOGIN_COMPLETED){
-                               tx_exchange(fi, data, len, r_ctl, type, d_id, 
mtu, int_required, ox_id, TYPE_LLC_SNAP);
-                               /* Some devices support HW_TYPE 0x01 */
-                               memcpy(fi->g.arp_buffer, data - 2*FC_ALEN, len 
+ 2*FC_ALEN);
-                               fi->g.arp_buffer[9 + 2*FC_ALEN] = 0x01;
-                               return tx_exchange(fi, (char 
*)(fi->g.arp_buffer + 2*FC_ALEN), len, r_ctl, type, d_id, my_mtu, int_required, 
ox_id, TYPE_LLC_SNAP);
-                       }
-                       else {
-                               DPRINTK1("Node not logged in... Txing PLOGI to 
%x", d_id);
-                               tx_logi(fi, ELS_PLOGI, d_id); /* FIXME: we are 
dumping the frame here */
-                       }
-               }
-               DPRINTK2("Look-Up Cache Failed");
-       }
-       else {
-               T_MSG("Warning!!! Invalid Opcode in ARP Packet!");
-       }
-       LEAVE("tx_arp_packet");
-       return 0;
-}
-
-
-static void rx_net_packet(struct fc_info *fi, u_char *buff_addr, int 
payload_size)
-{
-struct net_device *dev = fi->dev;
-struct sk_buff *skb;
-u_int skb_size = 0;
-struct fch_hdr fch;
-       ENTER("rx_net_packet");
-       skb_size = payload_size - TACHYON_HEADER_LEN;
-       DPRINTK("skb_size = %d", skb_size);
-       fi->fc_stats.rx_bytes += skb_size - 2;
-       skb = dev_alloc_skb(skb_size);
-       if (skb == NULL) {
-               printk(KERN_NOTICE "%s: In rx_net_packet() Memory squeeze, 
dropping packet.\n", dev->name);
-               fi->fc_stats.rx_dropped++;
-               return;
-       }
-       /* Skip over the Tachyon Frame Header.
-        */
-       buff_addr += TACHYON_HEADER_LEN; 
-
-       memcpy(fch.daddr, buff_addr + 2, FC_ALEN);
-       memcpy(fch.saddr, buff_addr + 10, FC_ALEN);
-       buff_addr += 2;
-       memcpy(buff_addr, fch.daddr, FC_ALEN);
-       memcpy(buff_addr + 6, fch.saddr, FC_ALEN);
-       skb_reserve(skb, 2);
-       memcpy(skb_put(skb, skb_size - 2), buff_addr, skb_size - 2);
-       skb->dev = dev;
-       skb->protocol = fc_type_trans(skb, dev);
-       DPRINTK("protocol = %x", skb->protocol);
-       
-       /* Hmmm... to accept HW Type 0x01 as well... 
-        */
-       if (skb->protocol == ntohs(ETH_P_ARP))
-               skb->data[1] = 0x06;
-       netif_rx(skb);
-       dev->last_rx = jiffies;
-       fi->fc_stats.rx_packets++;
-       LEAVE("rx_net_packet");
-}
-
-
-static void rx_net_mfs_packet(struct fc_info *fi, struct sk_buff *skb)
-{
-struct net_device *dev = fi->dev;
-struct fch_hdr fch;
-       ENTER("rx_net_mfs_packet");
-       /* Construct your Hard Header */
-       memcpy(fch.daddr, skb->data + 2, FC_ALEN);
-       memcpy(fch.saddr, skb->data + 10, FC_ALEN);
-       skb_pull(skb, 2);
-       memcpy(skb->data, fch.daddr, FC_ALEN);
-       memcpy(skb->data + 6, fch.saddr, FC_ALEN);
-       skb->dev = dev;
-       skb->protocol = fc_type_trans(skb, dev);
-       DPRINTK("protocol = %x", skb->protocol);
-       netif_rx(skb);
-       dev->last_rx = jiffies;
-       LEAVE("rx_net_mfs_packet");
-}
-
-static int tx_exchange(struct fc_info *fi, char *data, u_int len, u_int r_ctl, 
u_int type, u_int d_id, u_int mtu, int int_required, u_short tx_ox_id, u_int 
frame_class)
-{
-u_char df_ctl; 
-int NW_flag = 0, h_size, return_value;
-u_short rx_id = RX_ID_FIRST_SEQUENCE;
-u_int tachyon_status;
-u_int my_id = fi->g.my_id;
-       ENTER("tx_exchange");
-
-       tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
-       DPRINTK("Tachyon Status = %x len = %d MTU = %d", tachyon_status, len, 
mtu);
-       if (tachyon_status & OSM_FROZEN) {
-               reset_tachyon(fi, ERROR_RELEASE);
-               reset_tachyon(fi, OCQ_RESET);
-               DPRINTK("Tachyon Status = %x len = %d MTU = %d", 
tachyon_status, len, mtu);
-       }
-       if (tx_ox_id == OX_ID_FIRST_SEQUENCE) {
-               switch(fi->g.type_of_frame) {
-                       case FC_SCSI_READ:
-                               tx_ox_id = fi->g.scsi_oxid | SCSI_READ_BIT;
-                               break;
-                       case FC_SCSI_WRITE:
-                               tx_ox_id = fi->g.scsi_oxid;
-                               break;
-                       default:
-                               tx_ox_id = fi->g.ox_id;
-                               break;
-               }
-       }
-       else {
-               switch(fi->g.type_of_frame) {
-                       case FC_SCSI_READ:
-                               rx_id = fi->g.scsi_oxid | SCSI_READ_BIT;
-                               break;
-                       case FC_SCSI_WRITE:
-                               rx_id = fi->g.scsi_oxid;
-                               break;
-                       case FC_BLS:
-                               rx_id = RX_ID_FIRST_SEQUENCE;
-                               break;
-                       default:
-                               rx_id = fi->g.ox_id;
-                               break;
-               }
-       }
-
-       if (type == TYPE_LLC_SNAP) {
-               df_ctl = 0x20;
-               NW_flag = 1;
-               /* Multi Frame Sequence ? If yes, set RO bit */
-               if (len > mtu)
-                       type |= RELATIVE_OFF_PRESENT;
-               build_tachyon_header(fi, my_id, r_ctl, d_id, type, 
fi->g.seq_id, df_ctl, tx_ox_id, rx_id, data - 2*FC_ALEN);
-       }
-       else {
-               df_ctl = 0;
-               /* Multi Frame Sequence ? If yes, set RO bit */
-               if (len > mtu)
-                       type |= RELATIVE_OFF_PRESENT;
-               build_tachyon_header(fi, my_id, r_ctl, d_id, type, 
fi->g.seq_id, df_ctl, tx_ox_id, rx_id, NULL);
-       }
-
-       /* Get free Tachyon Headers and EDBs */
-       if (get_free_header(fi) || get_free_EDB(fi))
-               return 0;
-
-       if ((type & 0xFF000000) == TYPE_LLC_SNAP) {
-               h_size =  TACHYON_HEADER_LEN + NW_HEADER_LEN;
-               memcpy(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx], 
&(fi->g.tach_header), h_size);
-       }
-       else 
-               memcpy(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx], 
&(fi->g.tach_header), TACHYON_HEADER_LEN);
-
-       return_value = tx_sequence(fi, data, len, mtu, d_id, tx_ox_id, rx_id, 
fi->g.seq_id, NW_flag, int_required, frame_class);
-       
-       switch(fi->g.type_of_frame) {
-               case FC_SCSI_READ:
-               case FC_SCSI_WRITE:
-                       update_scsi_oxid(fi);
-                       break;
-               case FC_BLS:
-                       break;
-               default:
-                       fi->g.ox_id++;
-                       if (fi->g.ox_id == 0xFFFF)
-                               fi->g.ox_id = NOT_SCSI_XID;
-                       break;
-       }
-
-       if (fi->g.seq_id == MAX_SEQ_ID)
-               fi->g.seq_id = 0;
-       else
-               fi->g.seq_id++;
-       LEAVE("tx_exchange");
-       return return_value;
-}
-
-static int tx_sequence(struct fc_info *fi, char *data, u_int len, u_int mtu, 
u_int d_id, u_short ox_id, u_short rx_id, u_char seq_id, int NW_flag, int 
int_required, u_int frame_class)
-{
-u_int cntl = 0;
-int return_value;
-       ENTER("tx_sequence");
-       build_EDB(fi, data, EDB_END, len);
-       memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB));
-       build_ODB(fi, seq_id, d_id, len, cntl, mtu, ox_id, rx_id, NW_flag, 
int_required, frame_class);
-       memcpy(fi->q.ptr_odb[fi->q.ocq_prod_indx], &(fi->g.odb), sizeof(ODB));
-       if (fi->g.link_up != TRUE) {
-               DPRINTK2("Fibre Channel Link not up. Dropping Exchange!");
-               return_value = FALSE;
-       }
-       else {
-               /* To be on the safe side, a check should be included
-                * at this point to check if we are overrunning 
-                * Tachyon.
-                */
-               update_OCQ_indx(fi);
-               return_value = TRUE;
-       }
-       update_EDB_indx(fi);
-       update_tachyon_header_indx(fi);
-       LEAVE("tx_sequence");
-       return return_value;
-}
-
-static int get_free_header(struct fc_info *fi)
-{
-u_short temp_ox_id;
-u_int *tach_header, initial_indx = fi->q.tachyon_header_indx;
-       /* Check if the header is in use.
-        * We could have an outstanding command.
-        * We should find a free slot as we can queue a
-        * maximum of 32 SCSI commands only. 
-        */
-       tach_header = fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx];
-       temp_ox_id = ntohl(*(tach_header + 6)) >> 16;
-       /* We care about the SCSI writes only. Those are the wicked ones
-        * that need an additional set of buffers.
-        */
-       while(temp_ox_id <= MAX_SCSI_XID) {
-               update_tachyon_header_indx(fi);
-               if (fi->q.tachyon_header_indx == initial_indx) {
-                       /* Should never happen.
-                        */
-                       T_MSG("No free Tachyon headers available");
-                       reset_tachyon(fi, SOFTWARE_RESET);
-                       return 1;
-               }
-               tach_header = 
fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx];
-               temp_ox_id = ntohl(*(tach_header + 6)) >> 16;
-       }
-       return 0;
-}
-
-static int get_free_EDB(struct fc_info *fi)
-{
-unsigned int initial_indx = fi->q.edb_buffer_indx;
-       /* Check if the EDB is in use.
-        * We could have an outstanding SCSI Write command.
-        * We should find a free slot as we can queue a
-        * maximum of 32 SCSI commands only. 
-        */
-       while (fi->q.free_edb_list[fi->q.edb_buffer_indx] != EDB_FREE) {
-               update_EDB_indx(fi);
-               if (fi->q.edb_buffer_indx == initial_indx) {
-                       T_MSG("No free EDB buffers avaliable")
-                       reset_tachyon(fi, SOFTWARE_RESET);
-                       return 1;
-               }
-       }
-       return 0;
-}              
-
-static int validate_login(struct fc_info *fi, u_int *base_ptr)
-{
-struct fc_node_info *q = fi->node_info_list;
-char n_port_name[PORT_NAME_LEN];
-char node_name[NODE_NAME_LEN];
-u_int s_id;
-       ENTER("validate_login");
-       /*index to Port Name in the payload. We need the 8 byte Port Name */
-       memcpy(n_port_name, base_ptr + 10, PORT_NAME_LEN);
-       memcpy(node_name, base_ptr + 12, NODE_NAME_LEN);
-       s_id = ntohl(*(base_ptr + 3)) & 0x00FFFFFF;
-       
-       /* check if Fibre Channel IDs have changed */
-       while(q != NULL) {      
-               if (memcmp(n_port_name, q->hw_addr, PORT_NAME_LEN) == 0) {
-                       if ((s_id != q->d_id) || (memcmp(node_name, 
q->node_name, NODE_NAME_LEN) != 0)) {
-                               DPRINTK1("Fibre Channel ID of Node has changed. 
Txing LOGO.");
-                               return 0;
-                       }
-                       q->login = LOGIN_COMPLETED;
-#if DEBUG_5526_2
-                       display_cache(fi);
-#endif
-                       return 1;
-               }
-               q = q->next;
-       }
-       DPRINTK1("Port Name does not match. Txing LOGO.");
-       LEAVE("validate_login");
-       return 0;
-}
-
-static void add_to_address_cache(struct fc_info *fi, u_int *base_ptr)
-{
-int size = sizeof(struct fc_node_info);
-struct fc_node_info *p, *q = fi->node_info_list, *r = NULL;
-char n_port_name[PORT_NAME_LEN];
-u_int s_id;
-       ENTER("add_to_address_cache");
-       /*index to Port Name in the payload. We need the 8 byte Port Name */
-       memcpy(n_port_name, base_ptr + 13, PORT_NAME_LEN);
-       s_id = ntohl(*(base_ptr + 3)) & 0x00FFFFFF;
-       
-       /* check if info already exists */
-       while(q != NULL) {      
-               if (memcmp(n_port_name, q->hw_addr, PORT_NAME_LEN) == 0) {
-                       if (s_id != q->d_id) {
-                               memcpy(&(q->c_of_s[0]), base_ptr + 17, 3 * 
sizeof(CLASS_OF_SERVICE));
-                               q->mtu = ntohl(*(base_ptr + 10)) & 0x00000FFF;
-                               q->d_id = s_id;
-                               memcpy(q->node_name, base_ptr + 15, 
NODE_NAME_LEN);
-                       }
-                       q->login = LOGIN_COMPLETED;
-                       q->scsi = FALSE;
-                       fi->num_nodes++;
-#if DEBUG_5526_2
-                       display_cache(fi);
-#endif
-                       return;
-               }
-               r = q;
-               q = q->next;
-       }
-       p = (struct fc_node_info *)kmalloc(size, GFP_ATOMIC);
-       if (p == NULL) {
-               T_MSG("kmalloc failed in add_to_address_cache()");
-               return;
-       }
-       memcpy(&(p->c_of_s[0]), base_ptr + 17, 3 * sizeof(CLASS_OF_SERVICE));
-       p->mtu = ntohl(*(base_ptr + 10)) & 0x00000FFF;
-       p->d_id = s_id;
-       memcpy(p->hw_addr, base_ptr + 13, PORT_NAME_LEN);
-       memcpy(p->node_name, base_ptr + 15, NODE_NAME_LEN);
-       p->login = LOGIN_COMPLETED;
-       p->scsi = FALSE;
-       p->target_id = 0xFF;
-       p->next = NULL;
-       if (fi->node_info_list == NULL)
-               fi->node_info_list = p;
-       else
-               r->next = p;
-       fi->num_nodes++;
-#if DEBUG_5526_2
-       display_cache(fi);
-#endif
-       LEAVE("add_to_address_cache");
-       return;
-}
-
-static void remove_from_address_cache(struct fc_info *fi, u_int *base_ptr, 
u_int cmnd_code)
-{
-struct fc_node_info *q = fi->node_info_list;
-u_int s_id;
-       ENTER("remove_from_address_cache");
-       s_id = ntohl(*(base_ptr + 3)) & 0x00FFFFFF;
-       switch(cmnd_code) {
-               case ELS_LOGO:
-                       /* check if info exists */
-                       while (q != NULL) {
-                               if (s_id == q->d_id) {
-                                       if (q->login == LOGIN_COMPLETED)
-                                               q->login = LOGIN_ATTEMPTED;
-                                       if (fi->num_nodes > 0)
-                                               fi->num_nodes--;
-#if DEBUG_5526_2
-                                       display_cache(fi);
-#endif
-                                       return;
-                               }
-                               q = q->next;
-                       }
-                       DPRINTK1("ELS_LOGO received from node 0x%x which is not 
logged-in", s_id);
-                       break;
-               case ELS_RSCN:
-               {
-               int payload_len = ntohl(*(base_ptr + 8)) & 0xFF;
-               int no_of_pages, i;
-               u_char address_format;
-               u_short received_ox_id = ntohl(*(base_ptr + 6)) >> 16;
-               u_int node_id, mask, *page_ptr = base_ptr + 9;
-                       if ((payload_len < 4) || (payload_len > 256)) {
-                               DPRINTK1("RSCN with invalid payload length 
received");
-                               tx_ls_rjt(fi, s_id, received_ox_id, 
LOGICAL_ERR, RECV_FIELD_SIZE);
-                               return;
-                       }
-                       /* Page_size includes the Command Code */
-                       no_of_pages = (payload_len / 4) - 1;
-                       for (i = 0; i < no_of_pages; i++) {
-                               address_format = ntohl(*page_ptr) >> 24; 
-                               node_id = ntohl(*page_ptr) & 0x00FFFFFF;
-                               switch(address_format) {
-                                       case PORT_ADDRESS_FORMAT:
-                                               rscn_handler(fi, node_id);
-                                               break;
-                                       case AREA_ADDRESS_FORMAT:
-                                       case DOMAIN_ADDRESS_FORMAT:
-                                               if (address_format == 
AREA_ADDRESS_FORMAT)
-                                                       mask = 0xFFFF00;
-                                               else
-                                                       mask = 0xFF0000;
-                                               while(q != NULL) {
-                                                       if ((q->d_id & mask) == 
(node_id & mask)) 
-                                                               
rscn_handler(fi, q->d_id);
-                                                       q = q->next;
-                                               }
-                                               /* There might be some new 
nodes to be 
-                                                * discovered. But, some of the 
earlier 
-                                                * requests as a result of the 
RSCN might be 
-                                                * in progress. We don't want 
to duplicate that 
-                                                * effort. So letz call SCR 
after a lag.
-                                                */
-                                               fi->explore_timer.function = 
scr_timer;
-                                               fi->explore_timer.data = 
(unsigned long)fi;
-                                               fi->explore_timer.expires = 
RUN_AT((no_of_pages*3*HZ)/100); 
-                                               init_timer(&fi->explore_timer);
-                                               add_timer(&fi->explore_timer);
-                                               break;
-                                       default:
-                                               T_MSG("RSCN with invalid 
address format received");
-                                               tx_ls_rjt(fi, s_id, 
received_ox_id, LOGICAL_ERR, NO_EXPLN);
-                               }
-                               page_ptr += 1;
-                       } /* end of for loop */
-               } /* end of case RSCN: */       
-               break;
-       }
-#if DEBUG_5526_2
-       display_cache(fi);
-#endif
-       LEAVE("remove_from_address_cache");
-}
-
-static void rscn_handler(struct fc_info *fi, u_int node_id)
-{
-struct fc_node_info *q = fi->node_info_list;
-int login_state = sid_logged_in(fi, node_id);
-       if ((login_state == NODE_LOGGED_IN) || (login_state == 
NODE_PROCESS_LOGGED_IN)) {
-               while(q != NULL) {
-                       if (q->d_id == node_id) {
-                               q->login = LOGIN_ATTEMPTED;
-                               if (fi->num_nodes > 0)
-                                       fi->num_nodes--;
-                               break;
-                       }
-                       else
-                               q = q->next;
-               }
-       }
-       else
-       if (login_state == NODE_LOGGED_OUT)
-               tx_adisc(fi, ELS_ADISC, node_id, OX_ID_FIRST_SEQUENCE); 
-       else
-       if (login_state == NODE_LOGGED_OUT)
-               tx_logi(fi, ELS_PLOGI, node_id);
-}
-
-static void scr_timer(unsigned long data)
-{
-struct fc_info *fi = (struct fc_info *)data;
-       del_timer(&fi->explore_timer);
-       tx_name_server_req(fi, FCS_GP_ID4);
-}
-
-static int sid_logged_in(struct fc_info *fi, u_int s_id)
-{
-struct fc_node_info *temp = fi->node_info_list;
-       while(temp != NULL)
-               if ((temp->d_id == s_id) && (temp->login == LOGIN_COMPLETED)) {
-                       if (temp->scsi != FALSE)
-                               return NODE_PROCESS_LOGGED_IN;
-                       else
-                               return NODE_LOGGED_IN;
-               }
-               else
-               if ((temp->d_id == s_id) && (temp->login != LOGIN_COMPLETED))
-                       return NODE_LOGGED_OUT;
-               else
-                       temp = temp->next;
-       return NODE_NOT_PRESENT;
-}
-
-static void mark_scsi_sid(struct fc_info *fi, u_int *buff_addr, u_char action)
-{
-struct fc_node_info *temp = fi->node_info_list;
-u_int s_id;
-u_int service_params;
-       s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
-       service_params = ntohl(*(buff_addr + 12)) & 0x000000F0;
-       while(temp != NULL)
-               if ((temp->d_id == s_id) && (temp->login == LOGIN_COMPLETED)) {
-                       if (action == DELETE_ENTRY) {
-                               temp->scsi = FALSE;
-#if DEBUG_5526_2
-                               display_cache(fi);
-#endif
-                               return;
-                       }
-                       /* Check if it is a SCSI Target */
-                       if (!(service_params & TARGET_FUNC)) {
-                               temp->scsi = INITIATOR; 
-#if DEBUG_5526_2
-                               display_cache(fi);
-#endif
-                               return;
-                       }
-                       temp->scsi = TARGET;
-                       /* This helps to maintain the target_id no matter what 
your
-                        *  Fibre Channel ID is.
-                        */
-                       if (temp->target_id == 0xFF) {
-                               if (fi->g.no_of_targets <= MAX_SCSI_TARGETS)
-                                       temp->target_id = fi->g.no_of_targets++;
-                               else
-                                       T_MSG("MAX TARGETS reached!");
-                       }
-                       else
-                               DPRINTK1("Target_id %d already present", 
temp->target_id);
-#if DEBUG_5526_2
-                       display_cache(fi);
-#endif
-                       return;
-               }
-               else
-                       temp = temp->next;
-       return;
-}
-
-static int node_logged_in_prev(struct fc_info *fi, u_int *buff_addr)
-{
-struct fc_node_info *temp;
-u_char *data = (u_char *)buff_addr;
-u_int s_id;
-char node_name[NODE_NAME_LEN];
-       s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
-       memcpy(node_name, buff_addr + 12, NODE_NAME_LEN);
-       /* point to port_name in the ADISC payload */
-       data += 10 * 4;
-       /* point to last 6 bytes of port_name */
-       data += 2;
-       temp = look_up_cache(fi, data);
-       if (temp != NULL) {
-               if ((temp->d_id == s_id) && (memcmp(node_name, temp->node_name, 
NODE_NAME_LEN) == 0)) {
-                       temp->login = LOGIN_COMPLETED;
-#if DEBUG_5526_2
-                       display_cache(fi);
-#endif
-                       return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-static struct fc_node_info *look_up_cache(struct fc_info *fi, char *data)
-{
-struct fc_node_info *temp_list = fi->node_info_list, *q;
-u_char n_port_name[FC_ALEN], temp_addr[FC_ALEN];
-       ENTER("look_up_cache");
-       memcpy(n_port_name, data, FC_ALEN);
-       while(temp_list) {
-               if (memcmp(n_port_name, &(temp_list->hw_addr[2]), FC_ALEN) == 0)
-                       return temp_list;
-               else
-                       temp_list = temp_list->next;
-       }
-       
-       /* Broadcast IP ?
-        */
-       temp_addr[0] = temp_addr[1] = temp_addr[2] = 0xFF;
-       temp_addr[3] = temp_addr[4] = temp_addr[5] = 0xFF;
-       if (memcmp(n_port_name, temp_addr, FC_ALEN) == 0) {
-               q = (struct fc_node_info *)kmalloc(sizeof(struct fc_node_info), 
GFP_ATOMIC);
-               if (q == NULL) {
-                       T_MSG("kmalloc failed in look_up_cache()");
-                       return NULL;
-               }
-               q->d_id = BROADCAST;
-               return q;
-       }
-       LEAVE("look_up_cache");
-       return NULL;
-}
-
-static int display_cache(struct fc_info *fi)
-{
-struct fc_node_info *q = fi->node_info_list;
-#if DEBUG_5526_2
-struct ox_id_els_map *temp_ox_id_list = fi->ox_id_list;
-#endif
-int count = 0, j;
-       printk("\nFibre Channel Node Information for %s\n", fi->name);
-       printk("My FC_ID = %x, My WWN = %x %x, ", fi->g.my_id, 
fi->g.my_node_name_high, fi->g.my_node_name_low);
-       if (fi->g.ptp_up == TRUE)
-               printk("Port_Type = N_Port\n");
-       if (fi->g.loop_up == TRUE)
-               printk("Port_Type = L_Port\n");
-       while(q != NULL) {
-               printk("WWN = ");
-               for (j = 0; j < PORT_NAME_LEN; j++)
-                       printk("%x ", q->hw_addr[j]); 
-               printk("FC_ID = %x, ", q->d_id);
-               printk("Login = ");
-               if (q->login == LOGIN_COMPLETED)
-                       printk("ON ");
-               else
-                       printk("OFF ");
-               if (q->scsi == TARGET)
-                       printk("Target_ID = %d ", q->target_id);
-               printk("\n");
-               q = q->next;
-               count++;
-       }
-
-#if DEBUG_5526_2
-       printk("OX_ID -> ELS Map\n");
-       while(temp_ox_id_list) {
-                       printk("ox_id = %x, ELS = %x\n", 
temp_ox_id_list->ox_id, temp_ox_id_list->els);
-                       temp_ox_id_list = temp_ox_id_list->next;
-       }
-#endif
-
-       return 0;
-}
-
-static struct net_device_stats * iph5526_get_stats(struct net_device *dev)
-{      
-struct fc_info *fi = dev->priv;
-       return (struct net_device_stats *) &fi->fc_stats;
-}
-
-
-/* SCSI stuff starts here */
-
-int iph5526_detect(Scsi_Host_Template *tmpt)
-{
-       struct Scsi_Host *host = NULL;
-       struct iph5526_hostdata *hostdata;
-       struct fc_info *fi = NULL;
-       int no_of_hosts = 0, i, j, count = 0;
-       u_int pci_maddr = 0;
-       struct pci_dev *pdev = NULL;
-       unsigned long timeout;
-
-       tmpt->proc_name = "iph5526";
-
-       for (i = 0; i <= MAX_FC_CARDS; i++) 
-               fc[i] = NULL;
-
-       for (i = 0; clone_list[i].vendor_id != 0; i++)
-       while ((pdev = pci_find_device(clone_list[i].vendor_id, 
clone_list[i].device_id, pdev))) {
-               unsigned short pci_command;
-               if (pci_enable_device(pdev))
-                       continue;
-               if (count < MAX_FC_CARDS) {
-                       fc[count] = kmalloc(sizeof(struct fc_info), GFP_ATOMIC);
-                       if (fc[count] == NULL) {
-                               printk("iph5526.c: Unable to register card # 
%d\n", count + 1);
-                               return no_of_hosts;
-                       }
-                       memset(fc[count], 0, sizeof(struct fc_info));
-               }
-               else {
-                       printk("iph5526.c: Maximum Number of cards reached.\n");
-                       return no_of_hosts;
-               }
-                       
-               fi = fc[count];
-               sprintf(fi->name, "fc%d", count);
-
-               host = scsi_register(tmpt, sizeof(struct iph5526_hostdata));
-               if(host==NULL) {
-                       kfree(fc[count]);
-                       return no_of_hosts;
-               }
-                       
-               hostdata = (struct iph5526_hostdata *)host->hostdata;
-               memset(hostdata, 0 , sizeof(struct iph5526_hostdata));
-               for (j = 0; j < MAX_SCSI_TARGETS; j++)
-                       hostdata->tag_ages[j] = jiffies;
-               hostdata->fi = fi;
-               fi->host = host;
-               //host->max_id = MAX_SCSI_TARGETS;
-               host->max_id = 5;
-               host->this_id = tmpt->this_id;
-
-               pci_maddr = pci_resource_start(pdev, 0);
-               if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
-                       printk("iph5526.c : Cannot find proper PCI device base 
address.\n");
-                       scsi_unregister(host);
-                       kfree(fc[count]);
-                       fc[count] = NULL;
-                       continue;
-               }
-               
-               DPRINTK("pci_maddr = %x", pci_maddr);
-               pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-                       
-               pci_irq_line = pdev->irq;
-               printk("iph5526.c: PCI BIOS reports %s at i/o %#x, irq %d.\n", 
clone_list[i].name, pci_maddr, pci_irq_line);
-               fi->g.mem_base = ioremap(pci_maddr & PAGE_MASK, 1024);
-               
-               /* We use Memory Mapped IO. The initial space contains the
-                * PCI Configuration registers followed by the (i) chip
-                * registers followed by the Tachyon registers.
-                */
-               /* Thatz where (i)chip maps Tachyon Address Space.
-                */
-               fi->g.tachyon_base = (u_long)fi->g.mem_base + TACHYON_OFFSET + 
( pci_maddr & ~PAGE_MASK );
-               DPRINTK("fi->g.tachyon_base = %x", (u_int)fi->g.tachyon_base);
-               if (fi->g.mem_base == NULL) {
-                       printk("iph5526.c : ioremap failed!!!\n");
-                       scsi_unregister(host);
-                       kfree(fc[count]);
-                       fc[count] = NULL;
-                       continue;
-               }       
-               DPRINTK("IRQ1 = %d\n", pci_irq_line);
-               printk(version);
-               fi->base_addr = (long) pdev;
-
-               if (pci_irq_line) {
-               int irqval = 0;
-                       /* Found it, get IRQ.
-                        */
-                       irqval = request_irq(pci_irq_line, &tachyon_interrupt, 
pci_irq_line ? SA_SHIRQ : 0, fi->name, host);
-                       if (irqval) {
-                               printk("iph5526.c : Unable to get IRQ %d 
(irqval = %d).\n", pci_irq_line, irqval);
-                               scsi_unregister(host);
-                               kfree(fc[count]);
-                               fc[count] = NULL;
-                               continue;
-                       }
-                       host->irq = fi->irq = pci_irq_line;
-                       pci_irq_line = 0;
-                       fi->clone_id = clone_list[i].vendor_id;
-               }
-
-               if (!initialize_register_pointers(fi) || !tachyon_init(fi)) {
-                       printk("iph5526.c: TACHYON initialization failed for 
card # %d!!!\n", count + 1);
-                       free_irq(host->irq, host);
-                       scsi_unregister(host);
-                       if (fi) 
-                               clean_up_memory(fi);
-                       kfree(fc[count]);
-                       fc[count] = NULL;
-                       break;
-               }
-               DPRINTK1("Fibre Channel card initialized");
-               /* Wait for the Link to come up and the login process 
-                * to complete. 
-                */
-               for(timeout = jiffies + 10*HZ; time_before(jiffies, timeout) && 
((fi->g.link_up == FALSE) || (fi->g.port_discovery == TRUE) || 
(fi->g.explore_fabric == TRUE) || (fi->g.perform_adisc == TRUE));)
-               {
-                       cpu_relax();
-                       barrier();
-               }
-               
-               count++;
-               no_of_hosts++;
-       }
-       DPRINTK1("no_of_hosts = %d",no_of_hosts);
-       
-       /* This is to make sure that the ACC to the PRLI comes in 
-        * for the last ALPA. 
-        */
-       mdelay(1000); /* Ugly! Let the Gods forgive me */
-
-       DPRINTK1("leaving iph5526_detect\n");
-       return no_of_hosts;
-}
-
-
-int iph5526_biosparam(struct scsi_device *sdev, struct block_device *n,
-               sector_t capacity, int ip[])
-{
-int size = capacity;
-       ip[0] = 64;
-       ip[1] = 32;
-       ip[2] = size >> 11;
-       if (ip[2] > 1024) {
-               ip[0] = 255;
-               ip[1] = 63;
-               ip[2] = size / (ip[0] * ip[1]);
-       }
-       return 0;
-}
-
-int iph5526_queuecommand(Scsi_Cmnd *Cmnd, void (*done) (Scsi_Cmnd *))
-{
-int int_required = 0;
-u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_COMMAND;
-u_int type = TYPE_FCP | SEQUENCE_INITIATIVE;
-u_int frame_class = Cmnd->device->id;
-u_short ox_id = OX_ID_FIRST_SEQUENCE;
-struct Scsi_Host *host = Cmnd->device->host;
-struct iph5526_hostdata *hostdata = (struct iph5526_hostdata*)host->hostdata;
-struct fc_info *fi = hostdata->fi;
-struct fc_node_info *q;
-u_long flags;
-       ENTER("iph5526_queuecommand");
-
-       spin_lock_irqsave(&fi->fc_lock, flags);
-       Cmnd->scsi_done = done;
-
-       if (Cmnd->device->tagged_supported) {
-               switch(Cmnd->tag) {
-                       case SIMPLE_QUEUE_TAG:
-                               hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_SIMPLE;
-                               break;
-                       case HEAD_OF_QUEUE_TAG:
-                               hostdata->cmnd.fcp_cntl = 
FCP_CNTL_QTYPE_HEAD_OF_Q;
-                               break;
-                       case  ORDERED_QUEUE_TAG:
-                               hostdata->cmnd.fcp_cntl = 
FCP_CNTL_QTYPE_ORDERED;
-                               break;
-                       default:
-                               if ((jiffies - 
hostdata->tag_ages[Cmnd->device->id]) > (5 * HZ)) {
-                                       hostdata->cmnd.fcp_cntl = 
FCP_CNTL_QTYPE_ORDERED;
-                                       hostdata->tag_ages[Cmnd->device->id] = 
jiffies;
-                               }
-                               else
-                                       hostdata->cmnd.fcp_cntl = 
FCP_CNTL_QTYPE_SIMPLE;
-                               break;
-               }
-       }
-       /*else
-               hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_UNTAGGED;
-       */
-
-       hostdata->cmnd.fcp_addr[3] = 0;
-       hostdata->cmnd.fcp_addr[2] = 0;
-       hostdata->cmnd.fcp_addr[1] = 0;
-       hostdata->cmnd.fcp_addr[0] = htons(Cmnd->device->lun);
-
-       memcpy(&hostdata->cmnd.fcp_cdb, Cmnd->cmnd, Cmnd->cmd_len);
-       hostdata->cmnd.fcp_data_len = htonl(Cmnd->request_bufflen);
-
-       /* Get an used OX_ID. We could have pending commands.
-        */
-       if (get_scsi_oxid(fi)) {
-               spin_unlock_irqrestore(&fi->fc_lock, flags);
-               return 1;
-       }
-       fi->q.free_scsi_oxid[fi->g.scsi_oxid] = OXID_INUSE;     
-
-       /* Maintain a handler so that we can associate the done() function
-        * on completion of the SCSI command. 
-        */
-       hostdata->cmnd_handler[fi->g.scsi_oxid] = Cmnd;
-
-       switch(Cmnd->cmnd[0]) {
-               case WRITE_6:
-               case WRITE_10:
-               case WRITE_12:
-                       fi->g.type_of_frame = FC_SCSI_WRITE;
-                       hostdata->cmnd.fcp_cntl = htonl(FCP_CNTL_WRITE | 
hostdata->cmnd.fcp_cntl);
-                       break;
-               default:
-                       fi->g.type_of_frame = FC_SCSI_READ;
-                       hostdata->cmnd.fcp_cntl = htonl(FCP_CNTL_READ | 
hostdata->cmnd.fcp_cntl);
-       }
-       
-       memcpy(fi->q.ptr_fcp_cmnd[fi->q.fcp_cmnd_indx], &(hostdata->cmnd), 
sizeof(fcp_cmd));    
-       
-       q = resolve_target(fi, Cmnd->device->id);
-
-       if (q == NULL) {
-       u_int bad_id = fi->g.my_ddaa | 0xFE;
-               /* We transmit to an non-existant AL_PA so that the "done" 
-                * function can be called while receiving the interrupt 
-                * due to a Timeout for a bad AL_PA. In a PTP configuration,
-                * the int_required field is set, since there is no notion
-                * of AL_PAs. This approach sucks, but works alright!
-                */
-               if (fi->g.ptp_up == TRUE)
-                       int_required = 1;
-               tx_exchange(fi, (char *)(&(hostdata->cmnd)), sizeof(fcp_cmd), 
r_ctl, type, bad_id, fi->g.my_mtu, int_required, ox_id, FC_SCSI_BAD_TARGET);
-               spin_unlock_irqrestore(&fi->fc_lock, flags);
-               DPRINTK1("Target ID %x not present", Cmnd->target);
-               return 0;
-       }
-       if (q->login == LOGIN_COMPLETED) {
-               if (add_to_sest(fi, Cmnd, q)) {
-                       DPRINTK1("add_to_sest() failed.");
-                       spin_unlock_irqrestore(&fi->fc_lock, flags);
-                       return 0;
-               }
-               tx_exchange(fi, (char 
*)(fi->q.ptr_fcp_cmnd[fi->q.fcp_cmnd_indx]), sizeof(fcp_cmd), r_ctl, type, 
q->d_id, q->mtu, int_required, ox_id, frame_class << 16);
-               update_FCP_CMND_indx(fi);
-       }
-       spin_unlock_irqrestore(&fi->fc_lock, flags);
-       /* If q != NULL, then we have a SCSI Target. 
-        * If q->login != LOGIN_COMPLETED, then that device could be 
-        * offline temporarily. So we let the command to time-out. 
-        */
-       LEAVE("iph5526_queuecommand");
-       return 0;
-}
-
-int iph5526_abort(Scsi_Cmnd *Cmnd)
-{
-struct Scsi_Host *host = Cmnd->device->host;
-struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
-struct fc_info *fi = hostdata->fi;
-struct fc_node_info *q;
-u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_COMMAND;
-u_int type = TYPE_FCP | SEQUENCE_INITIATIVE;
-u_short ox_id = OX_ID_FIRST_SEQUENCE;
-int int_required = 1, i, abort_status = FALSE;
-u_long flags;
-       
-       ENTER("iph5526_abort");
-       
-       spin_lock_irqsave(&fi->fc_lock, flags);
-       
-       q = resolve_target(fi, Cmnd->device->id);
-       if (q == NULL) {
-       u_int bad_id = fi->g.my_ddaa | 0xFE;
-               /* This should not happen as we should always be able to
-                * resolve a target id. But, jus in case...
-                * We transmit to an non-existant AL_PA so that the done 
-                * function can be called while receiving the interrupt 
-                * for a bad AL_PA. 
-                */
-               DPRINTK1("Unresolved Target ID!");
-               tx_exchange(fi, (char *)(&(hostdata->cmnd)), sizeof(fcp_cmd), 
r_ctl, type, bad_id, fi->g.my_mtu, int_required, ox_id, FC_SCSI_BAD_TARGET);
-               DPRINTK1("Target ID %x not present", Cmnd->target);
-               spin_unlock_irqrestore(&fi->fc_lock, flags);
-               return FAILED;
-       }
-
-       /* If q != NULL, then we have a SCSI Target. If 
-        * q->login != LOGIN_COMPLETED, then that device could 
-        * be offline temporarily. So we let the command to time-out. 
-        */
-
-       /* Get the OX_ID for the Command to be aborted.
-        */
-       for (i = 0; i <= MAX_SCSI_XID; i++) {
-               if (hostdata->cmnd_handler[i] == Cmnd) {
-                       hostdata->cmnd_handler[i] = NULL;
-                       ox_id = i;
-                       break;
-               }
-       }
-       if (i > MAX_SCSI_XID) {
-               T_MSG("Command could not be resolved to OX_ID");
-               spin_unlock_irqrestore(&fi->fc_lock, flags);
-               return FAILED;
-       }
-
-       switch(Cmnd->cmnd[0]) {
-               case WRITE_6:
-               case WRITE_10:
-               case WRITE_12:
-                       break;
-               default:
-                       ox_id |= SCSI_READ_BIT;
-       }
-       abort_status = abort_exchange(fi, ox_id);
-       
-       if ((q->login == LOGIN_COMPLETED) && (abort_status == TRUE)) {
-               /* Then, transmit an ABTS to the target. The rest 
-                * is done when the BA_ACC is received for the ABTS.
-                */
-               tx_abts(fi, q->d_id, ox_id);
-       }
-       else {
-       u_int STE_bit;
-       u_short x_id;
-               /* Invalidate resources for that Exchange.
-                */
-               x_id = ox_id & MAX_SCSI_XID;
-               STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
-               if (STE_bit & SEST_V) {
-                       *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
-                       invalidate_SEST_entry(fi, ox_id);
-               }
-       }
-
-       LEAVE("iph5526_abort");
-       spin_unlock_irqrestore(&fi->fc_lock, flags);
-       return SUCCESS;
-}
-
-static int abort_exchange(struct fc_info *fi, u_short ox_id)
-{
-u_short x_id;
-volatile u_int flush_SEST, STE_bit;
-       x_id = ox_id & MAX_SCSI_XID;
-       DPRINTK1("Aborting Exchange %x", ox_id);
-
-       STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
-       /* Is the Exchange still active?.
-        */
-       if (STE_bit & SEST_V) {
-               if (ox_id & SCSI_READ_BIT) {
-                       /* If the Exchange to be aborted is Inbound, 
-                        * Flush the SEST Entry from Tachyon's Cache.
-                        */
-                       *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
-                       flush_tachyon_cache(fi, ox_id);
-                       flush_SEST = readl(fi->t_r.ptr_tach_flush_oxid_reg);
-                       while ((flush_SEST & 0x80000000) != 0) 
-                               flush_SEST = 
readl(fi->t_r.ptr_tach_flush_oxid_reg);
-                       STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
-                       while ((STE_bit & 0x80000000) != 0)
-                               STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
-                       flush_SEST = readl(fi->t_r.ptr_tach_flush_oxid_reg);
-                       invalidate_SEST_entry(fi, ox_id);
-               }
-               else {
-               int i;
-               u_int *ptr_edb;
-                       /* For In-Order Reassembly, the following is done:
-                        * First, write zero as the buffer length in the EDB. 
-                        */
-                       ptr_edb = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 
7)));
-                       for (i = 0; i < EDB_LEN; i++)
-                               if (fi->q.ptr_edb[i] == ptr_edb)
-                                       break;
-                       if (i < EDB_LEN) 
-                               *ptr_edb = *ptr_edb & 0x0000FFFF;
-                       else
-                               T_MSG("EDB not found while clearing in 
abort_exchange()");
-               }
-               DPRINTK1("Exchange %x invalidated", ox_id);
-               return TRUE;
-       }
-       else {
-               DPRINTK1("SEST Entry for exchange %x not valid", ox_id);
-               return FALSE;
-       }       
-}
-
-static void flush_tachyon_cache(struct fc_info *fi, u_short ox_id)
-{
-volatile u_int tachyon_status;
-       if (fi->g.loop_up == TRUE) {
-               writel(HOST_CONTROL, fi->t_r.ptr_fm_control_reg);
-               /* Make sure that the Inbound FIFO is empty.
-                */
-               do {
-                       tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
-                       udelay(200);
-               }while ((tachyon_status & RECEIVE_FIFO_EMPTY) == 0);
-               /* Ok. Go ahead and flushhhhhhhhh!
-                */
-               writel(0x80000000 | ox_id, fi->t_r.ptr_tach_flush_oxid_reg);
-               writel(EXIT_HOST_CONTROL, fi->t_r.ptr_fm_control_reg);
-               return;
-       }
-       if (fi->g.ptp_up == TRUE) {
-               take_tachyon_offline(fi);
-               /* Make sure that the Inbound FIFO is empty.
-                */
-               do {
-                       tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
-                       udelay(200);
-               }while ((tachyon_status & RECEIVE_FIFO_EMPTY) == 0);
-               writel(0x80000000 | ox_id, fi->t_r.ptr_tach_flush_oxid_reg);
-               /* Write the Initialize command to the FM Control reg.
-                */
-               fi->g.n_port_try = TRUE;
-               DPRINTK1("In abort_exchange, TACHYON initializing as 
N_Port...\n");
-               writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
-       }
-}
-
-static struct fc_node_info *resolve_target(struct fc_info *fi, u_char target)
-{
-struct fc_node_info *temp = fi->node_info_list;
-       while(temp != NULL)
-               if (temp->target_id == target) {
-                       if ((temp->scsi == TARGET) && (temp->login == 
LOGIN_COMPLETED))
-                               return temp;
-                       else {
-                               if (temp->login != LOGIN_COMPLETED) {
-                                       /* The Target is not currently logged 
in.
-                                        * It could be a Target on the Local 
Loop or
-                                        * on a Remote Loop connected through a 
switch.
-                                        * In either case, we will know 
whenever the Target
-                                        * comes On-Line again. We let the 
command to 
-                                        * time-out so that it gets retried.
-                                        */
-                                       T_MSG("Target %d not logged in.", 
temp->target_id);
-                                       tx_logi(fi, ELS_PLOGI, temp->d_id);
-                                       return temp;
-                               }
-                               else {
-                                       if (temp->scsi != TARGET) {
-                                               /* For some reason, we did not 
get a response to
-                                                * PRLI. Letz try it again...
-                                                */
-                                               DPRINTK1("Node not PRLIied. 
Txing PRLI...");
-                                               tx_prli(fi, ELS_PRLI, 
temp->d_id, OX_ID_FIRST_SEQUENCE);
-                                       }
-                               }
-                               return temp;
-                       }
-               }
-               else
-                       temp = temp->next;
-       return NULL;
-}
-
-static int add_to_sest(struct fc_info *fi, Scsi_Cmnd *Cmnd, struct 
fc_node_info *ni)
-{
-/* we have at least 1 buffer, the terminator */
-int no_of_sdb_buffers = 1, i; 
-int no_of_edb_buffers = 0; 
-u_int *req_buffer = (u_int *)Cmnd->request_buffer;
-u_int *ptr_sdb = NULL;
-struct scatterlist *sl1, *sl2 = NULL;
-int no_of_sg = 0;
-
-       switch(fi->g.type_of_frame) {
-               case FC_SCSI_READ:
-                       fi->g.inb_sest_entry.flags_and_byte_offset = 
htonl(INB_SEST_VED);
-                       fi->g.inb_sest_entry.byte_count = 0;
-                       fi->g.inb_sest_entry.no_of_recvd_frames = 0;
-                       fi->g.inb_sest_entry.no_of_expected_frames = 0;
-                       fi->g.inb_sest_entry.last_fctl = 0;
-
-                       if (Cmnd->use_sg) {
-                               no_of_sg = Cmnd->use_sg;
-                               sl1 = sl2 = (struct scatterlist 
*)Cmnd->request_buffer;
-                               for (i = 0; i < no_of_sg; i++) {
-                                       no_of_sdb_buffers += sl1->length / 
SEST_BUFFER_SIZE;
-                                       if (sl1->length % SEST_BUFFER_SIZE)
-                                               no_of_sdb_buffers++;
-                                       sl1++;
-                               }
-                       }
-                       else {
-                               no_of_sdb_buffers += Cmnd->request_bufflen / 
SEST_BUFFER_SIZE;
-                               if (Cmnd->request_bufflen % SEST_BUFFER_SIZE)
-                                       no_of_sdb_buffers++;
-                       } /* if !use_sg */
-
-                       /* We are working with the premise that at the max we 
would
-                        * get a scatter-gather buffer containing 63 buffers
-                        * of size 1024 bytes each. Is it a _bad_ assumption?
-                        */
-                       if (no_of_sdb_buffers > 512) {
-                               T_MSG("Number of SDB buffers needed = %d", 
no_of_sdb_buffers);
-                               T_MSG("Disable Scatter-Gather!!!");
-                               return 1;
-                       }
-                               
-
-                       /* Store it in the sdb_table so that we can retrieve 
that
-                        * free up the memory when the Read Command completes.
-                        */
-                       if (get_free_SDB(fi))
-                               return 1;
-                       ptr_sdb = fi->q.ptr_sdb_slot[fi->q.sdb_indx];
-                       fi->q.sdb_slot_status[fi->q.sdb_indx] = SDB_BUSY;
-                       fi->g.inb_sest_entry.sdb_address = 
htonl(virt_to_bus(ptr_sdb));
-
-                       if (Cmnd->use_sg) {
-                       int count = 0, j;
-                               for(i = 0; i < no_of_sg; i++) {
-                               char *addr_ptr = sl2->address;
-                                       count = sl2->length / SEST_BUFFER_SIZE;
-                                       if (sl2->length % SEST_BUFFER_SIZE)
-                                               count++;
-                                       for (j = 0; j < count; j++) {
-                                               *(ptr_sdb) = 
htonl(virt_to_bus(addr_ptr));
-                                               addr_ptr += SEST_BUFFER_SIZE;
-                                               ptr_sdb++;
-                                       }
-                                       count = 0;
-                                       sl2++;
-                               }
-                       }
-                       else {
-                               for (i = 0; i < no_of_sdb_buffers - 1; i++) {
-                                       *(ptr_sdb) = 
htonl(virt_to_bus(req_buffer));
-                                       req_buffer += SEST_BUFFER_SIZE/4;
-                                       ptr_sdb++;
-                               }
-                       }
-                       *(ptr_sdb) = htonl(0x1); /* Terminator */
-                       
-                       /* The scratch pad is used to hold the index into the 
SDB.
-                        */
-                       fi->g.inb_sest_entry.scratch_pad = fi->q.sdb_indx;
-                       fi->g.inb_sest_entry.expected_ro = 0;
-                       fi->g.inb_sest_entry.buffer_index = 0;
-                       fi->g.inb_sest_entry.buffer_offset = 0;
-                       memcpy(fi->q.ptr_sest[fi->g.scsi_oxid], 
&fi->g.inb_sest_entry, sizeof(INB_SEST_ENTRY));
-                       break;
-               case FC_SCSI_WRITE:
-                       fi->g.outb_sest_entry.flags_and_did = 
htonl(OUTB_SEST_VED | ni->d_id);
-                       fi->g.outb_sest_entry.max_frame_len = htons(ni->mtu << 
4);
-                       fi->g.outb_sest_entry.cntl = htons(ODB_CLASS_3 | 
ODB_EE_CREDIT | ODB_NO_INT | ODB_NO_COMP);
-                       fi->g.outb_sest_entry.total_seq_length = INV_SEQ_LEN;
-                       fi->g.outb_sest_entry.link = htons(OUTB_SEST_LINK);
-                       fi->g.outb_sest_entry.transaction_id = 
htonl(fi->g.scsi_oxid);
-                       fi->g.outb_sest_entry.seq_id = fi->g.seq_id;
-                       fi->g.outb_sest_entry.reserved = 0x0;
-                       fi->g.outb_sest_entry.header_length = 
htons(TACHYON_HEADER_LEN);
-               
-                       {
-                       u_char df_ctl = 0;
-                       u_short rx_id = RX_ID_FIRST_SEQUENCE;
-                       u_int r_ctl = FC4_DEVICE_DATA | SOLICITED_DATA;
-                       u_int type = TYPE_FCP | SEQUENCE_INITIATIVE;
-                               /* Multi Frame Sequence ? If yes, set RO bit. 
-                                */
-                               if (Cmnd->request_bufflen > ni->mtu)
-                                       type |= RELATIVE_OFF_PRESENT;
-                               build_tachyon_header(fi, fi->g.my_id, r_ctl, 
ni->d_id, type, fi->g.seq_id, df_ctl, fi->g.scsi_oxid, rx_id, NULL);
-                               if (get_free_header(fi) || get_free_EDB(fi))
-                                       return 1;
-                               
memcpy(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx], 
&(fi->g.tach_header), TACHYON_HEADER_LEN);
-                               fi->g.outb_sest_entry.header_address = 
htonl(virt_to_bus(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx]));
-                               update_tachyon_header_indx(fi);
-                       }
-
-                       if (Cmnd->use_sg) {
-                               no_of_sg = Cmnd->use_sg;
-                               sl1 = sl2 = (struct scatterlist 
*)Cmnd->request_buffer;
-                               for (i = 0; i < no_of_sg; i++) {
-                                       no_of_edb_buffers += sl1->length / 
SEST_BUFFER_SIZE;
-                                       if (sl1->length % SEST_BUFFER_SIZE)
-                                               no_of_edb_buffers++;
-                                       sl1++;
-                               }
-                       }
-                       else {
-                               no_of_edb_buffers += Cmnd->request_bufflen / 
SEST_BUFFER_SIZE;
-                               if (Cmnd->request_bufflen % SEST_BUFFER_SIZE)
-                                       no_of_edb_buffers++;
-                       } /* if !use_sg */
-
-
-                       /* We need "no_of_edb_buffers" _contiguous_ EDBs 
-                        * that are FREE. Check for that first.
-                        */
-                       for (i = 0; i < no_of_edb_buffers; i++) {
-                       int j;
-                               if ((fi->q.edb_buffer_indx + no_of_edb_buffers) 
>= EDB_LEN)
-                                       fi->q.edb_buffer_indx = 0;
-                               if (fi->q.free_edb_list[fi->q.edb_buffer_indx + 
i] != EDB_FREE) {
-                                       for (j = 0; j < i; j++)
-                                               update_EDB_indx(fi);
-                                       if (get_free_EDB(fi))
-                                               return 1;
-                                       i = 0;
-                               }
-                       }
-
-                       /* We got enuff FREE EDBs.
-                        */
-                       if (Cmnd->use_sg) {
-                               fi->g.outb_sest_entry.edb_address = 
htonl(virt_to_bus(fi->q.ptr_edb[fi->q.edb_buffer_indx]));
-                               sl1 = (struct scatterlist 
*)Cmnd->request_buffer;
-                               for(i = 0; i < no_of_sg; i++) {
-                               int count = 0, j;
-                                       count = sl1->length / SEST_BUFFER_SIZE;
-                                       for (j = 0; j < count; j++) {
-                                               build_EDB(fi, (char 
*)sl1->address, 0, SEST_BUFFER_SIZE);
-                                               
memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB));
-                                               /* Mark this EDB as being in 
use */
-                                               
fi->q.free_edb_list[fi->q.edb_buffer_indx] = EDB_BUSY;
-                                               /* We have already made sure 
that we have enuff
-                                                * free EDBs that are 
contiguous. So this is 
-                                                * safe.
-                                                */
-                                               update_EDB_indx(fi);
-                                               sl1->address += 
SEST_BUFFER_SIZE;
-                                       }
-                                       /* Just in case itz not a multiple of 
-                                        * SEST_BUFFER_SIZE bytes.
-                                        */
-                                       if (sl1->length % SEST_BUFFER_SIZE) {
-                                               build_EDB(fi, (char 
*)sl1->address, 0, sl1->length % SEST_BUFFER_SIZE);
-                                               
memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB));
-                                               
fi->q.free_edb_list[fi->q.edb_buffer_indx] = EDB_BUSY;
-                                               update_EDB_indx(fi);
-                                       }
-                                       sl1++;
-                               }
-                               /* The last EDB is special. It needs the "end 
bit" to
-                                * be set.
-                                */
-                               *(fi->q.ptr_edb[fi->q.edb_buffer_indx - 1] + 1) 
= *(fi->q.ptr_edb[fi->q.edb_buffer_indx - 1] + 1) | ntohs(EDB_END);
-                       }
-                       else {
-                       int count = 0, j;
-                               fi->g.outb_sest_entry.edb_address = 
htonl(virt_to_bus(fi->q.ptr_edb[fi->q.edb_buffer_indx]));
-                               count = Cmnd->request_bufflen / 
SEST_BUFFER_SIZE;
-                               for (j = 0; j < count; j++) {
-                                       build_EDB(fi, (char *)req_buffer, 0, 
SEST_BUFFER_SIZE);
-                                       
memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB));
-                                       /* Mark this EDB as being in use */
-                                       
fi->q.free_edb_list[fi->q.edb_buffer_indx] = EDB_BUSY;
-                                       /* We have already made sure that we 
have enuff
-                                        * free EDBs that are contiguous. So 
this is 
-                                        * safe.
-                                        */
-                                       update_EDB_indx(fi);
-                                       req_buffer += SEST_BUFFER_SIZE;
-                               }
-                               /* Just in case itz not a multiple of 
-                                * SEST_BUFFER_SIZE bytes.
-                                */
-                               if (Cmnd->request_bufflen % SEST_BUFFER_SIZE) {
-                                       build_EDB(fi, (char *)req_buffer, 
EDB_END, Cmnd->request_bufflen % SEST_BUFFER_SIZE);
-                                       
memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB));
-                                       
fi->q.free_edb_list[fi->q.edb_buffer_indx] = EDB_BUSY;
-                                       update_EDB_indx(fi);
-                               }
-                               else {
-                                       /* Mark the last EDB as the "end edb".
-                                        */
-                                       *(fi->q.ptr_edb[fi->q.edb_buffer_indx - 
1] + 1) = *(fi->q.ptr_edb[fi->q.edb_buffer_indx - 1] + 1) | htons(EDB_END);
-                               }
-                       }
-
-                       /* Finally we have something to send!.
-                        */
-                       memcpy(fi->q.ptr_sest[fi->g.scsi_oxid], 
&fi->g.outb_sest_entry, sizeof(OUTB_SEST_ENTRY));
-                       break;
-               }               
-       return 0;
-}
-
-static void update_FCP_CMND_indx(struct fc_info *fi)
-{
-       fi->q.fcp_cmnd_indx++;
-       if (fi->q.fcp_cmnd_indx == NO_OF_FCP_CMNDS)
-               fi->q.fcp_cmnd_indx = 0;
-}
-
-static int get_scsi_oxid(struct fc_info *fi)
-{
-u_short initial_oxid = fi->g.scsi_oxid;
-       /* Check if the OX_ID is in use.
-        * We could have an outstanding SCSI command.
-        */
-       while (fi->q.free_scsi_oxid[fi->g.scsi_oxid] != OXID_AVAILABLE) {
-               update_scsi_oxid(fi);
-               if (fi->g.scsi_oxid == initial_oxid) {
-                       T_MSG("No free OX_IDs avaliable")
-                       reset_tachyon(fi, SOFTWARE_RESET);
-                       return 1;
-               }
-       }
-       return 0;
-}              
-
-static void update_scsi_oxid(struct fc_info *fi)
-{
-       fi->g.scsi_oxid++;
-       if (fi->g.scsi_oxid == (MAX_SCSI_XID + 1))
-               fi->g.scsi_oxid = 0;
-}
-
-static int get_free_SDB(struct fc_info *fi)
-{
-unsigned int initial_indx = fi->q.sdb_indx;
-       /* Check if the SDB is in use.
-        * We could have an outstanding SCSI Read command.
-        * We should find a free slot as we can queue a
-        * maximum of 32 SCSI commands only. 
-        */
-       while (fi->q.sdb_slot_status[fi->q.sdb_indx] != SDB_FREE) {
-               update_SDB_indx(fi);
-               if (fi->q.sdb_indx == initial_indx) {
-                       T_MSG("No free SDB buffers avaliable")
-                       reset_tachyon(fi, SOFTWARE_RESET);
-                       return 1;
-               }
-       }
-       return 0;
-}              
-
-static void update_SDB_indx(struct fc_info *fi)
-{
-       fi->q.sdb_indx++;
-       if (fi->q.sdb_indx == NO_OF_SDB_ENTRIES)
-               fi->q.sdb_indx = 0;
-}
-
-int iph5526_release(struct Scsi_Host *host)
-{
-struct iph5526_hostdata *hostdata = (struct iph5526_hostdata*)host->hostdata;
-struct fc_info *fi = hostdata->fi;
-       free_irq(host->irq, host);
-       iounmap(fi->g.mem_base);
-       return 0;
-}
-
-const char *iph5526_info(struct Scsi_Host *host)
-{
-static char buf[80];
-       sprintf(buf, "Interphase 5526 Fibre Channel PCI SCSI Adapter using IRQ 
%d\n", host->irq);
-       return buf;
-}
-
-#define NAMELEN                8       /* # of chars for storing dev->name */
-
-static struct net_device *dev_fc[MAX_FC_CARDS];
-
-static int io;
-static int irq;
-static int bad;        /* 0xbad = bad sig or no reset ack */
-static int scsi_registered;
-
-
-static int __init iph5526_init(void)
-{
-       int i = 0;
-
-       driver_template.module = THIS_MODULE;
-       scsi_register_host(&driver_template);
-       if (driver_template.present)
-               scsi_registered = TRUE; 
-       else {
-               printk("iph5526: SCSI registeration failed!!!\n");
-               scsi_registered = FALSE;
-               scsi_unregister_host(&driver_template);
-       }
-
-       while(fc[i] != NULL) {
-               struct net_device *dev = alloc_fcdev(0);
-               int err;
-
-               if (!dev) {
-                       printk("iph5526.c: init_fcdev failed for card #%d\n", 
i+1);
-                       break;
-               }
-               dev->priv = fc[i];
-               iph5526_probe_pci(dev);
-               err = register_netdev(dev);
-               if (err < 0) {
-                       free_netdev(dev);
-                       printk("iph5526.c: init_fcdev failed for card #%d\n", 
i+1);
-                       break;
-               }
-               dev_fc[i] = dev;
-               i++;
-       }
-       if (i == 0)
-               return -ENODEV;
-
-       return 0;
-}
-
-static void __exit iph5526_exit(void)
-{
-       int i = 0;
-       while(fc[i] != NULL) {
-               struct net_device *dev = fc[i]->dev;
-               void *priv = dev->priv;
-               fc[i]->g.dont_init = TRUE;
-               take_tachyon_offline(fc[i]);
-               unregister_netdev(dev);
-               clean_up_memory(fc[i]);
-               if (dev->priv)
-                       kfree(priv);
-               free_netdev(dev);
-               dev = NULL;
-               i++;
-       }
-       if (scsi_registered == TRUE)
-               scsi_unregister_host(&driver_template); 
-}
-
-module_init(iph5526_init);
-module_exit(iph5526_exit);
-
-void clean_up_memory(struct fc_info *fi)
-{
-int i,j;
-       ENTER("clean_up_memory");
-       if (fi->q.ptr_mfsbq_base)
-               free_pages((u_long)bus_to_virt(ntohl(*(fi->q.ptr_mfsbq_base))), 
5);
-       DPRINTK("after kfree2");
-       for (i = 0; i < SFSBQ_LENGTH; i++)
-               for (j = 0; j < NO_OF_ENTRIES; j++)
-                       if (fi->q.ptr_sfs_buffers[i*NO_OF_ENTRIES + j])
-                               kfree(fi->q.ptr_sfs_buffers[i*NO_OF_ENTRIES + 
j]);
-       DPRINTK("after kfree1");
-       if (fi->q.ptr_ocq_base)
-               free_page((u_long)fi->q.ptr_ocq_base);
-       if (fi->q.ptr_imq_base)
-               free_page((u_long)fi->q.ptr_imq_base);
-       if (fi->q.ptr_mfsbq_base)
-               free_page((u_long)fi->q.ptr_mfsbq_base);
-       if (fi->q.ptr_sfsbq_base)
-               free_page((u_long)fi->q.ptr_sfsbq_base);
-       if (fi->q.ptr_edb_base)
-               free_pages((u_long)fi->q.ptr_edb_base, 5);
-       if (fi->q.ptr_sest_base)
-               free_pages((u_long)fi->q.ptr_sest_base, 5);
-       if (fi->q.ptr_tachyon_header_base)
-               free_page((u_long)fi->q.ptr_tachyon_header_base);
-       if (fi->q.ptr_sdb_base)
-               free_pages((u_long)fi->q.ptr_sdb_base, 5);
-       if (fi->q.ptr_fcp_cmnd_base)
-               free_page((u_long)fi->q.ptr_fcp_cmnd_base);
-       DPRINTK("after free_pages"); 
-       if (fi->q.ptr_host_ocq_cons_indx)
-               kfree(fi->q.ptr_host_ocq_cons_indx);
-       if (fi->q.ptr_host_hpcq_cons_indx)
-               kfree(fi->q.ptr_host_hpcq_cons_indx);
-       if (fi->q.ptr_host_imq_prod_indx)
-               kfree(fi->q.ptr_host_imq_prod_indx);
-       DPRINTK("after kfree3");
-       while (fi->node_info_list) {
-       struct fc_node_info *temp_list = fi->node_info_list;
-               fi->node_info_list = fi->node_info_list->next;
-               kfree(temp_list);
-       }
-       while (fi->ox_id_list) {
-       struct ox_id_els_map *temp = fi->ox_id_list;
-               fi->ox_id_list = fi->ox_id_list->next;
-               kfree(temp);
-       }
-       LEAVE("clean_up_memory");
-}
-
-static int initialize_register_pointers(struct fc_info *fi)
-{
-ENTER("initialize_register_pointers");
-if(fi->g.tachyon_base == 0)
-       return -ENOMEM; 
-       
-fi->i_r.ptr_ichip_hw_control_reg       = ICHIP_HW_CONTROL_REG_OFF + 
fi->g.tachyon_base;
-fi->i_r.ptr_ichip_hw_status_reg = ICHIP_HW_STATUS_REG_OFF + fi->g.tachyon_base;
-fi->i_r.ptr_ichip_hw_addr_mask_reg = ICHIP_HW_ADDR_MASK_REG_OFF + 
fi->g.tachyon_base;
-fi->t_r.ptr_ocq_base_reg = OCQ_BASE_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_ocq_len_reg = OCQ_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_ocq_prod_indx_reg = OCQ_PRODUCER_REGISTER_OFFSET + 
fi->g.tachyon_base;
-fi->t_r.ptr_ocq_cons_indx_reg = OCQ_CONSUMER_REGISTER_OFFSET + 
fi->g.tachyon_base;
-fi->t_r.ptr_imq_base_reg = IMQ_BASE_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_imq_len_reg = IMQ_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_imq_cons_indx_reg = IMQ_CONSUMER_REGISTER_OFFSET + 
fi->g.tachyon_base;
-fi->t_r.ptr_imq_prod_indx_reg = IMQ_PRODUCER_REGISTER_OFFSET + 
fi->g.tachyon_base;
-fi->t_r.ptr_mfsbq_base_reg = MFSBQ_BASE_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_mfsbq_len_reg = MFSBQ_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_mfsbq_prod_reg = MFSBQ_PRODUCER_REGISTER_OFFSET + 
fi->g.tachyon_base;
-fi->t_r.ptr_mfsbq_cons_reg = MFSBQ_CONSUMER_REGISTER_OFFSET + 
fi->g.tachyon_base;
-fi->t_r.ptr_mfsbuff_len_reg = MFS_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_sfsbq_base_reg = SFSBQ_BASE_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_sfsbq_len_reg = SFSBQ_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_sfsbq_prod_reg = SFSBQ_PRODUCER_REGISTER_OFFSET + 
fi->g.tachyon_base;
-fi->t_r.ptr_sfsbq_cons_reg = SFSBQ_CONSUMER_REGISTER_OFFSET + 
fi->g.tachyon_base;
-fi->t_r.ptr_sfsbuff_len_reg = SFS_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_sest_base_reg = SEST_BASE_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_sest_len_reg = SEST_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_scsibuff_len_reg = SCSI_LENGTH_REGISTER_OFFSET + 
fi->g.tachyon_base;
-fi->t_r.ptr_tach_config_reg = TACHYON_CONFIG_REGISTER_OFFSET + 
fi->g.tachyon_base;
-fi->t_r.ptr_tach_control_reg = TACHYON_CONTROL_REGISTER_OFFSET + 
fi->g.tachyon_base;
-fi->t_r.ptr_tach_status_reg = TACHYON_STATUS_REGISTER_OFFSET + 
fi->g.tachyon_base;
-fi->t_r.ptr_tach_flush_oxid_reg = TACHYON_FLUSH_SEST_REGISTER_OFFSET + 
fi->g.tachyon_base;
-fi->t_r.ptr_fm_config_reg = FMGR_CONFIG_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_fm_control_reg = FMGR_CONTROL_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_fm_status_reg = FMGR_STATUS_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_fm_tov_reg = FMGR_TIMER_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_fm_wwn_hi_reg = FMGR_WWN_HI_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_fm_wwn_low_reg = FMGR_WWN_LO_REGISTER_OFFSET + fi->g.tachyon_base;
-fi->t_r.ptr_fm_rx_al_pa_reg = FMGR_RCVD_ALPA_REGISTER_OFFSET + 
fi->g.tachyon_base;
-
-LEAVE("initialize_register_pointers");
-return 1;
-}
-
-
-
-/*
- * Local variables:
- *  compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer 
-I/usr/src/linux/net/tcp -c iph5526.c"
- *  version-control: t
- *  kept-new-versions: 5
- * End:
- */
===== drivers/net/fc/iph5526_ip.h 1.1 vs edited =====
--- 1.1/drivers/net/fc/iph5526_ip.h     2002-02-05 18:40:03 +01:00
+++ edited/drivers/net/fc/iph5526_ip.h  2004-09-06 11:54:04 +02:00
@@ -1,25 +0,0 @@
-#ifndef IPH5526_IP_H
-#define IPH5526_IP_H
-
-#define LLC_SNAP_LEN           0x8
-
-/* Offsets into the ARP frame */
-#define ARP_OPCODE_0   (0x6 + LLC_SNAP_LEN)
-#define ARP_OPCODE_1   (0x7 + LLC_SNAP_LEN)
-
-int iph5526_probe(struct net_device *dev);
-static int fcdev_init(struct net_device *dev);
-static int iph5526_open(struct net_device *dev);
-static int iph5526_close(struct net_device *dev);
-static int iph5526_send_packet(struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats * iph5526_get_stats(struct net_device *dev);
-static int iph5526_change_mtu(struct net_device *dev, int mtu);
-
-
-static void rx_net_packet(struct fc_info *fi, u_char *buff_addr, int 
payload_size);
-static void rx_net_mfs_packet(struct fc_info *fi, struct sk_buff *skb);
-unsigned short fc_type_trans(struct sk_buff *skb, struct net_device *dev); 
-static int tx_ip_packet(struct sk_buff *skb, unsigned long len, struct fc_info 
*fi);
-static int tx_arp_packet(char *data, unsigned long len, struct fc_info *fi);
-#endif
-
===== drivers/net/fc/iph5526_novram.c 1.1 vs edited =====
--- 1.1/drivers/net/fc/iph5526_novram.c 2002-02-05 18:40:03 +01:00
+++ edited/drivers/net/fc/iph5526_novram.c      2004-09-06 11:54:09 +02:00
@@ -1,278 +0,0 @@
-/********************************************************************** 
- * Reading the NVRAM on the Interphase 5526 PCI Fibre Channel Card. 
- * All contents in this file : courtesy Interphase Corporation.
- * Special thanks to Kevin Quick, kquick@xxxxxxxxxxx
- **********************************************************************/
-
-#define FF_MAGIC        0x4646
-#define DB_MAGIC        0x4442
-#define DL_MAGIC        0x444d
-
-
-#define CMD_LEN         9
-
-/***********
- *
- *      Switches and defines for header files.
- *
- *      The following defines are used to turn on and off
- *      various options in the header files. Primarily useful
- *      for debugging.
- *
- ***********/
-
-static const unsigned short novram_default[4] = {
-    FF_MAGIC,
-    DB_MAGIC,
-    DL_MAGIC,
-    0 };
-
-
-/*
- * a list of the commands that can be sent to the NOVRAM
- */
-
-#define NR_EXTEND  0x100
-#define NR_WRITE   0x140
-#define NR_READ    0x180
-#define NR_ERASE   0x1c0
-
-#define EWDS    0x00
-#define WRAL    0x10
-#define ERAL    0x20
-#define EWEN    0x30
-
-/*
- * Defines for the pins on the NOVRAM
- */
-
-#define BIT(x)          (1 << (x))
-
-#define NVDI_B          31
-#define NVDI            BIT(NVDI_B)
-#define NVDO            BIT(9)
-#define NVCE            BIT(30)
-#define NVSK            BIT(29)
-#define NV_MANUAL       BIT(28)
-
-/***********
- *
- *      Include files.
- *
- ***********/
-
-#define KeStallExecutionProcessor(x)    {volatile int d, p;\
-                 for (d=0; d<x; d++) for (p=0; p<10; p++);\
-                                    }
-
-
-/***********************
- *
- * This define ands the value and the current config register and puts
- * the result in the config register
- *
- ***********************/
-
-#define CFG_AND(val) { volatile int t; \
-                          t = readl(fi->n_r.ptr_novram_hw_control_reg);   \
-                          t &= (val);                                  \
-                          writel(t, fi->n_r.ptr_novram_hw_control_reg);   \
-                  }
-
-/***********************
- *
- * This define ors the value and the current config register and puts
- * the result in the config register
- *
- ***********************/
-
-#define CFG_OR(val) { volatile int t; \
-                          t = readl(fi->n_r.ptr_novram_hw_control_reg);   \
-                          t |= (val);                                  \
-                          writel(t, fi->n_r.ptr_novram_hw_control_reg);   \
-                  }
-
-/***********************
- *
- * Send a command to the NOVRAM, the command is in cmd.
- *
- * clear CE and SK. Then assert CE.
- * Clock each of the command bits out in the correct order with SK
- * exit with CE still asserted
- *
- ***********************/
-
-#define NVRAM_CMD(cmd) { int i; \
-                        int c = cmd; \
-                        CFG_AND(~(NVCE|NVSK)); \
-                        CFG_OR(NVCE); \
-                        for (i=0; i<CMD_LEN; i++) { \
-                            NVRAM_CLKOUT((c & (1 << (CMD_LEN - 1))) ? 1 : 0);\
-                            c <<= 1; } }
-
-/***********************
- *
- * clear the CE, this must be used after each command is complete
- *
- ***********************/
-
-#define NVRAM_CLR_CE    CFG_AND(~NVCE)
-
-/***********************
- *
- * clock the data bit in bitval out to the NOVRAM.  The bitval must be
- * a 1 or 0, or the clockout operation is undefined
- *
- ***********************/
-
-#define NVRAM_CLKOUT(bitval) {\
-                          CFG_AND(~NVDI); \
-                          CFG_OR((bitval) << NVDI_B); \
-                          KeStallExecutionProcessor(5);\
-                          CFG_OR(NVSK); \
-                          KeStallExecutionProcessor(5);\
-                          CFG_AND( ~NVSK); \
-                          }
-
-/***********************
- *
- * clock the data bit in and return a 1 or 0, depending on the value
- * that was received from the NOVRAM
- *
- ***********************/
-
-#define NVRAM_CLKIN(val)        {\
-                      CFG_OR(NVSK); \
-                          KeStallExecutionProcessor(5);\
-                      CFG_AND(~NVSK); \
-                          KeStallExecutionProcessor(5);\
-                      val = (readl(fi->n_r.ptr_novram_hw_status_reg) & NVDO) ? 
1 : 0; \
-                      }
-
-/***********
- *
- *      Function Prototypes
- *
- ***********/
-
-static int iph5526_nr_get(struct fc_info *fi, int addr);
-static void iph5526_nr_do_init(struct fc_info *fi);
-static void iph5526_nr_checksum(struct fc_info *fi);
-
-
-/*******************************************************************
- *
- *      Local routine:  iph5526_nr_do_init
- *      Purpose:        initialize novram server
- *      Description:
- *
- *      iph5526_nr_do_init reads the novram into the temporary holding place.
- *      A checksum is done on the area and the Magic Cookies are checked.
- *      If any of them are bad, the NOVRAM is initialized with the 
- *      default values and a warning message is displayed.
- *
- *******************************************************************/
-
-static void iph5526_nr_do_init(struct fc_info *fi)
-{
-    int i;
-    unsigned short chksum = 0;
-    int bad = 0;
-
-    for (i=0; i<IPH5526_NOVRAM_SIZE; i++) {
-       fi->n_r.data[i] = iph5526_nr_get(fi, i);
-       chksum += fi->n_r.data[i];
-    }
-
-    if (chksum) 
-       bad = 1;
-
-    if (fi->n_r.data[IPH5526_NOVRAM_SIZE - 4] != FF_MAGIC)
-       bad = 1;
-    if (fi->n_r.data[IPH5526_NOVRAM_SIZE - 3] != DB_MAGIC)
-       bad = 1;                 
-       if (fi->n_r.data[IPH5526_NOVRAM_SIZE - 2] != DL_MAGIC)
-       bad = 1;
-
-    if (bad) {
-       for (i=0; i<IPH5526_NOVRAM_SIZE; i++) {
-           if (i < (IPH5526_NOVRAM_SIZE - 4)) {
-               fi->n_r.data[i] = 0xffff;
-           } else {
-               fi->n_r.data[i] = novram_default[i - (IPH5526_NOVRAM_SIZE - 4)];
-           }
-       }
-       iph5526_nr_checksum(fi);
-    }
-}
-
-
-/*******************************************************************
- *
- *      Local routine:  iph5526_nr_get
- *      Purpose:        read a single word of NOVRAM
- *      Description:
- *
- *      read the 16 bits that make up a word addr of the novram.  
- *      The 16 bits of data that are read are returned as the return value
- *
- *******************************************************************/
-
-static int iph5526_nr_get(struct fc_info *fi, int addr)
-{
-    int i;
-    int t;
-    int val = 0;
-
-    CFG_OR(NV_MANUAL);
-
-    /*
-     * read the first bit that was clocked with the falling edge of the
-     * the last command data clock
-     */
-
-    NVRAM_CMD(NR_READ + addr);
-
-    /*
-     * Now read the rest of the bits, the next bit read is D1, then D2,
-     * and so on
-     */
-
-    val = 0;
-    for (i=0; i<16; i++) {
-       NVRAM_CLKIN(t);
-       val <<= 1;
-       val |= t;
-    }
-    NVRAM_CLR_CE;
-
-    CFG_OR(NVDI);
-    CFG_AND(~NV_MANUAL);
-
-    return(val);
-}
-
-
-
-
-/*******************************************************************
- *
- *      Local routine:  iph5526_nr_checksum
- *      Purpose:        calculate novram checksum on fi->n_r.data
- *      Description:
- *
- *      calculate a checksum for the novram on the image that is
- *      currently in fi->n_r.data
- *
- *******************************************************************/
-
-static void iph5526_nr_checksum(struct fc_info *fi)
-{
-    int i;
-    unsigned short chksum = 0;
-
-    for (i=0; i<(IPH5526_NOVRAM_SIZE - 1); i++)
-       chksum += fi->n_r.data[i];
-
-    fi->n_r.data[i] = -chksum;
-}
===== drivers/net/fc/iph5526_scsi.h 1.4 vs edited =====
--- 1.4/drivers/net/fc/iph5526_scsi.h   2004-01-10 16:32:23 +01:00
+++ edited/drivers/net/fc/iph5526_scsi.h        2004-09-06 11:54:12 +02:00
@@ -1,31 +0,0 @@
-#ifndef IPH5526_SCSI_H
-#define IPH5526_SCSI_H
-
-#define IPH5526_CAN_QUEUE      32
-#define IPH5526_SCSI_FC {                                                      
                        \
-        .name                   = "Interphase 5526 Fibre Channel SCSI 
Adapter",   \
-        .detect                 = iph5526_detect,                  \
-        .release                = iph5526_release,                 \
-        .info                   = iph5526_info,                    \
-        .queuecommand           = iph5526_queuecommand,            \
-       .bios_param             = iph5526_biosparam,               \
-        .can_queue              = IPH5526_CAN_QUEUE,               \
-        .this_id                = -1,                              \
-        .sg_tablesize           = 255,                             \
-        .cmd_per_lun            = 8,                               \
-        .use_clustering         = DISABLE_CLUSTERING,              \
-        .eh_abort_handler       = iph5526_abort,                   \
-        .eh_device_reset_handler = NULL,                            \
-        .eh_bus_reset_handler   = NULL,                            \
-        .eh_host_reset_handler  = NULL,                            \
-}
-
-int iph5526_detect(Scsi_Host_Template *tmpt);
-int iph5526_queuecommand(Scsi_Cmnd *Cmnd, void (*done) (Scsi_Cmnd *));
-int iph5526_release(struct Scsi_Host *host);
-int iph5526_abort(Scsi_Cmnd *Cmnd);
-const char *iph5526_info(struct Scsi_Host *host);
-int iph5526_biosparam(struct Scsi_Disk * disk, struct block_device *n, int 
ip[]);
-
-#endif
-
===== drivers/net/fc/tach.h 1.2 vs edited =====
--- 1.2/drivers/net/fc/tach.h   2002-02-05 08:49:26 +01:00
+++ edited/drivers/net/fc/tach.h        2004-09-06 11:54:16 +02:00
@@ -1,475 +0,0 @@
-/**********************************************************************
- * Defines for the Tachyon Fibre Channel Controller and the Interphase
- * (i)chip TPI. 
- *********************************************************************/
-
-#ifndef _TACH_H
-#define _TACH_H
-
-#define MY_PAGE_SIZE       4096
-#define REPLICATE          0xFF
-#define MAX_NODES          127
-#define BROADCAST          0xFFFFFF
-#define BROADCAST_ADDR     0xFFFFFFFFFFFF
-#define LOGIN_COMPLETED     2
-#define LOGIN_ATTEMPTED     1
-#define LOGIN_NOT_ATTEMPTED 0
-#define TRUE                1
-#define FALSE               0
-
-#define TACHYON_LIMIT       0x01EF
-#define TACHYON_OFFSET      0x200
-
-/* Offsets to the (i) chip */
-#define ICHIP_HW_CONTROL_REG_OFF    (0x080 - TACHYON_OFFSET)
-#define ICHIP_HW_STATUS_REG_OFF     (0x084 - TACHYON_OFFSET)
-#define ICHIP_HW_ADDR_MASK_REG_OFF  (0x090 - TACHYON_OFFSET)
-
-/* (i)chip Hardware Control Register defines */
-#define ICHIP_HCR_RESET         0x01
-#define ICHIP_HCR_DERESET       0x0
-#define ICHIP_HCR_ENABLE_INTA   0x0000003E 
-#define ICHIP_HCR_ENABLE_INTB   0x003E0000
-#define ICHIP_HCR_IWDATA_FIFO   0x800000
-
-/* (i)chip Hardware Status Register defines */
-#define ICHIP_HSR_INT_LATCH     0x02
-
-/* (i)chip Hardware Address Mask Register defines */
-#define ICHIP_HAMR_BYTE_SWAP_ADDR_TR    0x08
-#define ICHIP_HAMR_BYTE_SWAP_NO_ADDR_TR 0x04
-
-/* NOVRAM defines */
-#define IPH5526_NOVRAM_SIZE 64
-
-
-/* Offsets for the registers that correspond to the 
- * Qs on the Tachyon (As defined in the Tachyon Manual).
- */
-
-/* Outbound Command Queue (OCQ).
- */
-#define OCQ_BASE_REGISTER_OFFSET       0x000  
-#define OCQ_LENGTH_REGISTER_OFFSET     0x004
-#define OCQ_PRODUCER_REGISTER_OFFSET   0x008  
-#define OCQ_CONSUMER_REGISTER_OFFSET   0x00C 
-
-/* Inbound Message Queue (IMQ).
- */
-#define IMQ_BASE_REGISTER_OFFSET       0x080
-#define IMQ_LENGTH_REGISTER_OFFSET     0x084
-#define IMQ_CONSUMER_REGISTER_OFFSET   0x088
-#define IMQ_PRODUCER_REGISTER_OFFSET   0x08C
-
-/* Multiframe Sequence Buffer Queue (MFSBQ)
- */
-#define MFSBQ_BASE_REGISTER_OFFSET     0x0C0
-#define MFSBQ_LENGTH_REGISTER_OFFSET   0x0C4
-#define MFSBQ_PRODUCER_REGISTER_OFFSET 0x0C8
-#define MFSBQ_CONSUMER_REGISTER_OFFSET 0x0CC  
-#define MFS_LENGTH_REGISTER_OFFSET     0x0D0
-
-/* Single Frame Sequence Buffer Queue (SFSBQ)
- */
-#define SFSBQ_BASE_REGISTER_OFFSET     0x100
-#define SFSBQ_LENGTH_REGISTER_OFFSET   0x104
-#define SFSBQ_PRODUCER_REGISTER_OFFSET 0x108
-#define SFSBQ_CONSUMER_REGISTER_OFFSET 0x10C  
-#define SFS_LENGTH_REGISTER_OFFSET     0x110
-
-/* SCSI Exchange State Table (SEST)
- */
-#define SEST_BASE_REGISTER_OFFSET      0x140
-#define SEST_LENGTH_REGISTER_OFFSET    0x144
-#define SCSI_LENGTH_REGISTER_OFFSET    0x148
-
-/*  Length of the various Qs 
- */
-#define NO_OF_ENTRIES          8
-#define OCQ_LENGTH             (MY_PAGE_SIZE/32)
-#define IMQ_LENGTH             (MY_PAGE_SIZE/32)
-#define MFSBQ_LENGTH           8
-#define SFSBQ_LENGTH           8
-#define SEST_LENGTH            MY_PAGE_SIZE
-
-/* Size of the various buffers.
- */
-#define TACH_FRAME_SIZE         2048
-#define MFS_BUFFER_SIZE         TACH_FRAME_SIZE
-#define SFS_BUFFER_SIZE         (TACH_FRAME_SIZE + TACHYON_HEADER_LEN)
-#define SEST_BUFFER_SIZE        512
-#define TACH_HEADER_SIZE        64
-#define NO_OF_TACH_HEADERS      ((MY_PAGE_SIZE)/TACH_HEADER_SIZE)
-
-#define NO_OF_FCP_CMNDS         (MY_PAGE_SIZE/32)
-#define SDB_SIZE                2048
-#define NO_OF_SDB_ENTRIES       ((32*MY_PAGE_SIZE)/SDB_SIZE)
-
-
-/* Offsets to the other Tachyon registers.
- * (As defined in the Tachyon manual)
- */
-#define TACHYON_CONFIG_REGISTER_OFFSET          0x184
-#define TACHYON_CONTROL_REGISTER_OFFSET         0x188
-#define TACHYON_STATUS_REGISTER_OFFSET          0x18C
-#define TACHYON_FLUSH_SEST_REGISTER_OFFSET      0x190
-
-/* Defines for the Tachyon Configuration register.
- */
-#define SCSI_ENABLE             0x40000000     
-#define WRITE_STREAM_SIZE       0x800  /* size = 16 */         
-#define READ_STREAM_SIZE        0x300  /* size = 64 */      
-#define PARITY_EVEN             0x2         
-#define OOO_REASSEMBLY_DISABLE  0x40
-
-/* Defines for the Tachyon Control register.
- */
-#define SOFTWARE_RESET 0x80000000
-#define OCQ_RESET      0x4
-#define ERROR_RELEASE  0x2
-
-/* Defines for the Tachyon Status register.
- */
-#define RECEIVE_FIFO_EMPTY      0x10
-#define OSM_FROZEN              0x1
-#define OCQ_RESET_STATUS        0x20
-#define SCSI_FREEZE_STATUS      0x40
-
-
-/* Offsets to the Frame Manager registers.
- */
-#define FMGR_CONFIG_REGISTER_OFFSET 0x1C0
-#define FMGR_CONTROL_REGISTER_OFFSET 0x1C4
-#define FMGR_STATUS_REGISTER_OFFSET 0x1C8
-#define FMGR_TIMER_REGISTER_OFFSET 0x1CC
-#define FMGR_WWN_HI_REGISTER_OFFSET 0x1E0
-#define FMGR_WWN_LO_REGISTER_OFFSET 0x1E4
-#define FMGR_RCVD_ALPA_REGISTER_OFFSET 0x1E8
-
-/* Defines for the Frame Manager Configuration register.
- */
-#define BB_CREDIT                    0x10000
-#define NPORT                        0x8000 
-#define LOOP_INIT_FABRIC_ADDRESS     0x400  
-#define LOOP_INIT_PREVIOUS_ADDRESS   0x200  
-#define LOOP_INIT_SOFT_ADDRESS       0x80  
-
-/* Defines for the Frame Manager Control register.
- */
-#define HOST_CONTROL                 0x02   
-#define EXIT_HOST_CONTROL            0x03  
-#define OFFLINE                      0x05 
-#define INITIALIZE                   0x06 
-#define CLEAR_LF                     0x07
-
-/* Defines for the Frame Manager Status register.
- */
-#define LOOP_UP                 0x80000000
-#define TRANSMIT_PARITY_ERROR   0x40000000
-#define NON_PARTICIPATING       0x20000000
-#define OUT_OF_SYNC             0x02000000
-#define LOSS_OF_SIGNAL          0x01000000
-#define NOS_OLS_RECEIVED        0x00080000
-#define LOOP_STATE_TIMEOUT      0x00040000
-#define LIPF_RECEIVED           0x00020000
-#define BAD_ALPA                0x00010000
-#define LINK_FAILURE            0x00001000
-#define ELASTIC_STORE_ERROR     0x00000400
-#define LINK_UP                 0x00000200
-#define LINK_DOWN               0x00000100
-#define ARBITRATING             0x00000010
-#define ARB_WON                 0x00000020
-#define OPEN                    0x00000030
-#define OPENED                  0x00000040
-#define TX_CLS                  0x00000050
-#define RX_CLS                  0x00000060
-#define TRANSFER                0x00000070
-#define INITIALIZING            0x00000080
-#define LOOP_FAIL               0x000000D0
-#define OLD_PORT                0x000000F0
-#define PORT_STATE_ACTIVE       0x0000000F
-#define PORT_STATE_OFFLINE      0x00000000
-#define PORT_STATE_LF1          0x00000009
-#define PORT_STATE_LF2          0x0000000A
-
-/* Completion Message Types 
- * (defined in P.177 of the Tachyon manual)
- */
-#define OUTBOUND_COMPLETION             0x000
-#define OUTBOUND_COMPLETION_I           0x100
-#define OUT_HI_PRI_COMPLETION           0x001
-#define OUT_HI_PRI_COMPLETION_I         0x101
-#define INBOUND_MFS_COMPLETION          0x102
-#define INBOUND_OOO_COMPLETION          0x003
-#define INBOUND_SFS_COMPLETION          0x104
-#define INBOUND_C1_TIMEOUT              0x105
-#define INBOUND_UNKNOWN_FRAME_I         0x106
-#define INBOUND_BUSIED_FRAME            0x006
-#define SFS_BUF_WARN                    0x107
-#define MFS_BUF_WARN                    0x108
-#define IMQ_BUF_WARN                    0x109
-#define FRAME_MGR_INTERRUPT             0x10A
-#define READ_STATUS                     0x10B
-#define INBOUND_SCSI_DATA_COMPLETION    0x10C
-#define INBOUND_SCSI_COMMAND            0x10D
-#define BAD_SCSI_FRAME                  0x10E
-#define INB_SCSI_STATUS_COMPLETION      0x10F
-
-/* One of the things that we care about when we receive an
- * Outbound Completion Message (OCM).
- */
-#define OCM_TIMEOUT_OR_BAD_ALPA         0x0800
-
-/* Defines for the Tachyon Header structure.
- */
-#define SOFI3                0x70
-#define SOFN3                0xB0
-#define EOFN                 0x5
-
-/* R_CTL */
-#define FC4_DEVICE_DATA      0
-#define EXTENDED_LINK_DATA   0x20000000
-#define FC4_LINK_DATA        0x30000000
-#define BASIC_LINK_DATA      0x80000000
-#define LINK_CONTROL         0xC0000000
-#define SOLICITED_DATA       0x1000000
-#define UNSOLICITED_CONTROL  0x2000000
-#define SOLICITED_CONTROL    0x3000000
-#define UNSOLICITED_DATA     0x4000000
-#define DATA_DESCRIPTOR      0x5000000
-#define UNSOLICITED_COMMAND  0x6000000
-
-#define RCTL_ELS_UCTL          0x22000000
-#define RCTL_ELS_SCTL          0x23000000
-#define RCTL_BASIC_ABTS        0x81000000
-#define RCTL_BASIC_ACC         0x84000000
-#define RCTL_BASIC_RJT         0x85000000
-
-/* TYPE */
-#define TYPE_BLS               0x00000000
-#define TYPE_ELS               0x01000000
-#define TYPE_FC_SERVICES       0x20000000
-#define TYPE_LLC_SNAP          0x05000000
-#define TYPE_FCP               0x08000000
-
-/* F_CTL */
-#define EXCHANGE_RESPONDER     0x800000
-#define SEQUENCE_RESPONDER     0x400000
-#define FIRST_SEQUENCE         0x200000
-#define LAST_SEQUENCE          0x100000
-#define SEQUENCE_INITIATIVE    0x10000
-#define RELATIVE_OFF_PRESENT   0x8
-#define END_SEQUENCE           0x80000
-
-#define TACHYON_HEADER_LEN     32
-#define NW_HEADER_LEN          16
-/* Defines for the Outbound Descriptor Block (ODB).
- */
-#define ODB_CLASS_3          0xC000
-#define ODB_NO_COMP          0x400
-#define ODB_NO_INT           0x200
-#define ODB_EE_CREDIT        0xF
-
-/* Defines for the Extended Descriptor Block (EDB).
- */
-#define EDB_LEN              ((32*MY_PAGE_SIZE)/8) 
-#define EDB_END              0x8000
-#define EDB_FREE             0
-#define EDB_BUSY             1
-
-/* Command Codes */
-#define ELS_LS_RJT          0x01000000
-#define ELS_ACC             0x02000000
-#define ELS_PLOGI           0x03000000
-#define ELS_FLOGI           0x04000000
-#define ELS_LOGO            0x05000000
-#define ELS_TPRLO           0x24000000
-#define ELS_ADISC           0x52000000
-#define ELS_PDISC           0x50000000
-#define ELS_PRLI            0x20000000 
-#define ELS_PRLO            0x21000000
-#define ELS_SCR             0x62000000
-#define ELS_RSCN            0x61000000
-#define ELS_FARP_REQ        0x54000000
-#define ELS_ABTX            0x06000000
-#define ELS_ADVC            0x0D000000
-#define ELS_ECHO            0x10000000
-#define ELS_ESTC            0x0C000000
-#define ELS_ESTS            0x0B000000
-#define ELS_RCS             0x07000000
-#define ELS_RES             0x08000000
-#define ELS_RLS             0x0F000000
-#define ELS_RRQ             0x12000000
-#define ELS_RSS             0x09000000
-#define ELS_RTV             0x0E000000
-#define ELS_RSI             0x0A000000
-#define ELS_TEST            0x11000000
-#define ELS_RNC             0x53000000
-#define ELS_RVCS            0x41000000
-#define ELS_TPLS            0x23000000
-#define ELS_GAID            0x30000000
-#define ELS_FACT            0x31000000
-#define ELS_FAN             0x60000000
-#define ELS_FDACT           0x32000000
-#define ELS_NACT            0x33000000
-#define ELS_NDACT           0x34000000
-#define ELS_QoSR            0x40000000
-#define ELS_FDISC           0x51000000
-
-#define ELS_NS_PLOGI        0x03FFFFFC 
-
-/* LS_RJT reason codes.
- */
-#define INV_LS_CMND_CODE                0x0001
-#define LOGICAL_ERR                     0x0003
-#define LOGICAL_BUSY                    0x0005
-#define PROTOCOL_ERR                    0x0007
-#define UNABLE_TO_PERFORM               0x0009
-#define CMND_NOT_SUPP                   0x000B
-
-/* LS_RJT explanation codes.
- */
-#define NO_EXPLN                        0x0000
-#define RECV_FIELD_SIZE                 0x0700
-#define CONC_SEQ                        0x0900
-#define REQ_NOT_SUPPORTED               0x2C00
-#define INV_PAYLOAD_LEN                 0x2D00
-
-/* Payload Length defines. 
- */
-#define PLOGI_LEN                              116
-
-#define CONCURRENT_SEQUENCES 0x01
-#define RO_INFO_CATEGORY     0xFE
-#define E_D_TOV              0x07D0 /* 2 Secs */
-#define AL_TIME                     0x0010 /* ~15 msec */
-#define TOV_VALUES           (AL_TIME << 16) | E_D_TOV
-#define RT_TOV               0x64   /* 100 msec */
-#define PTP_TOV_VALUES       (RT_TOV << 16) | E_D_TOV
-#define SERVICE_VALID        0x8000
-#define SEQUENCE_DELIVERY       0x0800
-#define CLASS3_CONCURRENT_SEQUENCE    0x01
-#define CLASS3_OPEN_SEQUENCE          0x01
-
-/* These are retrieved from the NOVRAM.
- */
-#define WORLD_WIDE_NAME_LOW     fi->g.my_port_name_low
-#define WORLD_WIDE_NAME_HIGH    fi->g.my_port_name_high
-#define N_PORT_NAME_HIGH        fi->g.my_port_name_high
-#define N_PORT_NAME_LOW         fi->g.my_port_name_low
-#define NODE_NAME_HIGH          fi->g.my_node_name_high
-#define NODE_NAME_LOW           fi->g.my_node_name_low
-
-#define PORT_NAME_LEN           8
-#define NODE_NAME_LEN           8
-
-
-#define PH_VERSION        0x0909
-
-#define LOOP_BB_CREDIT  0x00
-#define PT2PT_BB_CREDIT 0x01
-#define FLOGI_C_F       0x0800 /* Alternate BB_Credit Mgmnt */ 
-#define PLOGI_C_F       0x8800 /* Continuously Increasing + Alternate 
BB_Credit Management */
-
-/* Fabric defines */
-#define DIRECTORY_SERVER        0xFFFFFC
-#define FABRIC_CONTROLLER       0xFFFFFD
-#define F_PORT                  0xFFFFFE
-
-#define FLOGI_DID                              0xFFFE
-#define NS_PLOGI_DID                   0xFFFC
-
-/* Fibre Channel Services defines */
-#define FCS_RFC_4           0x02170000
-#define FCS_GP_ID4          0x01A10000
-#define FCS_ACC             0x8002
-#define FCS_REJECT          0x8001
-
-/* CT Header defines */
-#define FC_CT_REV               0x01000000
-#define DIRECTORY_SERVER_APP    0xFC
-#define NAME_SERVICE            0x02
-
-/* Port Type defines */
-#define PORT_TYPE_IP            0x05000000
-#define PORT_TYPE_NX_PORTS      0x7F000000
-
-/* SCR defines */
-#define FABRIC_DETECTED_REG            0x00000001
-#define N_PORT_DETECTED_REG            0x00000002
-#define FULL_REGISTRATION              0x00000003
-#define CLEAR_REGISTRATION             0x000000FF
-
-/* Command structure has only one byte to address targets 
- */
-#define MAX_SCSI_TARGETS               0xFF 
-
-#define FC_SCSI_READ                    0x80
-#define FC_SCSI_WRITE                   0x81
-#define FC_ELS                          0x01
-#define FC_BLS                          0x00
-#define FC_IP                           0x05
-#define FC_BROADCAST                    0xFF
-
-/* SEST defines.
- */
-#define SEST_V                          0x80000000 /* V = 1 */
-#define INB_SEST_VED                    0xA0000000 /* V = 1, D = 1 */
-#define SEST_INV                        0x7FFFFFFF 
-#define OUTB_SEST_VED                   0x80000000 /* V = 1 */
-#define INV_SEQ_LEN                     0xFFFFFFFF
-#define OUTB_SEST_LINK                  0xFFFF
-
-/* PRLI defines. 
- */
-#define PAGE_LEN                0x100000 /* 3rd byte - 0x10 */
-#define PRLI_LEN                0x0014 /* 20 bytes */
-#define FCP_TYPE_CODE           0x0800 /* FCP-SCSI */
-#define IMAGE_PAIR              0x2000 /* establish image pair */
-#define INITIATOR_FUNC          0x00000020
-#define TARGET_FUNC             0x00000010
-#define READ_XFER_RDY_DISABLED  0x00000002
-
-#define NODE_PROCESS_LOGGED_IN  0x3
-#define NODE_NOT_PRESENT        0x2
-#define NODE_LOGGED_IN          0x1
-#define NODE_LOGGED_OUT         0x0
-
-/* Defines to determine what should be returned when a SCSI frame
- * times out.
- */
-#define FC_SCSI_BAD_TARGET             0xFFFE0000
-
-/* RSCN Address formats */
-#define PORT_ADDRESS_FORMAT             0x00
-#define AREA_ADDRESS_FORMAT             0x01
-#define DOMAIN_ADDRESS_FORMAT           0x02
-
-/* Defines used to determine whether a frame transmission should
- * be indicated by an interrupt or not.
- */
-#define NO_COMP_AND_INT                        0
-#define INT_AND_COMP_REQ               1
-#define NO_INT_COMP_REQ                        2
-
-/* Other junk...
- */
-#define SDB_FREE             0
-#define SDB_BUSY             1
-#define MAX_PENDING_FRAMES   15
-#define RX_ID_FIRST_SEQUENCE 0xFFFF
-#define OX_ID_FIRST_SEQUENCE 0xFFFF
-#define NOT_SCSI_XID            0x8000
-#define MAX_SCSI_XID            0x0FFF /* X_IDs are from 0-4095 */
-#define SCSI_READ_BIT           0x4000 
-#define MAX_SCSI_OXID           0x4FFF
-#define OXID_AVAILABLE          0
-#define OXID_INUSE              1
-#define MAX_SEQ_ID              0xFF
-
-#define INITIATOR             2
-#define TARGET                1
-#define DELETE_ENTRY          1
-#define ADD_ENTRY             2
-
-#endif /* _TACH_H */
===== drivers/net/fc/tach_structs.h 1.2 vs edited =====
--- 1.2/drivers/net/fc/tach_structs.h   2003-02-25 11:44:51 +01:00
+++ edited/drivers/net/fc/tach_structs.h        2004-09-06 11:54:19 +02:00
@@ -1,428 +0,0 @@
-/**********************************************************************
- * iph5526.c: Structures for the Interphase 5526 PCI Fibre Channel 
- *                       IP/SCSI driver.
- * Copyright (C) 1999 Vineet M Abraham <vmabraham@xxxxxxxxxxx>
- **********************************************************************/
-
-#ifndef _TACH_STRUCT_H
-#define _TACH_STRUCT_H
-
-typedef struct {
-       u_short cmnd_code;
-       u_short payload_length;
-       u_short type_code;
-       u_short est_image_pair;
-       u_int originator_pa;
-       u_int responder_pa;
-       u_int service_params;
-} PRLI;
-
-typedef struct {
-       u_int flags_and_byte_offset;
-       u_int byte_count;
-       u_short no_of_recvd_frames;
-       u_short no_of_expected_frames;
-       u_int last_fctl;
-       u_int sdb_address;
-       u_int scratch_pad;
-       u_int expected_ro;
-       u_short buffer_index;
-       u_short buffer_offset;
-       } INB_SEST_ENTRY;
-
-typedef struct {
-       u_int flags_and_did;
-       u_short max_frame_len;
-       u_short cntl;
-       u_int total_seq_length;
-       u_short link;
-       u_short rx_id;
-       u_int transaction_id;
-       u_int header_address;
-       u_char seq_id;
-       u_char reserved;
-       u_short header_length;
-       u_int edb_address;
-       } OUTB_SEST_ENTRY;
-
-typedef struct {
-       u_short d_naa;
-       u_short dest_high;
-       u_int dest_low;
-       u_short s_naa;
-       u_short source_high;
-       u_int source_low;
-       } NW_HEADER;
-
-typedef struct {
-       u_int resv;
-       u_char sof_and_eof;
-       u_char dest_alpa;
-       u_short lcr_and_time_stamp;
-       u_int r_ctl_and_d_id;
-       u_int vc_id_and_s_id;
-       u_int type_and_f_cntl;
-       u_char seq_id;
-       u_char df_cntl;
-       u_short seq_cnt;
-       u_short ox_id;
-       u_short rx_id;
-       u_int ro;
-       NW_HEADER nw_header;
-       } TACHYON_HEADER;
-
-typedef struct {
-       u_short service_options;
-       u_short initiator_ctl;
-       u_short recipient_ctl;
-       u_short recv_data_field_size;
-       u_short concurrent_sequences;
-       u_short n_port_end_to_end_credit;
-       u_short open_seq_per_exchange;
-       u_short resv;
-       }CLASS_OF_SERVICE;
-
-typedef struct {
-       u_int logo_cmnd;
-       u_char reserved;
-       u_char n_port_id_2;
-       u_char n_port_id_1;
-       u_char n_port_id_0;
-       u_int port_name_up;
-       u_int port_name_low;
-       } LOGO;
-
-typedef struct {
-       u_int ls_cmnd_code;
-       u_int hard_address;
-       u_int port_name_high;
-       u_int port_name_low;
-       u_int node_name_high;
-       u_int node_name_low;
-       u_int n_port_id;
-       } ADISC;
-       
-typedef struct {
-       u_int cmnd_code;
-       u_int reason_code;
-       } LS_RJT;
-
-typedef struct {
-       u_int cmnd_code;
-       } ACC;
-
-typedef struct  {
-       u_int seq_d_id;
-       u_int tot_len;
-       u_short cntl;
-       u_short rx_id;
-       u_short cs_enable;
-       u_short cs_seed;
-       u_int trans_id;
-       u_int hdr_addr;
-       u_short frame_len;
-       u_short hdr_len;
-       u_int edb_addr;
-       }ODB;
-
-typedef struct {
-       u_int cmnd_code;
-       u_int reg_function; /* in the last byte */
-       } SCR;
-
-typedef struct {
-       u_int rev_in_id;
-       u_char fs_type;
-       u_char fs_subtype;
-       u_char options;
-       u_char resv1;
-       u_short cmnd_resp_code;
-       u_short max_res_size;
-       u_char resv2;
-       u_char reason_code;
-       u_char expln_code;
-       u_char vendor_unique;
-       } CT_HDR;
-
-typedef struct {
-       CT_HDR   ct_hdr;
-       u_int s_id;
-       u_char bit_map[32]; /* 32 byte bit map */
-       } RFC_4;
-
-typedef struct {
-       u_int ls_cmnd_code;
-       u_short fc_ph_version;
-       u_short buff_to_buff_credit;
-       u_short common_features;
-       u_short recv_data_field_size;
-       u_short n_port_total_conc_seq;
-       u_short rel_off_by_info_cat;
-       u_int ED_TOV;
-       u_int n_port_name_high;
-       u_int n_port_name_low;
-       u_int node_name_high;
-       u_int node_name_low;
-       CLASS_OF_SERVICE c_of_s[3];
-       u_int resv[4];
-       u_int vendor_version_level[4];
-       }LOGIN;
-
-typedef struct {
-       CT_HDR   ct_hdr;
-       u_int port_type; /* in the first byte */
-       } GP_ID4;
-
-typedef struct  {
-       u_int   buf_addr;
-       u_short ehf;
-       u_short buf_len;
-       }EDB;
-
-/* (i)chip Registers */
-struct i_chip_regs {
-       u_int   ptr_ichip_hw_control_reg;
-       u_int   ptr_ichip_hw_status_reg;
-       u_int   ptr_ichip_hw_addr_mask_reg;
-};
-
-struct iph5526_novram {
-       u_int   ptr_novram_hw_control_reg;
-       u_int   ptr_novram_hw_status_reg;
-       u_short data[IPH5526_NOVRAM_SIZE];
-};
-
-/* Tachyon Registers */
-struct tachyon_regs {
-       u_int    ptr_ocq_base_reg;
-       u_int    ptr_ocq_len_reg;
-       u_int    ptr_ocq_prod_indx_reg;
-       u_int    ptr_ocq_cons_indx_reg;
-
-       u_int    ptr_imq_base_reg;
-       u_int    ptr_imq_len_reg;
-       u_int    ptr_imq_cons_indx_reg;
-       u_int    ptr_imq_prod_indx_reg;
-
-       u_int    ptr_mfsbq_base_reg;
-       u_int    ptr_mfsbq_len_reg;
-       u_int    ptr_mfsbq_prod_reg;
-       u_int    ptr_mfsbq_cons_reg;
-       u_int    ptr_mfsbuff_len_reg;
-
-       u_int    ptr_sfsbq_base_reg;
-       u_int    ptr_sfsbq_len_reg;
-       u_int    ptr_sfsbq_prod_reg;
-       u_int    ptr_sfsbq_cons_reg;
-       u_int    ptr_sfsbuff_len_reg;
-
-       u_int    ptr_sest_base_reg;
-       u_int    ptr_sest_len_reg;
-       u_int    ptr_scsibuff_len_reg;
-
-       u_int    ptr_tach_config_reg;
-       u_int    ptr_tach_control_reg;
-       u_int    ptr_tach_status_reg;
-       u_int    ptr_tach_flush_oxid_reg;
-
-       u_int    ptr_fm_config_reg;
-       u_int    ptr_fm_control_reg;
-       u_int    ptr_fm_status_reg;
-       u_int    ptr_fm_tov_reg;
-       u_int    ptr_fm_wwn_hi_reg;
-       u_int    ptr_fm_wwn_low_reg;
-       u_int    ptr_fm_rx_al_pa_reg;
-};
-
-struct globals {
-       u_long tachyon_base;
-       u_int *mem_base;
-       u_short ox_id; /* OX_ID used for IP and ELS frames */
-       u_short scsi_oxid; /* OX_ID for SEST entry */
-       u_char seq_id;
-       u_int my_id;
-       u_int my_ddaa; /* my domain and area in a fabric */
-       volatile u_char loop_up;
-       volatile u_char ptp_up; /* we have a point-to-point link */
-       volatile u_char link_up;
-       volatile u_char n_port_try;
-       volatile u_char nport_timer_set;
-       volatile u_char lport_timer_set;
-       /* Hmmm... We don't want to Initialize while closing */
-       u_char dont_init; 
-       u_int my_node_name_high;
-       u_int my_node_name_low;
-       u_int my_port_name_high;
-       u_int my_port_name_low;
-       u_char fabric_present;
-       u_char explore_fabric;
-       u_char name_server;  
-       u_int my_mtu;
-       u_int *els_buffer[MAX_PENDING_FRAMES]; /* temp space for ELS frames */
-       char *arp_buffer; /* temp space for ARP frames */
-       u_int mfs_buffer_count; /* keep track of MFS buffers used*/
-       u_char scsi_registered;
-       /* variables for port discovery */
-       volatile u_char port_discovery;
-       volatile u_char perform_adisc;
-       u_short alpa_list_index;
-       u_short type_of_frame; /* Could be IP/SCSI Read/SCSI Write*/    
-       u_char no_of_targets; /* used to assign target_ids */
-       u_long sem; /* to synchronize between IP and SCSI */
-       u_char e_i;
-
-       /* the frames */
-       TACHYON_HEADER tach_header;
-       LOGIN login;
-       PRLI prli;
-       LOGO logo;
-       ADISC adisc;
-       LS_RJT ls_rjt;
-       ODB     odb;
-       INB_SEST_ENTRY inb_sest_entry;
-       OUTB_SEST_ENTRY outb_sest_entry;
-       ACC     acc;
-       SCR     scr;
-       EDB     edb;
-       RFC_4 rfc_4;
-       GP_ID4 gp_id4;
-};
-
-struct queue_variables {
-       /* Indices maintained in host memory.
-        */
-       u_int *host_ocq_cons_indx, *host_hpcq_cons_indx, *host_imq_prod_indx;
-       u_int *ptr_host_ocq_cons_indx, *ptr_host_hpcq_cons_indx, 
*ptr_host_imq_prod_indx;
-
-       /* Variables for Outbound Command Queue (OCQ).
-        */
-       u_int *ptr_ocq_base;
-       u_int ocq_len, ocq_end;
-       u_int ocq_prod_indx;
-       u_int *ptr_odb[OCQ_LENGTH];
-
-       /* Variables for Inbound Message Queue (IMQ).
-        */
-       u_int *ptr_imq_base;
-       u_int imq_len, imq_end;
-       u_int imq_cons_indx;
-       u_int imq_prod_indx;
-       u_int *ptr_imqe[IMQ_LENGTH];
-
-       u_int *ptr_mfsbq_base;
-       u_int mfsbq_len, mfsbq_end;
-       u_int mfsbq_prod_indx;
-       u_int mfsbq_cons_indx;
-       u_int mfsbuff_len, mfsbuff_end;
-
-       u_int *ptr_sfsbq_base;
-       u_int sfsbq_len, sfsbq_end;
-       u_int sfsbq_prod_indx;
-       u_int sfsbq_cons_indx;
-       u_int sfsbuff_len, sfsbuff_end;
-       u_int *ptr_sfs_buffers[SFSBQ_LENGTH * NO_OF_ENTRIES];
-
-       /* Tables for SCSI Transactions */
-       u_int *ptr_sest_base;
-       u_int *ptr_sest[SEST_LENGTH];
-       u_char free_scsi_oxid[SEST_LENGTH];
-       u_int *ptr_sdb_base;
-       u_int *ptr_sdb_slot[NO_OF_SDB_ENTRIES];
-       u_char sdb_slot_status[NO_OF_SDB_ENTRIES];
-       u_int sdb_indx;
-       u_int *ptr_fcp_cmnd_base;
-       u_int *ptr_fcp_cmnd[NO_OF_FCP_CMNDS];
-       u_int fcp_cmnd_indx;
-
-       /* Table for data to be transmitted.
-        */
-       u_int *ptr_edb_base;
-       u_int *ptr_edb[EDB_LEN];
-       u_int edb_buffer_indx;
-       volatile u_char free_edb_list[EDB_LEN];
-
-       /* Table of Tachyon Headers.
-        */
-       u_int *ptr_tachyon_header[NO_OF_TACH_HEADERS];
-       u_int *ptr_tachyon_header_base;
-       u_int tachyon_header_indx;
-};
-
-/* Used to match incoming ACCs to ELS requests sent out */
-struct ox_id_els_map {
-       u_short ox_id;
-       u_int els;
-       struct ox_id_els_map *next;
-};
-
-
-/* Carries info about individual nodes... stores the info got at login 
- * time. Also maintains mapping between MAC->FC addresses 
- */
-struct fc_node_info {
-       /* Itz the WWN (8 bytes), the last 6 bytes is the MAC address */
-       u_char hw_addr[PORT_NAME_LEN]; 
-       u_char node_name[NODE_NAME_LEN]; 
-       u_int d_id;  /*real FC address, 3 bytes */
-       int mtu;
-       /* login = 1 if login attempted
-        * login = 2 if login completed 
-        */
-       int login;    
-       u_char scsi; /*  = 1 if device is a SCSI Target */
-       u_char target_id;
-       CLASS_OF_SERVICE c_of_s[3];
-       struct fc_node_info *next;
-};
-
-struct fc_info {
-       char name[8];
-       u_long base_addr;
-       int irq;
-       struct net_device_stats fc_stats;
-       struct fc_node_info *node_info_list;
-       int num_nodes;
-       struct ox_id_els_map *ox_id_list;
-       struct i_chip_regs i_r;
-       struct tachyon_regs t_r;
-       struct queue_variables q;
-       struct globals g;
-       struct iph5526_novram n_r;
-       u_short clone_id;
-       struct timer_list nport_timer;
-       struct timer_list lport_timer;
-       struct timer_list explore_timer;
-       struct timer_list display_cache_timer;
-       struct net_device *dev;
-       struct Scsi_Host *host;
-       spinlock_t fc_lock;
-};
-
-struct iph5526_hostdata {
-       struct fc_info *fi;
-       fcp_cmd cmnd;
-       Scsi_Cmnd *cmnd_handler[SEST_LENGTH];
-       u_int tag_ages[MAX_SCSI_TARGETS];
-};
-
-/* List of valid AL_PAs */
-u_char alpa_list[127] = { 
-       0x00, 0x01, 0x02, 0x04, 0x08, 0x0F, 0x10, 0x17, 
-       0x18, 0x1B, 0x1D, 0x1E, 0x1F, 0x23, 0x25, 0x26, 
-       0x27, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x31, 
-       0x32, 0x33, 0x34, 0x35, 0x36, 0x39, 0x3A, 0x3C, 
-       0x43, 0x45, 0x46, 0x47, 0x49, 0x4A, 0x4B, 0x4C, 
-       0x4D, 0x4E, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 
-       0x59, 0x5A, 0x5C, 0x63, 0x65, 0x66, 0x67, 0x69, 
-       0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x71, 0x72, 0x73, 
-       0x74, 0x75, 0x76, 0x79, 0x7A, 0x7C, 0x80, 0x81, 
-       0x82, 0x84, 0x88, 0x8F, 0x90, 0x97, 0x98, 0x9B, 
-       0x9D, 0x9E, 0x9F, 0xA3, 0xA5, 0xA6, 0xA7, 0xA9, 
-       0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xB1, 0xB2, 0xB3, 
-       0xB4, 0xB5, 0xB6, 0xB9, 0xBA, 0xBC, 0xC3, 0xC5, 
-       0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 
-       0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD9, 0xDA, 
-       0xDC, 0xE0, 0xE1, 0xE2, 0xE4, 0xE8, 0xEF
-};
-
-#endif /* _TACH_STRUCT_H */

<Prev in Thread] Current Thread [Next in Thread>