linux/drivers/scsi/dc395x.c

/*
 * dc395x.c
 *
 * Device Driver for Tekram DC395(U/UW/F), DC315(U)
 * PCI SCSI Bus Master Host Adapter
 * (SCSI chip set used Tekram ASIC TRM-S1040)
 *
 * Authors:
 *  C.L. Huang <[email protected]>
 *  Erich Chen <[email protected]>
 *  (C) Copyright 1995-1999 Tekram Technology Co., Ltd.
 *
 *  Kurt Garloff <[email protected]>
 *  (C) 1999-2000 Kurt Garloff
 *
 *  Oliver Neukum <[email protected]>
 *  Ali Akcaagac <[email protected]>
 *  Jamie Lenehan <[email protected]>
 *  (C) 2003
 *
 * License: GNU GPL
 *
 *************************************************************************
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ************************************************************************
 */
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/delay.h>
#include <linux/ctype.h>
#include <linux/blkdev.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/pci.h>
#include <linux/list.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <asm/io.h>

#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport_spi.h>

#include "dc395x.h"

#define DC395X_NAME
#define DC395X_BANNER
#define DC395X_VERSION

/*---------------------------------------------------------------------------
                                  Features
 ---------------------------------------------------------------------------*/
/*
 * Set to disable parts of the driver
 */
/*#define DC395x_NO_DISCONNECT*/
/*#define DC395x_NO_TAGQ*/
/*#define DC395x_NO_SYNC*/
/*#define DC395x_NO_WIDE*/

/*---------------------------------------------------------------------------
                                  Debugging
 ---------------------------------------------------------------------------*/
/*
 * Types of debugging that can be enabled and disabled
 */
#define DBG_KG
#define DBG_0
#define DBG_1
#define DBG_SG
#define DBG_FIFO
#define DBG_PIO


/*
 * Set set of things to output debugging for.
 * Undefine to remove all debugging
 */
/*#define DEBUG_MASK (DBG_0|DBG_1|DBG_SG|DBG_FIFO|DBG_PIO)*/
/*#define  DEBUG_MASK	DBG_0*/


/*
 * Output a kernel mesage at the specified level and append the
 * driver name and a ": " to the start of the message
 */
#define dprintkl(level, format, arg...)


#ifdef DEBUG_MASK
/*
 * print a debug message - this is formated with KERN_DEBUG, then the
 * driver name followed by a ": " and then the message is output. 
 * This also checks that the specified debug level is enabled before
 * outputing the message
 */
#define dprintkdbg

/*
 * Check if the specified type of debugging is enabled
 */
#define debug_enabled

#else
/*
 * No debugging. Do nothing
 */
#define dprintkdbg(type, format, arg...)
#define debug_enabled(type)

#endif


#ifndef PCI_VENDOR_ID_TEKRAM
#define PCI_VENDOR_ID_TEKRAM
#endif
#ifndef PCI_DEVICE_ID_TEKRAM_TRMS1040
#define PCI_DEVICE_ID_TEKRAM_TRMS1040
#endif


#define DC395x_LOCK_IO(dev,flags)
#define DC395x_UNLOCK_IO(dev,flags)

#define DC395x_read8(acb,address)
#define DC395x_read16(acb,address)
#define DC395x_read32(acb,address)
#define DC395x_write8(acb,address,value)
#define DC395x_write16(acb,address,value)
#define DC395x_write32(acb,address,value)

#define TAG_NONE

/*
 * srb->segement_x is the hw sg list. It is always allocated as a
 * DC395x_MAX_SG_LISTENTRY entries in a linear block which does not
 * cross a page boundy.
 */
#define SEGMENTX_LEN


struct SGentry {};

/* The SEEPROM structure for TRM_S1040 */
struct NVRamTarget {};

struct NvRamType {};

struct ScsiReqBlk {};

struct DeviceCtlBlk {};

struct AdapterCtlBlk {};


/*---------------------------------------------------------------------------
                            Forward declarations
 ---------------------------------------------------------------------------*/
