/*
* ultrastor.c Copyright (C) 1992 David B. Gentzel
* Low-level SCSI driver for UltraStor 14F, 24F, and 34F
* by David B. Gentzel, Whitfield Software Services, Carnegie, PA
* (gentzel@nova.enet.dec.com)
* scatter/gather added by Scott Taylor (n217cg@tamuts.tamu.edu)
* 24F and multiple command support by John F. Carr (jfc@athena.mit.edu)
* John's work modified by Caleb Epstein (cae@jpmorgan.com) and
* Eric Youngdale (ericy@cais.com).
* Thanks to UltraStor for providing the necessary documentation
*
* This is an old driver, for the 14F and 34F you should be using the
* u14-34f driver instead.
*/
/*
* TODO:
* 1. Find out why scatter/gather is limited to 16 requests per command.
* This is fixed, at least on the 24F, as of version 1.12 - CAE.
* 2. Look at command linking (mscp.command_link and
* mscp.command_link_id). (Does not work with many disks,
* and no performance increase. ERY).
* 3. Allow multiple adapters.
*/
/*
* NOTES:
* The UltraStor 14F, 24F, and 34F are a family of intelligent, high
* performance SCSI-2 host adapters. They all support command queueing
* and scatter/gather I/O. Some of them can also emulate the standard
* WD1003 interface for use with OS's which don't support SCSI. Here
* is the scoop on the various models:
* 14F - ISA first-party DMA HA with floppy support and WD1003 emulation.
* 14N - ISA HA with floppy support. I think that this is a non-DMA
* HA. Nothing further known.
* 24F - EISA Bus Master HA with floppy support and WD1003 emulation.
* 34F - VL-Bus Bus Master HA with floppy support (no WD1003 emulation).
*
* The 14F, 24F, and 34F are supported by this driver.
*
* Places flagged with a triple question-mark are things which are either
* unfinished, questionable, or wrong.
*/
/* Changes from version 1.11 alpha to 1.12
*
* Increased the size of the scatter-gather list to 33 entries for
* the 24F adapter (it was 16). I don't have the specs for the 14F
* or the 34F, so they may support larger s-g lists as well.
*
* Caleb Epstein <cae@jpmorgan.com>
*/
/* Changes from version 1.9 to 1.11
*
* Patches to bring this driver up to speed with the default kernel
* driver which supports only the 14F and 34F adapters. This version
* should compile cleanly into 0.99.13, 0.99.12 and probably 0.99.11.
*
* Fixes from Eric Youngdale to fix a few possible race conditions and
* several problems with bit testing operations (insufficient
* parentheses).
*
* Removed the ultrastor_abort() and ultrastor_reset() functions
* (enclosed them in #if 0 / #endif). These functions, at least on
* the 24F, cause the SCSI bus to do odd things and generally lead to
* kernel panics and machine hangs. This is like the Adaptec code.
*
* Use check/snarf_region for 14f, 34f to avoid I/O space address conflicts.
*/
/* Changes from version 1.8 to version 1.9
*
* 0.99.11 patches (cae@jpmorgan.com) */
/* Changes from version 1.7 to version 1.8
*
* Better error reporting.
*/
/* Changes from version 1.6 to version 1.7
*
* Removed CSIR command code.
*
* Better race condition avoidance (xchgb function added).
*
* Set ICM and OGM status to zero at probe (24F)
*
* reset sends soft reset to UltraStor adapter
*
* reset adapter if adapter interrupts with an invalid MSCP address
*
* handle aborted command interrupt (24F)
*
*/
/* Changes from version 1.5 to version 1.6:
*
* Read MSCP address from ICM _before_ clearing the interrupt flag.
* This fixes a race condition.
*/
/* Changes from version 1.4 to version 1.5:
*
* Abort now calls done when multiple commands are enabled.
*
* Clear busy when aborted command finishes, not when abort is called.
*
* More debugging messages for aborts.
*/
/* Changes from version 1.3 to version 1.4:
*
* Enable automatic request of sense data on error (requires newer version
* of scsi.c to be useful).
*
* Fix PORT_OVERRIDE for 14F.
*
* Fix abort and reset to work properly (config.aborted wasn't cleared
* after it was tested, so after a command abort no further commands would
* work).
*
* Boot time test to enable SCSI bus reset (defaults to not allowing reset).
*
* Fix test for OGM busy -- the busy bit is in different places on the 24F.
*
* Release ICM slot by clearing first byte on 24F.
*/
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/interrupt.h>
#include <linux/stddef.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include <linux/stat.h>
#include <linux/bitops.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/dma.h>
#define ULTRASTOR_PRIVATE /* Get the private stuff from ultrastor.h */
#include "scsi.h"
#include <scsi/scsi_host.h>
#include "ultrastor.h"
#define FALSE 0
#define TRUE 1
#ifndef ULTRASTOR_DEBUG
#define ULTRASTOR_DEBUG (UD_ABORT|UD_CSIR|UD_RESET)
#endif
#define VERSION "1.12"
#define PACKED __attribute__((packed))
#define ALIGNED(x) __attribute__((aligned(x)))
/* The 14F uses an array of 4-byte ints for its scatter/gather list.
The data can be unaligned, but need not be. It's easier to give
the list normal alignment since it doesn't need to fit into a
packed structure. */
typedef struct {
u32 address;
u32 num_bytes;
} ultrastor_sg_list;
/* MailBox SCSI Command Packet. Basic command structure for communicating
with controller. */
struct mscp {
unsigned char opcode: 3; /* type of command */
unsigned char xdir: 2; /* data transfer direction */
unsigned char dcn: 1; /* disable disconnect */
unsigned char ca: 1; /* use cache (if available) */
unsigned char sg: 1; /* scatter/gather operation */
unsigned char target_id: 3; /* target SCSI id */
unsigned char ch_no: 2; /* SCSI channel (always 0 for 14f) */
unsigned char lun: 3; /* logical unit number */
unsigned int transfer_data PACKED; /* transfer data pointer */
unsigned int transfer_data_length PACKED; /* length in bytes */
unsigned int command_link PACKED; /* for linking command chains */
unsigned char scsi_command_link_id; /* identifies command in chain */
unsigned char number_of_sg_list; /* (if sg is set) 8 bytes per list */
unsigned char length_of_sense_byte;
unsigned char length_of_scsi_cdbs; /* 6, 10, or 12 */
unsigned char scsi_cdbs[12]; /* SCSI commands */
uns