linux/drivers/scsi/a100u2w.c

/*
 * Initio A100 device driver for Linux.
 *
 * Copyright (c) 1994-1998 Initio Corporation
 * Copyright (c) 2003-2004 Christoph Hellwig
 * All rights reserved.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
 */

/*
 * Revision History:
 * 07/02/98 hl	- v.91n Initial drivers.
 * 09/14/98 hl - v1.01 Support new Kernel.
 * 09/22/98 hl - v1.01a Support reset.
 * 09/24/98 hl - v1.01b Fixed reset.
 * 10/05/98 hl - v1.02 split the source code and release.
 * 12/19/98 bv - v1.02a Use spinlocks for 2.1.95 and up
 * 01/31/99 bv - v1.02b Use mdelay instead of waitForPause
 * 08/08/99 bv - v1.02c Use waitForPause again.
 * 06/25/02 Doug Ledford <[email protected]> - v1.02d
 *          - Remove limit on number of controllers
 *          - Port to DMA mapping API
 *          - Clean up interrupt handler registration
 *          - Fix memory leaks
 *          - Fix allocation of scsi host structs and private data
 * 11/18/03 Christoph Hellwig <[email protected]>
 *	    - Port to new probing API
 *	    - Fix some more leaks in init failure cases
 * 9/28/04 Christoph Hellwig <[email protected]>
 *	    - merge the two source files
 *	    - remove internal queueing code
 * 14/06/07 Alan Cox <[email protected]>
 *	 - Grand cleanup and Linuxisation
 */

#include <linux/module.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/spinlock.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/dma-mapping.h>

#include <asm/io.h>
#include <asm/irq.h>

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

#include "a100u2w.h"


static struct orc_scb *__orc_alloc_scb(struct orc_host * host);
static void inia100_scb_handler(struct orc_host *host, struct orc_scb *scb);

static struct orc_nvram nvram, *nvramp =;

static u8 default_nvram[64] =;


static u8 wait_chip_ready(struct orc_host * host)
{}

static u8 wait_firmware_ready(struct orc_host * host)
{}

/***************************************************************************/
static u8 wait_scsi_reset_done(struct orc_host * host)
{}

/***************************************************************************/
static u8 wait_HDO_off(struct orc_host * host)
{}

/***************************************************************************/
static u8 wait_hdi_set(struct orc_host * host, u8 * data)
{}

/***************************************************************************/
static unsigned short orc_read_fwrev(struct orc_host * host)
{}

/***************************************************************************/
static u8 orc_nv_write(struct orc_host * host, unsigned char address, unsigned char value)
{}

/***************************************************************************/
static u8 orc_nv_read(struct orc_host * host, u8 address, u8 *ptr)
{}

/**
 *	orc_exec_scb		-	Queue an SCB with the HA
 *	@host: host adapter the SCB belongs to
 *	@scb: SCB to queue for execution
 */

static void orc_exec_scb(struct orc_host * host, struct orc_scb * scb)
{}


/**
 *	se2_rd_all	-	read SCSI parameters from EEPROM
 *	@host: Host whose EEPROM is being loaded
 *
 *	Read SCSI H/A configuration parameters from serial EEPROM
 */

static int se2_rd_all(struct orc_host * host)
{}

/**
 *	se2_update_all		-	update the EEPROM
 *	@host: Host whose EEPROM is being updated
 *
 *	Update changed bytes in the EEPROM image.
 */

static void se2_update_all(struct orc_host * host)
{}

/**
 *	read_eeprom		-	load EEPROM
 *	@host: Host EEPROM to read
 *
 *	Read the EEPROM for a given host. If it is invalid or fails
 *	the restore the defaults and use them.
 */

static void read_eeprom(struct orc_host * host)
{}


/**
 *	orc_load_firmware	-	initialise firmware
 *	@host: Host to set up
 *
 *	Load the firmware from the EEPROM into controller SRAM. This
 *	is basically a 4K block copy and then a 4K block read to check
 *	correctness. The rest is convulted by the indirect interfaces
 *	in the hardware
 */

static u8 orc_load_firmware(struct orc_host * host)
{}

/***************************************************************************/
static void setup_SCBs(struct orc_host * host)
{}

/**
 *	init_alloc_map		-	initialise allocation map
 *	@host: host map to configure
 *
 *	Initialise the allocation maps for this device. If the device
 *	is not quiescent the caller must hold the allocation lock
 */

static void init_alloc_map(struct orc_host * host)
{}

/**
 *	init_orchid		-	initialise the host adapter
 *	@host:host adapter to initialise
 *
 *	Initialise the controller and if necessary load the firmware.
 *
 *	Returns -1 if the initialisation fails.
 */

static int init_orchid(struct orc_host * host)
{}

/**
 *	orc_reset_scsi_bus		-	perform bus reset
 *	@host: host being reset
 *
 *	Perform a full bus reset on the adapter.
 */

static int orc_reset_scsi_bus(struct orc_host * host)
{}

/**
 *	orc_device_reset	-	device reset handler
 *	@host: host to reset
 *	@cmd: command causing the reset
 *	@target: target device
 *
 *	Reset registers, reset a hanging bus and kill active and disconnected
 *	commands for target w/o soft reset
 */