static void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status);
static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status);
static void command_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status);
static void status_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status);
static void msgout_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status);
static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status);
static void data_out_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status);
static void data_in_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status);
static void command_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status);
static void status_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status);
static void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status);
static void msgin_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status);
static void nop0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status);
static void nop1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, 
		u16 *pscsi_status);
static void set_basic_config(struct AdapterCtlBlk *acb);
static void cleanup_after_transfer(struct AdapterCtlBlk *acb,
		struct ScsiReqBlk *srb);
static void reset_scsi_bus(struct AdapterCtlBlk *acb);
static void data_io_transfer(struct AdapterCtlBlk *acb,
		struct ScsiReqBlk *srb, u16 io_dir);
static void disconnect(struct AdapterCtlBlk *acb);
static void reselect(struct AdapterCtlBlk *acb);
static u8 start_scsi(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
		struct ScsiReqBlk *srb);
static inline void enable_msgout_abort(struct AdapterCtlBlk *acb,
		struct ScsiReqBlk *srb);
static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
		struct ScsiReqBlk *srb);
static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_code,
		struct scsi_cmnd *cmd, u8 force);
static void scsi_reset_detect(struct AdapterCtlBlk *acb);
static void pci_unmap_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb);
static void pci_unmap_srb_sense(struct AdapterCtlBlk *acb,
		struct ScsiReqBlk *srb);
static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
		struct ScsiReqBlk *srb);
static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
		struct ScsiReqBlk *srb);
static void set_xfer_rate(struct AdapterCtlBlk *acb,
		struct DeviceCtlBlk *dcb);
static void waiting_timeout(struct timer_list *t);


/*---------------------------------------------------------------------------
                                 Static Data
 ---------------------------------------------------------------------------*/
static u16 current_sync_offset =;

static void *dc395x_scsi_phase0[] =;

static void *dc395x_scsi_phase1[] =;

/*
 *Fast20:	000	 50ns, 20.0 MHz
 *		001	 75ns, 13.3 MHz
 *		010	100ns, 10.0 MHz
 *		011	125ns,  8.0 MHz
 *		100	150ns,  6.6 MHz
 *		101	175ns,  5.7 MHz
 *		110	200ns,  5.0 MHz
 *		111	250ns,  4.0 MHz
 *
 *Fast40(LVDS):	000	 25ns, 40.0 MHz
 *		001	 50ns, 20.0 MHz
 *		010	 75ns, 13.3 MHz
 *		011	100ns, 10.0 MHz
 *		100	125ns,  8.0 MHz
 *		101	150ns,  6.6 MHz
 *		110	175ns,  5.7 MHz
 *		111	200ns,  5.0 MHz
 */
/*static u8	clock_period[] = {12,19,25,31,37,44,50,62};*/

/* real period:48ns,76ns,100ns,124ns,148ns,176ns,200ns,248ns */
static u8 clock_period[] =;
static u16 clock_speed[] =;


/*---------------------------------------------------------------------------
                                Configuration
  ---------------------------------------------------------------------------*/
/*
 * Module/boot parameters currently effect *all* instances of the
 * card in the system.
 */

/*
 * Command line parameters are stored in a structure below.
 * These are the index's into the structure for the various
 * command line options.
 */
#define CFG_ADAPTER_ID
#define CFG_MAX_SPEED
#define CFG_DEV_MODE
#define CFG_ADAPTER_MODE
#define CFG_TAGS
#define CFG_RESET_DELAY

#define CFG_NUM


/*
 * Value used to indicate that a command line override
 * hasn't been used to modify the value.
 */
#define CFG_PARAM_UNSET


/*
 * Hold command line parameters.
 */
struct ParameterData {};
static struct ParameterData cfg_data[] =;


/*
 * Safe settings. If set to zero the BIOS/default values with
 * command line overrides will be used. If set to 1 then safe and
 * slow settings will be used.
 */
static bool use_safe_settings =;
module_param_named(safe, use_safe_settings, bool, 0);
MODULE_PARM_DESC();


module_param_named(adapter_id, cfg_data[CFG_ADAPTER_ID].value, int, 0);
MODULE_PARM_DESC();

module_param_named(max_speed, cfg_data[CFG_MAX_SPEED].value, int, 0);
MODULE_PARM_DESC();

