/* $Id: aha1542.c,v 1.1 1992/07/24 06:27:38 root Exp root $
* linux/kernel/aha1542.c
*
* Copyright (C) 1992 Tommy Thorn
* Copyright (C) 1993, 1994, 1995 Eric Youngdale
*
* Modified by Eric Youngdale
* Use request_irq and request_dma to help prevent unexpected conflicts
* Set up on-board DMA controller, such that we do not have to
* have the bios enabled to use the aha1542.
* Modified by David Gentzel
* Don't call request_dma if dma mask is 0 (for BusLogic BT-445S VL-Bus
* controller).
* Modified by Matti Aarnio
* Accept parameters from LILO cmd-line. -- 1-Oct-94
* Modified by Mike McLagan <mike.mclagan@linux.org>
* Recognise extended mode on AHA1542CP, different bit than 1542CF
* 1-Jan-97
* Modified by Bjorn L. Thordarson and Einar Thor Einarsson
* Recognize that DMA0 is valid DMA channel -- 13-Jul-98
* Modified by Chris Faulhaber <jedgar@fxp.org>
* Added module command-line options
* 19-Jul-99
* Modified by Adam Fritzler
* Added proper detection of the AHA-1640 (MCA, now deleted)
*/
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/isa.h>
#include <linux/pnp.h>
#include <linux/blkdev.h>
#include <linux/slab.h>
#include <asm/dma.h>
#include <asm/io.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include "aha1542.h"
#include <linux/stat.h>
#ifdef DEBUG
#define DEB(x) x
#else
#define DEB(x)
#endif
#define MAXBOARDS 4
static bool isapnp = 1;
module_param(isapnp, bool, 0);
MODULE_PARM_DESC(isapnp, "enable PnP support (default=1)");
static int io[MAXBOARDS] = { 0x330, 0x334, 0, 0 };
module_param_array(io, int, NULL, 0);
MODULE_PARM_DESC(io, "base IO address of controller (0x130,0x134,0x230,0x234,0x330,0x334, default=0x330,0x334)");
/* time AHA spends on the AT-bus during data transfer */
static int bus_on[MAXBOARDS] = { -1, -1, -1, -1 }; /* power-on default: 11us */
module_param_array(bus_on, int, NULL, 0);
MODULE_PARM_DESC(bus_on, "bus on time [us] (2-15, default=-1 [HW default: 11])");
/* time AHA spends off the bus (not to monopolize it) during data transfer */
static int bus_off[MAXBOARDS] = { -1, -1, -1, -1 }; /* power-on default: 4us */
module_param_array(bus_off, int, NULL, 0);
MODULE_PARM_DESC(bus_off, "bus off time [us] (1-64, default=-1 [HW default: 4])");
/* default is jumper selected (J1 on 1542A), factory default = 5 MB/s */
static int dma_speed[MAXBOARDS] = { -1, -1, -1, -1 };
module_param_array(dma_speed, int, NULL, 0);
MODULE_PARM_DESC(dma_speed, "DMA speed [MB/s] (5,6,7,8,10, default=-1 [by jumper])");
#define BIOS_TRANSLATION_6432 1 /* Default case these days */
#define BIOS_TRANSLATION_25563 2 /* Big disk case */
struct aha1542_hostdata {
/* This will effectively start both of them at the first mailbox */
int bios_translation; /* Mapping bios uses - for compatibility */
int aha1542_last_mbi_used;
int aha1542_last_mbo_used;
Scsi_Cmnd *SCint[AHA1542_MAILBOXES];
struct mailbox mb[2 * AHA1542_MAILBOXES];
struct ccb ccb[AHA1542_MAILBOXES];
};
static DEFINE_SPINLOCK(aha1542_lock);
static inline void aha1542_intr_reset(u16 base)
{
outb(IRST, CONTROL(base));
}
static inline bool wait_mask(u16 port, u8 mask, u8 allof, u8 noneof, int timeout)
{
bool delayed = true;
if (timeout == 0) {
timeout = 3000000;
delayed = false;
}
while (1) {
u8 bits = inb(port) & mask;
if ((bits & allof) ==