static int orc_device_reset(struct orc_host * host, struct scsi_cmnd *cmd, unsigned int target)
{}

/**
 *	__orc_alloc_scb		-		allocate an SCB
 *	@host: host to allocate from
 *
 *	Allocate an SCB and return a pointer to the SCB object. NULL
 *	is returned if no SCB is free. The caller must already hold
 *	the allocator lock at this point.
 */


static struct orc_scb *__orc_alloc_scb(struct orc_host * host)
{}

/**
 *	orc_alloc_scb		-		allocate an SCB
 *	@host: host to allocate from
 *
 *	Allocate an SCB and return a pointer to the SCB object. NULL
 *	is returned if no SCB is free.
 */

static struct orc_scb *orc_alloc_scb(struct orc_host * host)
{}

/**
 *	orc_release_scb			-	release an SCB
 *	@host: host owning the SCB
 *	@scb: SCB that is now free
 *
 *	Called to return a completed SCB to the allocation pool. Before
 *	calling the SCB must be out of use on both the host and the HA.
 */

static void orc_release_scb(struct orc_host *host, struct orc_scb *scb)
{}

/*
 *	orchid_abort_scb	-	abort a command
 *
 *	Abort a queued command that has been passed to the firmware layer
 *	if possible. This is all handled by the firmware. We aks the firmware
 *	and it either aborts the command or fails
 */

static int orchid_abort_scb(struct orc_host * host, struct orc_scb * scb)
{}

static int inia100_abort_cmd(struct orc_host * host, struct scsi_cmnd *cmd)
{}

/**
 *	orc_interrupt		-	IRQ processing
 *	@host: Host causing the interrupt
 *
 *	This function is called from the IRQ handler and protected
 *	by the host lock. While the controller reports that there are
 *	scb's for processing we pull them off the controller, turn the
 *	index into a host address pointer to the scb and call the scb
 *	handler.
 *
 *	Returns IRQ_HANDLED if any SCBs were processed, IRQ_NONE otherwise
 */

static irqreturn_t orc_interrupt(struct orc_host * host)
{}				/* End of I1060Interrupt() */

/**
 *	inia100_build_scb	-	build SCB
 *	@host: host owing the control block
 *	@scb: control block to use
 *	@cmd: Mid layer command
 *
 *	Build a host adapter control block from the SCSI mid layer command
 */

static int inia100_build_scb(struct orc_host * host, struct orc_scb * scb, struct scsi_cmnd * cmd)
{}

/**
 *	inia100_queue_lck		-	queue command with host
 *	@cmd: Command block
 *
 *	Called by the mid layer to queue a command. Process the command
 *	block, build the host specific scb structures and if there is room
 *	queue the command down to the controller
 */
static int inia100_queue_lck(struct scsi_cmnd *cmd)
{}

static DEF_SCSI_QCMD(inia100_queue)

/*****************************************************************************
 Function name  : inia100_abort
 Description    : Abort a queued command.
	                 (commands that are on the bus can't be aborted easily)
 Input          : host  -       Pointer to host adapter structure
 Output         : None.
 Return         : pSRB  -       Pointer to SCSI request block.
*****************************************************************************/
static int inia100_abort(struct scsi_cmnd * cmd)
{}

/*****************************************************************************
 Function name  : inia100_reset
 Description    : Reset registers, reset a hanging bus and
                  kill active and disconnected commands for target w/o soft reset
 Input          : host  -       Pointer to host adapter structure
 Output         : None.
 Return         : pSRB  -       Pointer to SCSI request block.
*****************************************************************************/
static int inia100_bus_reset(struct scsi_cmnd * cmd)
{}

/*****************************************************************************
 Function name  : inia100_device_reset
 Description    : Reset the device
 Input          : host  -       Pointer to host adapter structure
 Output         : None.
 Return         : pSRB  -       Pointer to SCSI request block.
*****************************************************************************/
static int inia100_device_reset(struct scsi_cmnd * cmd)
{}

/**
 *	inia100_scb_handler	-	interrupt callback
 *	@host: Host causing the interrupt
 *	@scb: SCB the controller returned as needing processing
 *
 *	Perform completion processing on a control block. Do the conversions
 *	from host to SCSI midlayer error coding, save any sense data and
 *	the complete with the midlayer and recycle the scb.
 */

static void inia100_scb_handler(struct orc_host *host, struct orc_scb *scb)
{}

/**
 *	inia100_intr		-	interrupt handler
 *	@irqno: Interrupt value
 *	@devid: Host adapter
 *
 *	Entry point for IRQ handling. All the real work is performed
 *	by orc_interrupt.
 */
static irqreturn_t inia100_intr(int irqno, void *devid)
{}

static const struct scsi_host_template inia100_template =;

static int inia100_probe_one(struct pci_dev *pdev,
			     const struct pci_device_id *id)
{}

static void inia100_remove_one(struct pci_dev *pdev)
{} 

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

static struct pci_driver inia100_pci_driver =;

module_pci_driver();

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