module_param_named(dev_mode, cfg_data[CFG_DEV_MODE].value, int, 0);
MODULE_PARM_DESC();

module_param_named(adapter_mode, cfg_data[CFG_ADAPTER_MODE].value, int, 0);
MODULE_PARM_DESC();

module_param_named(tags, cfg_data[CFG_TAGS].value, int, 0);
MODULE_PARM_DESC();

module_param_named(reset_delay, cfg_data[CFG_RESET_DELAY].value, int, 0);
MODULE_PARM_DESC();


/**
 * set_safe_settings - if the use_safe_settings option is set then
 * set all values to the safe and slow values.
 **/
static void set_safe_settings(void)
{}


/**
 * fix_settings - reset any boot parameters which are out of range
 * back to the default values.
 **/
static void fix_settings(void)
{}



/*
 * Mapping from the eeprom delay index value (index into this array)
 * to the number of actual seconds that the delay should be for.
 */
static char eeprom_index_to_delay_map[] =;


/**
 * eeprom_index_to_delay - Take the eeprom delay setting and convert it
 * into a number of seconds.
 *
 * @eeprom: The eeprom structure in which we find the delay index to map.
 **/
static void eeprom_index_to_delay(struct NvRamType *eeprom)
{}


/**
 * delay_to_eeprom_index - Take a delay in seconds and return the
 * closest eeprom index which will delay for at least that amount of
 * seconds.
 *
 * @delay: The delay, in seconds, to find the eeprom index for.
 **/
static int delay_to_eeprom_index(int delay)
{}


/**
 * eeprom_override - Override the eeprom settings, in the provided
 * eeprom structure, with values that have been set on the command
 * line.
 *
 * @eeprom: The eeprom data to override with command line options.
 **/
static void eeprom_override(struct NvRamType *eeprom)
{}


/*---------------------------------------------------------------------------
 ---------------------------------------------------------------------------*/

static unsigned int list_size(struct list_head *head)
{}


static struct DeviceCtlBlk *dcb_get_next(struct list_head *head,
		struct DeviceCtlBlk *pos)
{}


static void free_tag(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
{}


/* Find cmd in SRB list */
static inline struct ScsiReqBlk *find_cmd(struct scsi_cmnd *cmd,
		struct list_head *head)
{}

/* Sets the timer to wake us up */
static void waiting_set_timer(struct AdapterCtlBlk *acb, unsigned long to)
{}


/* Send the next command from the waiting list to the bus */
static void waiting_process_next(struct AdapterCtlBlk *acb)
{}


/* Wake up waiting queue */
static void waiting_timeout(struct timer_list *t)
{}


/* Get the DCB for a given ID/LUN combination */
static struct DeviceCtlBlk *find_dcb(struct AdapterCtlBlk *acb, u8 id, u8 lun)
{}


/* Send SCSI Request Block (srb) to adapter (acb) */
static void send_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
{}

/* Prepare SRB for being sent to Device DCB w/ command *cmd */
static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
		struct ScsiReqBlk *srb)
{}


/**
 * dc395x_queue_command_lck - queue scsi command passed from the mid
 * layer, invoke 'done' on completion
 *
 * @cmd: pointer to scsi command object
 *
 * Returns 1 if the adapter (host) is busy, else returns 0. One
 * reason for an adapter to be busy is that the number
 * of outstanding queued commands is already equal to
 * struct Scsi_Host::can_queue .
 *
 * Required: if struct Scsi_Host::can_queue is ever non-zero
 *           then this function is required.
 *
 * Locks: struct Scsi_Host::host_lock held on entry (with "irqsave")
 *        and is expected to be held on return.
 *
 */
static int dc395x_queue_command_lck(struct scsi_cmnd *cmd)
{}

static DEF_SCSI_QCMD(dc395x_queue_command)

static void dump_register_info(struct AdapterCtlBlk *acb,
		struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
{}


static inline void clear_fifo(struct AdapterCtlBlk *acb, char *txt)
{}


static void reset_dev_param(struct AdapterCtlBlk *acb)
{}


/*
 * perform a hard reset on the SCSI bus
 * @cmd - some command for this host (for fetching hooks)
 * Returns: SUCCESS (0x2002) on success, else FAILED (0x2003).
 */
static int __dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
{}

static int dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
{}

/*
 * abort an errant SCSI command
 * @cmd - command to be aborted
 * Returns: SUCCESS (0x2002) on success, else FAILED (0x2003).
 */
static int dc395x_eh_abort(struct scsi_cmnd *cmd)
{}


/* SDTR */
static void build_sdtr(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
		struct ScsiReqBlk *srb)
{}


/* WDTR */
static void build_wdtr(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
		struct ScsiReqBlk *srb)
{}


#if 0
/* Timer to work around chip flaw: When selecting and the bus is 
 * busy, we sometimes miss a Selection timeout IRQ */
void selection_timeout_missed(unsigned long ptr);
/* Sets the timer to wake us up */
static void selto_timer(struct AdapterCtlBlk *acb)
{
	if (timer_pending(&acb->selto_timer))
		return;
	acb->selto_timer.function = selection_timeout_missed;
	acb->selto_timer.data = (unsigned long) acb;
	if (time_before
	    (jiffies + HZ, acb->last_reset + HZ / 2))
		acb->selto_timer.expires =
		    acb->last_reset + HZ / 2 + 1;
	else
		acb->selto_timer.expires = jiffies + HZ + 1;
	add_timer(&acb->selto_timer);
}


void selection_timeout_missed(unsigned long ptr)
{
	unsigned long flags;
	struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)ptr;
	struct ScsiReqBlk *srb;
	dprintkl(KERN_DEBUG, "Chip forgot to produce SelTO IRQ!\n");
	if (!acb->active_dcb || !acb->active_dcb->active_srb) {
		dprintkl(KERN_DEBUG, "... but no cmd pending? Oops!\n");
		return;
	}
	DC395x_LOCK_IO(acb->scsi_host, flags);
	srb = acb->active_dcb->active_srb;
	disconnect(acb);
	DC395x_UNLOCK_IO(acb->scsi_host, flags);
}
#endif


static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb,
		struct ScsiReqBlk* srb)
{}


#define DC395x_ENABLE_MSGOUT


/* abort command */
static inline void enable_msgout_abort(struct AdapterCtlBlk *acb,
		struct ScsiReqBlk *srb)
{}


/**
 * dc395x_handle_interrupt - Handle an interrupt that has been confirmed to
 *                           have been triggered for this card.
 *
 * @acb:	 a pointer to the adpter control block
 * @scsi_status: the status return when we checked the card
 **/
static void dc395x_handle_interrupt(struct AdapterCtlBlk *acb,
		u16 scsi_status)
{}


static irqreturn_t dc395x_interrupt(int irq, void *dev_id)
{}


static void msgout_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status)
{}


static void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status)
{}


static void command_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status)
{}


static void command_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status)
{}


/*
 * Verify that the remaining space in the hw sg lists is the same as
 * the count of remaining bytes in srb->total_xfer_length
 */
static void sg_verify_length(struct ScsiReqBlk *srb)
{}


/*
 * Compute the next Scatter Gather list index and adjust its length
 * and address if necessary
 */
static void sg_update_list(struct ScsiReqBlk *srb, u32 left)
{}


/*
 * We have transferred a single byte (PIO mode?) and need to update
 * the count of bytes remaining (total_xfer_length) and update the sg
 * entry to either point to next byte in the current sg entry, or of
 * already at the end to point to the start of the next sg entry
 */
static void sg_subtract_one(struct ScsiReqBlk *srb)
{}


/* 
 * cleanup_after_transfer
 * 
 * Makes sure, DMA and SCSI engine are empty, after the transfer has finished
 * KG: Currently called from  StatusPhase1 ()
 * Should probably also be called from other places
 * Best might be to call it in DataXXPhase0, if new phase will differ 
 */
static void cleanup_after_transfer(struct AdapterCtlBlk *acb,
		struct ScsiReqBlk *srb)
{}


/*
 * Those no of bytes will be transferred w/ PIO through the SCSI FIFO
 * Seems to be needed for unknown reasons; could be a hardware bug :-(
 */
#define DC395x_LASTPIO


static void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status)
{}


static void data_out_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status)
{}

static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status)
{}


static void data_in_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status)
{}


static void data_io_transfer(struct AdapterCtlBlk *acb, 
		struct ScsiReqBlk *srb, u16 io_dir)
{}


static void status_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status)
{}


static void status_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status)
{}


/* Check if the message is complete */
static inline u8 msgin_completed(u8 * msgbuf, u32 len)
{}

/* reject_msg */
static inline void msgin_reject(struct AdapterCtlBlk *acb,
		struct ScsiReqBlk *srb)
{}


static struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb,
		struct DeviceCtlBlk *dcb, u8 tag)
{}


static inline void reprogram_regs(struct AdapterCtlBlk *acb,
		struct DeviceCtlBlk *dcb)
{}


/* set async transfer mode */
static void msgin_set_async(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
{}


/* set sync transfer mode */
static void msgin_set_sync(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
{}


static inline void msgin_set_nowide(struct AdapterCtlBlk *acb,
		struct ScsiReqBlk *srb)
{}

static void msgin_set_wide(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
{}


/*
 * extended message codes:
 *
 *	code	description
 *
 *	02h	Reserved
 *	00h	MODIFY DATA  POINTER
 *	01h	SYNCHRONOUS DATA TRANSFER REQUEST
 *	03h	WIDE DATA TRANSFER REQUEST
 *   04h - 7Fh	Reserved
 *   80h - FFh	Vendor specific
 */
static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status)
{}


static void msgin_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status)
{}


static void nop0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status)
{}


static void nop1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
		u16 *pscsi_status)
{}


static void set_xfer_rate(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb)
{}


static void disconnect(struct AdapterCtlBlk *acb)
{}


static void reselect(struct AdapterCtlBlk *acb)
{}


static inline u8 tagq_blacklist(char *name)
{}


static void disc_tagq_set(struct DeviceCtlBlk *dcb, struct ScsiInqData *ptr)
{}


static void add_dev(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
		struct ScsiInqData *ptr)
{}


/* unmap mapped pci regions from SRB */
static void pci_unmap_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
{}


/* unmap mapped pci sense buffer from SRB */
static void pci_unmap_srb_sense(struct AdapterCtlBlk *acb,
		struct ScsiReqBlk *srb)
{}


/*
 * Complete execution of a SCSI command
 * Signal completion to the generic SCSI driver  
 */
static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
		struct ScsiReqBlk *srb)
{}


/* abort all cmds in our queues */
static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
		struct scsi_cmnd *cmd, u8 force)
{}


static void reset_scsi_bus(struct AdapterCtlBlk *acb)
{}


static void set_basic_config(struct AdapterCtlBlk *acb)
{}


static void scsi_reset_detect(struct AdapterCtlBlk *acb)
{}


static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
		struct ScsiReqBlk *srb)
{}


/**
 * device_alloc - Allocate a new device instance. This create the
 * devices instance and sets up all the data items. The adapter
 * instance is required to obtain confiuration information for this
 * device. This does *not* add this device to the adapters device
 * list.
 *
 * @acb: The adapter to obtain configuration information from.
 * @target: The target for the new device.
 * @lun: The lun for the new device.
 *
 * Return the new device if successful or NULL on failure.
 **/
static struct DeviceCtlBlk *device_alloc(struct AdapterCtlBlk *acb,
		u8 target, u8 lun)
{}


/**
 * adapter_add_device - Adds the device instance to the adaptor instance.
 *
 * @acb: The adapter device to be updated
 * @dcb: A newly created and initialised device instance to add.
 **/
static void adapter_add_device(struct AdapterCtlBlk *acb,
		struct DeviceCtlBlk *dcb)
{}


/**
 * adapter_remove_device - Removes the device instance from the adaptor
 * instance. The device instance is not check in any way or freed by this. 
 * The caller is expected to take care of that. This will simply remove the
 * device from the adapters data strcutures.
 *
 * @acb: The adapter device to be updated
 * @dcb: A device that has previously been added to the adapter.
 **/
static void adapter_remove_device(struct AdapterCtlBlk *acb,
		struct DeviceCtlBlk *dcb)
{}


/**
 * adapter_remove_and_free_device - Removes a single device from the adapter
 * and then frees the device information.
 *
 * @acb: The adapter device to be updated
 * @dcb: A device that has previously been added to the adapter.
 */
static void adapter_remove_and_free_device(struct AdapterCtlBlk *acb,
		struct DeviceCtlBlk *dcb)
{}


/**
 * adapter_remove_and_free_all_devices - Removes and frees all of the
 * devices associated with the specified adapter.
 *
 * @acb: The adapter from which all devices should be removed.
 **/
static void adapter_remove_and_free_all_devices(struct AdapterCtlBlk* acb)
{}


/**
 * dc395x_slave_alloc - Called by the scsi mid layer to tell us about a new
 * scsi device that we need to deal with. We allocate a new device and then
 * insert that device into the adapters device list.
 *
 * @scsi_device: The new scsi device that we need to handle.
 **/
static int dc395x_slave_alloc(struct scsi_device *scsi_device)
{}


/**
 * dc395x_slave_destroy - Called by the scsi mid layer to tell us about a
 * device that is going away.
 *
 * @scsi_device: The new scsi device that we need to handle.
 **/
static void dc395x_slave_destroy(struct scsi_device *scsi_device)
{}




/**
 * trms1040_wait_30us: wait for 30 us
 *
 * Waits for 30us (using the chip by the looks of it..)
 *
 * @io_port: base I/O address
 **/
static void trms1040_wait_30us(unsigned long io_port)
{}


/**
 * trms1040_write_cmd - write the secified command and address to
 * chip
 *
 * @io_port:	base I/O address
 * @cmd:	SB + op code (command) to send
 * @addr:	address to send
 **/
static void trms1040_write_cmd(unsigned long io_port, u8 cmd, u8 addr)
{}


/**
 * trms1040_set_data - store a single byte in the eeprom
 *
 * Called from write all to write a single byte into the SSEEPROM
 * Which is done one bit at a time.
 *
 * @io_port:	base I/O address
 * @addr:	offset into EEPROM
 * @byte:	bytes to write
 **/
static void trms1040_set_data(unsigned long io_port, u8 addr, u8 byte)
{}


/**
 * trms1040_write_all - write 128 bytes to the eeprom
 *
 * Write the supplied 128 bytes to the chips SEEPROM
 *
 * @eeprom:	the data to write
 * @io_port:	the base io port
 **/
static void trms1040_write_all(struct NvRamType *eeprom, unsigned long io_port)
{}


/**
 * trms1040_get_data - get a single byte from the eeprom
 *
 * Called from read all to read a single byte into the SSEEPROM
 * Which is done one bit at a time.
 *
 * @io_port:	base I/O address
 * @addr:	offset into SEEPROM
 *
 * Returns the byte read.
 **/
static u8 trms1040_get_data(unsigned long io_port, u8 addr)
{}


/**
 * trms1040_read_all - read all bytes from the eeprom
 *
 * Read the 128 bytes from the SEEPROM.
 *
 * @eeprom:	where to store the data
 * @io_port:	the base io port
 **/
static void trms1040_read_all(struct NvRamType *eeprom, unsigned long io_port)
{}



/**
 * check_eeprom - get and check contents of the eeprom
 *
 * Read seeprom 128 bytes into the memory provider in eeprom.
 * Checks the checksum and if it's not correct it uses a set of default
 * values.
 *
 * @eeprom:	caller allocated strcuture to read the eeprom data into
 * @io_port:	io port to read from
 **/
static void check_eeprom(struct NvRamType *eeprom, unsigned long io_port)
{}


/**
 * print_eeprom_settings - output the eeprom settings
 * to the kernel log so people can see what they were.
 *
 * @eeprom: The eeprom data strucutre to show details for.
 **/
static void print_eeprom_settings(struct NvRamType *eeprom)
{}


/* Free SG tables */
static void adapter_sg_tables_free(struct AdapterCtlBlk *acb)
{}


/*
 * Allocate SG tables; as we have to pci_map them, an SG list (struct SGentry*)
 * should never cross a page boundary */
static int adapter_sg_tables_alloc(struct AdapterCtlBlk *acb)
{}



/**
 * adapter_print_config - print adapter connection and termination
 * config
 *
 * The io port in the adapter needs to have been set before calling
 * this function.
 *
 * @acb: The adapter to print the information for.
 **/
static void adapter_print_config(struct AdapterCtlBlk *acb)
{}


/**
 * adapter_init_params - Initialize the various parameters in the
 * adapter structure. Note that the pointer to the scsi_host is set
 * early (when this instance is created) and the io_port and irq
 * values are set later after they have been reserved. This just gets
 * everything set to a good starting position.
 *
 * The eeprom structure in the adapter needs to have been set before
 * calling this function.
 *
 * @acb: The adapter to initialize.
 **/
static void adapter_init_params(struct AdapterCtlBlk *acb)
{}


/**
 * adapter_init_scsi_host - Initialize the scsi host instance based on
 * values that we have already stored in the adapter instance. There's
 * some mention that a lot of these are deprecated, so we won't use
 * them (we'll use the ones in the adapter instance) but we'll fill
 * them in in case something else needs them.
 *
 * The eeprom structure, irq and io ports in the adapter need to have
 * been set before calling this function.
 *
 * @host: The scsi host instance to fill in the values for.
 **/
static void adapter_init_scsi_host(struct Scsi_Host *host)
{}


/**
 * adapter_init_chip - Get the chip into a know state and figure out
 * some of the settings that apply to this adapter.
 *
 * The io port in the adapter needs to have been set before calling
 * this function. The config will be configured correctly on return.
 *
 * @acb: The adapter which we are to init.
 **/
static void adapter_init_chip(struct AdapterCtlBlk *acb)
{}


/**
 * adapter_init - Grab the resource for the card, setup the adapter
 * information, set the card into a known state, create the various
 * tables etc etc. This basically gets all adapter information all up
 * to date, initialised and gets the chip in sync with it.
 *
 * @acb:	The adapter which we are to init.
 * @io_port:	The base I/O port
 * @io_port_len: The I/O port size
 * @irq:	IRQ
 *
 * Returns 0 if the initialization succeeds, any other value on
 * failure.
 **/
static int adapter_init(struct AdapterCtlBlk *acb, unsigned long io_port,
			u32 io_port_len, unsigned int irq)
{}


/**
 * adapter_uninit_chip - cleanly shut down the scsi controller chip,
 * stopping all operations and disabling interrupt generation on the
 * card.
 *
 * @acb: The adapter which we are to shutdown.
 **/
static void adapter_uninit_chip(struct AdapterCtlBlk *acb)
{}



/**
 * adapter_uninit - Shut down the chip and release any resources that
 * we had allocated. Once this returns the adapter should not be used
 * anymore.
 *
 * @acb: The adapter which we are to un-initialize.
 **/
static void adapter_uninit(struct AdapterCtlBlk *acb)
{}


#undef YESNO
#define YESNO(YN)

static int dc395x_show_info(struct seq_file *m, struct Scsi_Host *host)
{}


static const struct scsi_host_template dc395x_driver_template =;


/**
 * banner_display - Display banner on first instance of driver
 * initialized.
 **/
static void banner_display(void)
{}


/**
 * dc395x_init_one - Initialise a single instance of the adapter.
 *
 * The PCI layer will call this once for each instance of the adapter
 * that it finds in the system. The pci_dev strcuture indicates which
 * instance we are being called from.
 * 
 * @dev: The PCI device to initialize.
 * @id: Looks like a pointer to the entry in our pci device table
 * that was actually matched by the PCI subsystem.
 *
 * Returns 0 on success, or an error code (-ve) on failure.
 **/
static int dc395x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{}


/**
 * dc395x_remove_one - Called to remove a single instance of the
 * adapter.
 *
 * @dev: The PCI device to initialize.
 **/
static void dc395x_remove_one(struct pci_dev *dev)
{}


static struct pci_device_id dc395x_pci_table[] =;
MODULE_DEVICE_TABLE(pci, dc395x_pci_table);


static struct pci_driver dc395x_driver =;
module_pci_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();