mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
bitkeeper revision 1.392 (3f3244ecABjhViAc-zlxaKkbsstr4Q)
Many files: Upgraded our aacraid driver to latest Linux-ac version (Linux 2.4.21-ac4 with aacraid v1.1.2).
This commit is contained in:
1 parent
4a30b340d9
commit
6737c35322
12 files changed
+2474
-2309
No files matched your search
@@ -3,10 +3,6 @@ include $(BASEDIR)/Rules.mk
|
||||
|
||||
CFLAGS += -I$(BASEDIR)/drivers/scsi
|
||||
|
||||
|
||||
# -y := linit.o aachba.o commctrl.o comminit.o commsup.o \
|
||||
# dpcsup.o rx.o sa.o
|
||||
|
||||
default: $(OBJS)
|
||||
$(LD) -r -o aacraid.o $(OBJS)
|
||||
|
||||
|
||||
@@ -18,6 +18,12 @@ Supported Cards/Chipsets
|
||||
ADAPTEC 2120S
|
||||
ADAPTEC 2200S
|
||||
ADAPTEC 5400S
|
||||
Legend S220
|
||||
Legend S230
|
||||
Adaptec 3230S
|
||||
Adaptec 3240S
|
||||
ASR-2020S PCI-X
|
||||
AAR-2410SA SATA
|
||||
|
||||
People
|
||||
-------------------------
|
||||
@@ -28,15 +34,22 @@ Deanna Bonds <deanna_bonds@adaptec.com> (non-DASD support, PAE fibs and 64 bit,
|
||||
added new ioctls, changed scsi interface to use new error handler,
|
||||
increased the number of fibs and outstanding commands to a container)
|
||||
|
||||
(fixed 64bit and 64G memory model, changed confusing naming convention
|
||||
where fibs that go to the hardware are consistently called hw_fibs and
|
||||
not just fibs like the name of the driver tracking structure)
|
||||
Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas.
|
||||
|
||||
Original Driver
|
||||
-------------------------
|
||||
Adaptec Unix OEM Product Group
|
||||
|
||||
Mailing List
|
||||
-------------------------
|
||||
None currently. Also note this is very different to Brian's original driver
|
||||
linux-aacraid-devel@dell.com (Interested parties troll here)
|
||||
http://mbserver.adaptec.com/ (Currently more Community Support than Devel Support)
|
||||
Also note this is very different to Brian's original driver
|
||||
so don't expect him to support it.
|
||||
Adaptec does support this driver. Contact either tech support or deanna bonds.
|
||||
Adaptec does support this driver. Contact either tech support or Mark Salyzyn.
|
||||
|
||||
Original by Brian Boerner February 2001
|
||||
Rewritten by Alan Cox, November 2001
|
||||
@@ -2,3 +2,4 @@ o Testing
|
||||
o More testing
|
||||
o Feature request: display the firmware/bios/etc revisions in the
|
||||
/proc info
|
||||
o 2.5.0 and beyond.
|
||||
+839
-778
File diff suppressed because it is too large.
Load diff
@@ -1,17 +1,14 @@
|
||||
|
||||
/* #define dprintk(x) */
|
||||
// #define dprintk(x) printk x
|
||||
#define dprintk(x)
|
||||
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#define TRY_TASKLET
|
||||
#ifdef TRY_TASKLET
|
||||
/* XXX SMH: trying to use softirqs to trigger stuff done prev by threads */
|
||||
#include <xeno/interrupt.h> /* for tasklet/softirq stuff */
|
||||
//#define dprintk(x) printk x
|
||||
#if (!defined(dprintk))
|
||||
# define dprintk(x)
|
||||
#endif
|
||||
|
||||
/* Start of Xen additions XXX */
|
||||
#include <asm/byteorder.h>
|
||||
#include <xeno/interrupt.h>
|
||||
#define TRY_TASKLET
|
||||
/* End of Xen additions XXX */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* D E F I N E S
|
||||
*----------------------------------------------------------------------------*/
|
||||
@@ -19,12 +16,13 @@
|
||||
#define MAXIMUM_NUM_CONTAINERS 31
|
||||
#define MAXIMUM_NUM_ADAPTERS 8
|
||||
|
||||
#define AAC_NUM_FIB 578
|
||||
#define AAC_NUM_IO_FIB 512
|
||||
#define AAC_NUM_FIB 578
|
||||
//#define AAC_NUM_IO_FIB 512
|
||||
#define AAC_NUM_IO_FIB 100
|
||||
|
||||
#define AAC_MAX_TARGET (MAXIMUM_NUM_CONTAINERS+1)
|
||||
#define AAC_MAX_TARGET (MAXIMUM_NUM_CONTAINERS+1)
|
||||
//#define AAC_MAX_TARGET (16)
|
||||
#define AAC_MAX_LUN (8)
|
||||
#define AAC_MAX_LUN (8)
|
||||
|
||||
/*
|
||||
* These macros convert from physical channels to virtual channels
|
||||
@@ -266,27 +264,25 @@ enum aac_queue_types {
|
||||
*/
|
||||
|
||||
struct aac_fibhdr {
|
||||
u32 XferState; // Current transfer state for this CCB
|
||||
u16 Command; // Routing information for the destination
|
||||
u8 StructType; // Type FIB
|
||||
u8 Flags; // Flags for FIB
|
||||
u16 Size; // Size of this FIB in bytes
|
||||
u16 SenderSize; // Size of the FIB in the sender (for
|
||||
// response sizing)
|
||||
u32 SenderFibAddress; // Host defined data in the FIB
|
||||
u32 ReceiverFibAddress; // Logical address of this FIB for the adapter
|
||||
u32 SenderData; // Place holder for the sender to store data
|
||||
union {
|
||||
struct {
|
||||
u32 _ReceiverTimeStart; // Timestamp for receipt of fib
|
||||
u32 _ReceiverTimeDone; // Timestamp for completion of fib
|
||||
} _s;
|
||||
struct list_head _FibLinks; // Used to link Adapter Initiated
|
||||
// Fibs on the host
|
||||
} _u;
|
||||
u32 XferState; // Current transfer state for this CCB
|
||||
u16 Command; // Routing information for the destination
|
||||
u8 StructType; // Type FIB
|
||||
u8 Flags; // Flags for FIB
|
||||
u16 Size; // Size of this FIB in bytes
|
||||
u16 SenderSize; // Size of the FIB in the sender (for response sizing)
|
||||
u32 SenderFibAddress; // Host defined data in the FIB
|
||||
u32 ReceiverFibAddress; // Logical address of this FIB for the adapter
|
||||
u32 SenderData; // Place holder for the sender to store data
|
||||
union {
|
||||
struct {
|
||||
u32 _ReceiverTimeStart; // Timestamp for receipt of fib
|
||||
u32 _ReceiverTimeDone; // Timestamp for completion of fib
|
||||
} _s;
|
||||
// struct aac_list_head _FibLinks; // Used to link Adapter Initiated Fibs on the host
|
||||
} _u;
|
||||
};
|
||||
|
||||
#define FibLinks _u._FibLinks
|
||||
//#define FibLinks _u._FibLinks
|
||||
|
||||
#define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(struct aac_fibhdr))
|
||||
|
||||
@@ -451,6 +447,8 @@ struct aac_driver_ident
|
||||
char * vname;
|
||||
char * model;
|
||||
u16 channels;
|
||||
int quirks;
|
||||
#define AAC_QUIRK_31BIT 1
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -471,8 +469,7 @@ struct aac_queue {
|
||||
#if 0
|
||||
wait_queue_head_t qfull; /* Event to wait on if the queue is full */
|
||||
wait_queue_head_t cmdready; /* Indicates there is a Command ready from the adapter on this queue. */
|
||||
#endif
|
||||
/* This is only valid for adapter to host command queues. */
|
||||
#endif /* This is only valid for adapter to host command queues. */
|
||||
spinlock_t *lock; /* Spinlock for this queue must take this lock before accessing the lock */
|
||||
spinlock_t lockdata; /* Actual lock (used only on one side of the lock) */
|
||||
unsigned long SavedIrql; /* Previous IRQL when the spin lock is taken */
|
||||
@@ -646,7 +643,7 @@ struct aac_fib_context {
|
||||
#endif
|
||||
int wait; // Set to true when thread is in WaitForSingleObject
|
||||
unsigned long count; // total number of FIBs on FibList
|
||||
struct list_head fibs;
|
||||
struct list_head fib_list; // this holds fibs which should be 32 bit addresses
|
||||
};
|
||||
|
||||
struct fsa_scsi_hba {
|
||||
@@ -656,7 +653,7 @@ struct fsa_scsi_hba {
|
||||
u8 ro[MAXIMUM_NUM_CONTAINERS];
|
||||
u8 locked[MAXIMUM_NUM_CONTAINERS];
|
||||
u8 deleted[MAXIMUM_NUM_CONTAINERS];
|
||||
u32 devno[MAXIMUM_NUM_CONTAINERS];
|
||||
s32 devno[MAXIMUM_NUM_CONTAINERS];
|
||||
};
|
||||
|
||||
struct fib {
|
||||
@@ -667,7 +664,6 @@ struct fib {
|
||||
* The Adapter that this I/O is destined for.
|
||||
*/
|
||||
struct aac_dev *dev;
|
||||
u64 logicaladdr; /* 64 bit */
|
||||
#if 0
|
||||
/*
|
||||
* This is the event the sendfib routine will wait on if the
|
||||
@@ -686,9 +682,14 @@ struct fib {
|
||||
* Outstanding I/O queue.
|
||||
*/
|
||||
struct list_head queue;
|
||||
|
||||
/*
|
||||
* And for the internal issue/reply queues (we may be able
|
||||
* to merge these two)
|
||||
*/
|
||||
struct list_head fiblink;
|
||||
void *data;
|
||||
struct hw_fib *fib; /* Actual shared object */
|
||||
struct hw_fib *hw_fib; /* Actual shared object */
|
||||
dma_addr_t hw_fib_pa; /* physical address of hw_fib*/
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -715,6 +716,7 @@ struct aac_adapter_info
|
||||
u32 biosrev;
|
||||
u32 biosbuild;
|
||||
u32 cluster;
|
||||
u32 clusterchannelmask;
|
||||
u32 serial[2];
|
||||
u32 battery;
|
||||
u32 options;
|
||||
@@ -739,19 +741,22 @@ struct aac_adapter_info
|
||||
/*
|
||||
* Supported Options
|
||||
*/
|
||||
#define AAC_OPT_SNAPSHOT cpu_to_le32(1)
|
||||
#define AAC_OPT_CLUSTERS cpu_to_le32(1<<1)
|
||||
#define AAC_OPT_WRITE_CACHE cpu_to_le32(1<<2)
|
||||
#define AAC_OPT_64BIT_DATA cpu_to_le32(1<<3)
|
||||
#define AAC_OPT_HOST_TIME_FIB cpu_to_le32(1<<4)
|
||||
#define AAC_OPT_RAID50 cpu_to_le32(1<<5)
|
||||
#define AAC_OPT_4GB_WINDOW cpu_to_le32(1<<6)
|
||||
#define AAC_OPT_SCSI_UPGRADEABLE cpu_to_le32(1<<7)
|
||||
#define AAC_OPT_SOFT_ERR_REPORT cpu_to_le32(1<<8)
|
||||
#define AAC_OPT_SUPPORTED_RECONDITION cpu_to_le32(1<<9)
|
||||
#define AAC_OPT_SGMAP_HOST64 cpu_to_le32(1<<10)
|
||||
#define AAC_OPT_ALARM cpu_to_le32(1<<11)
|
||||
#define AAC_OPT_NONDASD cpu_to_le32(1<<12)
|
||||
#define AAC_OPT_SNAPSHOT cpu_to_le32(1)
|
||||
#define AAC_OPT_CLUSTERS cpu_to_le32(1<<1)
|
||||
#define AAC_OPT_WRITE_CACHE cpu_to_le32(1<<2)
|
||||
#define AAC_OPT_64BIT_DATA cpu_to_le32(1<<3)
|
||||
#define AAC_OPT_HOST_TIME_FIB cpu_to_le32(1<<4)
|
||||
#define AAC_OPT_RAID50 cpu_to_le32(1<<5)
|
||||
#define AAC_OPT_4GB_WINDOW cpu_to_le32(1<<6)
|
||||
#define AAC_OPT_SCSI_UPGRADEABLE cpu_to_le32(1<<7)
|
||||
#define AAC_OPT_SOFT_ERR_REPORT cpu_to_le32(1<<8)
|
||||
#define AAC_OPT_SUPPORTED_RECONDITION cpu_to_le32(1<<9)
|
||||
#define AAC_OPT_SGMAP_HOST64 cpu_to_le32(1<<10)
|
||||
#define AAC_OPT_ALARM cpu_to_le32(1<<11)
|
||||
#define AAC_OPT_NONDASD cpu_to_le32(1<<12)
|
||||
#define AAC_OPT_SCSI_MANAGED cpu_to_le32(1<<13)
|
||||
#define AAC_OPT_RAID_SCSI_MODE cpu_to_le32(1<<14)
|
||||
#define AAC_OPT_SUPPLEMENT_ADAPTER_INFO cpu_to_le32(1<<15)
|
||||
|
||||
struct aac_dev
|
||||
{
|
||||
@@ -765,13 +770,12 @@ struct aac_dev
|
||||
*/
|
||||
dma_addr_t hw_fib_pa;
|
||||
struct hw_fib *hw_fib_va;
|
||||
#if BITS_PER_LONG >= 64
|
||||
ulong fib_base_va;
|
||||
#endif
|
||||
/*
|
||||
* Fib Headers
|
||||
*/
|
||||
struct fib fibs[AAC_NUM_FIB];
|
||||
struct fib *fibs;
|
||||
|
||||
struct fib *free_fib;
|
||||
struct fib *timeout_fib;
|
||||
spinlock_t fib_lock;
|
||||
@@ -800,7 +804,9 @@ struct aac_dev
|
||||
|
||||
struct Scsi_Host *scsi_host_ptr;
|
||||
struct fsa_scsi_hba fsa_dev;
|
||||
int thread_pid;
|
||||
#if 0
|
||||
pid_t thread_pid;
|
||||
#endif
|
||||
int cardtype;
|
||||
|
||||
/*
|
||||
@@ -825,8 +831,15 @@ struct aac_dev
|
||||
*/
|
||||
u8 nondasd_support;
|
||||
u8 pae_support;
|
||||
u8 raid_scsi_mode;
|
||||
};
|
||||
|
||||
#define AllocateAndMapFibSpace(dev, MapFibContext) \
|
||||
dev->a_ops.AllocateAndMapFibSpace(dev, MapFibContext)
|
||||
|
||||
#define UnmapAndFreeFibSpace(dev, MapFibContext) \
|
||||
dev->a_ops.UnmapAndFreeFibSpace(dev, MapFibContext)
|
||||
|
||||
#define aac_adapter_interrupt(dev) \
|
||||
dev->a_ops.adapter_interrupt(dev)
|
||||
|
||||
@@ -1163,7 +1176,9 @@ struct aac_mntent {
|
||||
u32 altoid; // != oid <==> snapshot or broken mirror exists
|
||||
};
|
||||
|
||||
#define FSCS_READONLY 0x0002 /* possible result of broken mirror */
|
||||
#define FSCS_NOTCLEAN 0x0001 /* fsck is neccessary before mounting */
|
||||
#define FSCS_READONLY 0x0002 /* possible result of broken mirror */
|
||||
#define FSCS_HIDDEN 0x0004 /* should be ignored - set during a clear */
|
||||
|
||||
struct aac_query_mount {
|
||||
u32 command;
|
||||
@@ -1347,9 +1362,12 @@ extern struct aac_common aac_config;
|
||||
*/
|
||||
|
||||
#define AifCmdEventNotify 1 /* Notify of event */
|
||||
#define AifEnContainerChange 4 /* Container configuration change */
|
||||
#define AifCmdJobProgress 2 /* Progress report */
|
||||
#define AifCmdAPIReport 3 /* Report from other user of API */
|
||||
#define AifCmdDriverNotify 4 /* Notify host driver of event */
|
||||
#define AifDenMorphComplete 200 /* A morph operation completed */
|
||||
#define AifDenVolumeExtendComplete 201 /* A volume expand operation completed */
|
||||
#define AifReqJobList 100 /* Gets back complete job list */
|
||||
#define AifReqJobsForCtr 101 /* Gets back jobs for specific container */
|
||||
#define AifReqJobsForScsi 102 /* Gets back jobs for specific SCSI device */
|
||||
@@ -1374,16 +1392,6 @@ struct aac_aifcmd {
|
||||
u8 data[1]; /* Undefined length (from kernel viewpoint) */
|
||||
};
|
||||
|
||||
static inline u32 fib2addr(struct hw_fib *hw)
|
||||
{
|
||||
return (u32)hw;
|
||||
}
|
||||
|
||||
static inline struct hw_fib *addr2fib(u32 addr)
|
||||
{
|
||||
return (struct hw_fib *)addr;
|
||||
}
|
||||
|
||||
const char *aac_driverinfo(struct Scsi_Host *);
|
||||
struct fib *fib_alloc(struct aac_dev *dev);
|
||||
int fib_setup(struct aac_dev *dev);
|
||||
@@ -1397,7 +1405,7 @@ int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entr
|
||||
int aac_consumer_avail(struct aac_dev * dev, struct aac_queue * q);
|
||||
void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum);
|
||||
int fib_complete(struct fib * context);
|
||||
#define fib_data(fibctx) ((void *)(fibctx)->fib->data)
|
||||
#define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data)
|
||||
int aac_detach(struct aac_dev *dev);
|
||||
struct aac_dev *aac_init_adapter(struct aac_dev *dev);
|
||||
int aac_get_containers(struct aac_dev *dev);
|
||||
|
||||
@@ -28,17 +28,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xeno/config.h>
|
||||
/* #include <xeno/kernel.h> */
|
||||
#include <xeno/init.h>
|
||||
#include <xeno/types.h>
|
||||
#include <xeno/sched.h>
|
||||
#include <xeno/pci.h>
|
||||
/* #include <xeno/spinlock.h> */
|
||||
/* #include <xeno/slab.h> */
|
||||
/* #include <xeno/completion.h> */
|
||||
#include <xeno/blk.h>
|
||||
/* #include <asm/semaphore.h> */
|
||||
#include <linux/config.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/slab.h>
|
||||
/*#include <linux/completion.h>*/
|
||||
#include <linux/blk.h>
|
||||
/*#include <asm/semaphore.h>*/
|
||||
#include <asm/uaccess.h>
|
||||
#include "scsi.h"
|
||||
#include "hosts.h"
|
||||
@@ -63,7 +63,7 @@ static int ioctl_send_fib(struct aac_dev * dev, void *arg)
|
||||
if(fibptr == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
kfib = fibptr->fib;
|
||||
kfib = fibptr->hw_fib;
|
||||
/*
|
||||
* First copy in the header so that we can check the size field.
|
||||
*/
|
||||
@@ -152,7 +152,7 @@ static int open_getadapter_fib(struct aac_dev * dev, void *arg)
|
||||
* the list to 0.
|
||||
*/
|
||||
fibctx->count = 0;
|
||||
INIT_LIST_HEAD(&fibctx->fibs);
|
||||
INIT_LIST_HEAD(&fibctx->fib_list);
|
||||
fibctx->jiffies = jiffies/HZ;
|
||||
/*
|
||||
* Now add this context onto the adapter's
|
||||
@@ -183,7 +183,7 @@ static int next_getadapter_fib(struct aac_dev * dev, void *arg)
|
||||
{
|
||||
struct fib_ioctl f;
|
||||
struct aac_fib_context *fibctx, *aifcp;
|
||||
struct hw_fib * fib;
|
||||
struct fib * fib;
|
||||
int status;
|
||||
struct list_head * entry;
|
||||
int found;
|
||||
@@ -213,12 +213,16 @@ static int next_getadapter_fib(struct aac_dev * dev, void *arg)
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
if (found == 0)
|
||||
if (found == 0) {
|
||||
dprintk ((KERN_INFO "Fib not found\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
|
||||
(fibctx->size != sizeof(struct aac_fib_context)))
|
||||
(fibctx->size != sizeof(struct aac_fib_context))) {
|
||||
dprintk ((KERN_INFO "Fib Context corrupt?\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
status = 0;
|
||||
spin_lock_irqsave(&dev->fib_lock, flags);
|
||||
/*
|
||||
@@ -226,27 +230,28 @@ static int next_getadapter_fib(struct aac_dev * dev, void *arg)
|
||||
* -EAGAIN
|
||||
*/
|
||||
return_fib:
|
||||
if (!list_empty(&fibctx->fibs)) {
|
||||
if (!list_empty(&fibctx->fib_list)) {
|
||||
struct list_head * entry;
|
||||
/*
|
||||
* Pull the next fib from the fibs
|
||||
*/
|
||||
entry = fibctx->fibs.next;
|
||||
entry = fibctx->fib_list.next;
|
||||
list_del(entry);
|
||||
|
||||
fib = list_entry(entry, struct hw_fib, header.FibLinks);
|
||||
fib = list_entry(entry, struct fib, fiblink);
|
||||
fibctx->count--;
|
||||
spin_unlock_irqrestore(&dev->fib_lock, flags);
|
||||
if (copy_to_user(f.fib, fib, sizeof(struct hw_fib))) {
|
||||
if (copy_to_user(f.fib, fib->hw_fib, sizeof(struct hw_fib))) {
|
||||
kfree(fib->hw_fib);
|
||||
kfree(fib);
|
||||
return -EFAULT;
|
||||
}
|
||||
/*
|
||||
* Free the space occupied by this copy of the fib.
|
||||
*/
|
||||
kfree(fib->hw_fib);
|
||||
kfree(fib);
|
||||
status = 0;
|
||||
fibctx->jiffies = jiffies/HZ;
|
||||
} else {
|
||||
spin_unlock_irqrestore(&dev->fib_lock, flags);
|
||||
if (f.wait) {
|
||||
@@ -255,7 +260,7 @@ return_fib:
|
||||
status = -EINTR;
|
||||
} else {
|
||||
#else
|
||||
{
|
||||
{
|
||||
#endif
|
||||
/* Lock again and retry */
|
||||
spin_lock_irqsave(&dev->fib_lock, flags);
|
||||
@@ -265,28 +270,30 @@ return_fib:
|
||||
status = -EAGAIN;
|
||||
}
|
||||
}
|
||||
fibctx->jiffies = jiffies/HZ;
|
||||
return status;
|
||||
}
|
||||
|
||||
int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx)
|
||||
{
|
||||
struct hw_fib *fib;
|
||||
struct fib *fib;
|
||||
|
||||
/*
|
||||
* First free any FIBs that have not been consumed.
|
||||
*/
|
||||
while (!list_empty(&fibctx->fibs)) {
|
||||
while (!list_empty(&fibctx->fib_list)) {
|
||||
struct list_head * entry;
|
||||
/*
|
||||
* Pull the next fib from the fibs
|
||||
*/
|
||||
entry = fibctx->fibs.next;
|
||||
entry = fibctx->fib_list.next;
|
||||
list_del(entry);
|
||||
fib = list_entry(entry, struct hw_fib, header.FibLinks);
|
||||
fib = list_entry(entry, struct fib, fiblink);
|
||||
fibctx->count--;
|
||||
/*
|
||||
* Free the space occupied by this copy of the fib.
|
||||
*/
|
||||
kfree(fib->hw_fib);
|
||||
kfree(fib);
|
||||
}
|
||||
/*
|
||||
|
||||
@@ -29,17 +29,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xeno/config.h>
|
||||
/* #include <xeno/kernel.h> */
|
||||
#include <xeno/init.h>
|
||||
#include <xeno/types.h>
|
||||
#include <xeno/sched.h>
|
||||
#include <xeno/pci.h>
|
||||
#include <xeno/spinlock.h>
|
||||
/* #include <xeno/slab.h> */
|
||||
#include <xeno/blk.h>
|
||||
/* #include <xeno/completion.h> */
|
||||
/* #include <asm/semaphore.h> */
|
||||
#include <linux/config.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/blk.h>
|
||||
/*#include <linux/completion.h>*/
|
||||
#include <linux/mm.h>
|
||||
/*#include <asm/semaphore.h>*/
|
||||
#include "scsi.h"
|
||||
#include "hosts.h"
|
||||
|
||||
@@ -58,7 +59,6 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
|
||||
struct aac_init *init;
|
||||
dma_addr_t phys;
|
||||
|
||||
/* FIXME: Adaptec add 128 bytes to this value - WHY ?? */
|
||||
size = fibsize + sizeof(struct aac_init) + commsize + commalign + printfbufsiz;
|
||||
|
||||
base = pci_alloc_consistent(dev->pdev, size, &phys);
|
||||
@@ -74,14 +74,6 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
|
||||
dev->init = (struct aac_init *)(base + fibsize);
|
||||
dev->init_pa = phys + fibsize;
|
||||
|
||||
/*
|
||||
* Cache the upper bits of the virtual mapping for 64bit boxes
|
||||
* FIXME: this crap should be rewritten
|
||||
*/
|
||||
#if BITS_PER_LONG >= 64
|
||||
dev->fib_base_va = ((ulong)base & 0xffffffff00000000);
|
||||
#endif
|
||||
|
||||
init = dev->init;
|
||||
|
||||
init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
|
||||
@@ -92,16 +84,20 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
|
||||
* Adapter Fibs are the first thing allocated so that they
|
||||
* start page aligned
|
||||
*/
|
||||
init->AdapterFibsVirtualAddress = cpu_to_le32((u32)base);
|
||||
init->AdapterFibsPhysicalAddress = cpu_to_le32(phys);
|
||||
dev->fib_base_va = (ulong)base;
|
||||
|
||||
/* We submit the physical address for AIF tags to limit to 32 bits */
|
||||
init->AdapterFibsVirtualAddress = cpu_to_le32((u32)phys);
|
||||
init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys);
|
||||
init->AdapterFibsSize = cpu_to_le32(fibsize);
|
||||
init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
|
||||
init->HostPhysMemPages = cpu_to_le32(4096); // number of 4k pages of host physical memory
|
||||
|
||||
/*
|
||||
* Increment the base address by the amount already used
|
||||
*/
|
||||
base = base + fibsize + sizeof(struct aac_init);
|
||||
phys = phys + fibsize + sizeof(struct aac_init);
|
||||
phys = (dma_addr_t)((ulong)phys + fibsize + sizeof(struct aac_init));
|
||||
/*
|
||||
* Align the beginning of Headers to commalign
|
||||
*/
|
||||
@@ -111,8 +107,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
|
||||
/*
|
||||
* Fill in addresses of the Comm Area Headers and Queues
|
||||
*/
|
||||
*commaddr = (unsigned long *)base;
|
||||
init->CommHeaderAddress = cpu_to_le32(phys);
|
||||
*commaddr = base;
|
||||
init->CommHeaderAddress = cpu_to_le32((u32)phys);
|
||||
/*
|
||||
* Increment the base address by the size of the CommArea
|
||||
*/
|
||||
@@ -144,8 +140,8 @@ static void aac_queue_init(struct aac_dev * dev, struct aac_queue * q, u32 *mem,
|
||||
q->lock = &q->lockdata;
|
||||
q->headers.producer = mem;
|
||||
q->headers.consumer = mem+1;
|
||||
*q->headers.producer = cpu_to_le32(qsize);
|
||||
*q->headers.consumer = cpu_to_le32(qsize);
|
||||
*(q->headers.producer) = cpu_to_le32(qsize);
|
||||
*(q->headers.consumer) = cpu_to_le32(qsize);
|
||||
q->entries = qsize;
|
||||
}
|
||||
|
||||
@@ -250,9 +246,9 @@ int aac_comm_init(struct aac_dev * dev)
|
||||
if (!aac_alloc_comm(dev, (void * *)&headers, size, QUEUE_ALIGNMENT))
|
||||
return -ENOMEM;
|
||||
|
||||
queues = (struct aac_entry *)((unsigned char *)headers + hdrsize);
|
||||
queues = (struct aac_entry *)(((ulong)headers) + hdrsize);
|
||||
|
||||
/* Adapter to Host normal proirity Command queue */
|
||||
/* Adapter to Host normal priority Command queue */
|
||||
comm->queue[HostNormCmdQueue].base = queues;
|
||||
aac_queue_init(dev, &comm->queue[HostNormCmdQueue], headers, HOST_NORM_CMD_ENTRIES);
|
||||
queues += HOST_NORM_CMD_ENTRIES;
|
||||
@@ -317,23 +313,25 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
|
||||
/*
|
||||
* Ok now init the communication subsystem
|
||||
*/
|
||||
dev->queues = (struct aac_queue_block *)
|
||||
kmalloc(sizeof(struct aac_queue_block), GFP_KERNEL);
|
||||
dev->queues = (struct aac_queue_block *) kmalloc(sizeof(struct aac_queue_block), GFP_KERNEL);
|
||||
if (dev->queues == NULL) {
|
||||
printk(KERN_ERR "Error could not allocate comm region.\n");
|
||||
return NULL;
|
||||
}
|
||||
memset(dev->queues, 0, sizeof(struct aac_queue_block));
|
||||
|
||||
if (aac_comm_init(dev)<0)
|
||||
if (aac_comm_init(dev)<0){
|
||||
kfree(dev->queues);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
/*
|
||||
* Initialize the list of fibs
|
||||
*/
|
||||
if(fib_setup(dev)<0)
|
||||
return NULL;
|
||||
|
||||
if(fib_setup(dev)<0){
|
||||
kfree(dev->queues);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&dev->fib_list);
|
||||
#if 0
|
||||
init_completion(&dev->aif_completion);
|
||||
|
||||
+742
-644
File diff suppressed because it is too large.
Load diff
@@ -29,17 +29,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xeno/config.h>
|
||||
/* #include <xeno/kernel.h> */
|
||||
#include <xeno/init.h>
|
||||
#include <xeno/types.h>
|
||||
#include <xeno/sched.h>
|
||||
#include <xeno/pci.h>
|
||||
/* #include <xeno/spinlock.h> */
|
||||
/* #include <xeno/slab.h> */
|
||||
/* #include <xeno/completion.h> */
|
||||
#include <xeno/blk.h>
|
||||
/* #include <asm/semaphore.h> */
|
||||
#include <linux/config.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/slab.h>
|
||||
/*#include <linux/completion.h>*/
|
||||
#include <linux/blk.h>
|
||||
/*#include <asm/semaphore.h>*/
|
||||
#include "scsi.h"
|
||||
#include "hosts.h"
|
||||
|
||||
@@ -74,12 +74,14 @@ unsigned int aac_response_normal(struct aac_queue * q)
|
||||
*/
|
||||
while(aac_consumer_get(dev, q, &entry))
|
||||
{
|
||||
int fast;
|
||||
|
||||
fast = (int) (entry->addr & 0x01);
|
||||
hwfib = addr2fib(entry->addr & ~0x01);
|
||||
aac_consumer_free(dev, q, HostNormRespQueue);
|
||||
u32 fast ;
|
||||
fast = (entry->addr & cpu_to_le32(0x01));
|
||||
// fib = &dev->fibs[(entry->addr >> 1)];
|
||||
// hwfib = fib->hw_fib;
|
||||
hwfib = bus_to_virt(le32_to_cpu(entry->addr & cpu_to_le32(~0x01)));
|
||||
fib = &dev->fibs[hwfib->header.SenderData];
|
||||
|
||||
aac_consumer_free(dev, q, HostNormRespQueue);
|
||||
/*
|
||||
* Remove this fib from the Outstanding I/O queue.
|
||||
* But only if it has not already been timed out.
|
||||
@@ -173,32 +175,53 @@ unsigned int aac_command_normal(struct aac_queue *q)
|
||||
* up the waiters until there are no more QEs. We then return
|
||||
* back to the system.
|
||||
*/
|
||||
dprintk((KERN_INFO
|
||||
"dev=%p, dev->comm_phys=%x, dev->comm_addr=%p, dev->comm_size=%u\n",
|
||||
dev, (u32)dev->comm_phys, dev->comm_addr, (unsigned)dev->comm_size));
|
||||
|
||||
while(aac_consumer_get(dev, q, &entry))
|
||||
{
|
||||
struct hw_fib * fib;
|
||||
fib = addr2fib(entry->addr);
|
||||
struct fib fibctx;
|
||||
struct fib *fib = &fibctx;
|
||||
u32 hw_fib_pa = le32_to_cpu(entry->addr & cpu_to_le32(~0x01));
|
||||
struct hw_fib * hw_fib_va = ((dev->comm_phys <= hw_fib_pa)
|
||||
&& (hw_fib_pa < (dev->comm_phys + dev->comm_size)))
|
||||
? dev->comm_addr + (hw_fib_pa - dev->comm_phys)
|
||||
: /* inconceivable */ bus_to_virt(hw_fib_pa);
|
||||
dprintk((KERN_INFO "hw_fib_pa=%x hw_fib_va=%p\n", hw_fib_pa, hw_fib_va));
|
||||
|
||||
if (dev->aif_thread) {
|
||||
list_add_tail(&fib->header.FibLinks, &q->cmdq);
|
||||
/*
|
||||
* Allocate a FIB at all costs. For non queued stuff
|
||||
* we can just use the stack so we are happy. We need
|
||||
* a fib object in order to manage the linked lists
|
||||
*/
|
||||
if (dev->aif_thread)
|
||||
if((fib = kmalloc(sizeof(struct fib), GFP_ATOMIC))==NULL)
|
||||
fib = &fibctx;
|
||||
|
||||
memset(fib, 0, sizeof(struct fib));
|
||||
INIT_LIST_HEAD(&fib->fiblink);
|
||||
fib->type = FSAFS_NTC_FIB_CONTEXT;
|
||||
fib->size = sizeof(struct fib);
|
||||
fib->hw_fib = hw_fib_va;
|
||||
fib->data = hw_fib_va->data;
|
||||
fib->dev = dev;
|
||||
|
||||
if (dev->aif_thread && fib != &fibctx)
|
||||
{
|
||||
list_add_tail(&fib->fiblink, &q->cmdq);
|
||||
aac_consumer_free(dev, q, HostNormCmdQueue);
|
||||
#if 0
|
||||
wake_up_interruptible(&q->cmdready);
|
||||
#endif
|
||||
} else {
|
||||
struct fib fibctx;
|
||||
aac_consumer_free(dev, q, HostNormCmdQueue);
|
||||
spin_unlock_irqrestore(q->lock, flags);
|
||||
memset(&fibctx, 0, sizeof(struct fib));
|
||||
fibctx.type = FSAFS_NTC_FIB_CONTEXT;
|
||||
fibctx.size = sizeof(struct fib);
|
||||
fibctx.fib = fib;
|
||||
fibctx.data = fib->data;
|
||||
fibctx.dev = dev;
|
||||
/*
|
||||
* Set the status of this FIB
|
||||
*/
|
||||
*(u32 *)fib->data = cpu_to_le32(ST_OK);
|
||||
fib_adapter_complete(&fibctx, sizeof(u32));
|
||||
*(u32 *)hw_fib_va->data = cpu_to_le32(ST_OK);
|
||||
fib_adapter_complete(fib, sizeof(u32));
|
||||
spin_lock_irqsave(q->lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
+367
-383
@@ -35,21 +35,21 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define AAC_DRIVER_VERSION "0.9.9ac6-TEST"
|
||||
#define AAC_DRIVER_BUILD_DATE __DATE__
|
||||
#define AAC_DRIVER_VERSION "1.1.2"
|
||||
#define AAC_DRIVER_BUILD_DATE __DATE__ " " __TIME__
|
||||
|
||||
#include <xeno/module.h>
|
||||
#include <xeno/config.h>
|
||||
#include <xeno/kernel.h>
|
||||
#include <xeno/init.h>
|
||||
#include <xeno/types.h>
|
||||
#include <xeno/sched.h>
|
||||
#include <xeno/pci.h>
|
||||
#include <xeno/spinlock.h>
|
||||
/* #include <xeno/slab.h> */
|
||||
/* #include <xeno/completion.h> */
|
||||
/* #include <asm/semaphore.h> */
|
||||
#include <xeno/blk.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/config.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/slab.h>
|
||||
/*#include <linux/completion.h>*/
|
||||
/*#include <asm/semaphore.h>*/
|
||||
#include <linux/blk.h>
|
||||
#include "scsi.h"
|
||||
#include "hosts.h"
|
||||
|
||||
@@ -59,12 +59,14 @@
|
||||
#define AAC_DRIVERNAME "aacraid"
|
||||
|
||||
MODULE_AUTHOR("Red Hat Inc and Adaptec");
|
||||
MODULE_DESCRIPTION("Supports Dell PERC2, 2/Si, 3/Si, 3/Di, PERC 320/DC, Adaptec 2120S, 2200S, 5400S, and HP NetRAID-4M devices. http://domsch.com/xeno/ or http://linux.adaptec.com");
|
||||
MODULE_DESCRIPTION("Supports Dell PERC2, 2/Si, 3/Si, 3/Di, Adaptec Advanced Raid Products, and HP NetRAID-4M devices. http://domsch.com/linux/ or http://linux.adaptec.com");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_PARM(nondasd, "i");
|
||||
MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on");
|
||||
MODULE_PARM(paemode, "i");
|
||||
MODULE_PARM_DESC(paemode, "Control whether dma addressing is using PAE. 0=off, 1=on");
|
||||
|
||||
static int nondasd=-1;
|
||||
#if 0
|
||||
static int paemode = -1;
|
||||
#endif
|
||||
|
||||
struct aac_dev *aac_devices[MAXIMUM_NUM_ADAPTERS];
|
||||
|
||||
@@ -81,25 +83,41 @@ static int aac_cfg_major = -1;
|
||||
*/
|
||||
|
||||
static struct aac_driver_ident aac_drivers[] = {
|
||||
{ 0x1028, 0x0001, 0x1028, 0x0001, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 2/Si */
|
||||
{ 0x1028, 0x0002, 0x1028, 0x0002, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di */
|
||||
{ 0x1028, 0x0003, 0x1028, 0x0003, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Si */
|
||||
{ 0x1028, 0x0004, 0x1028, 0x00d0, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Si */
|
||||
{ 0x1028, 0x0002, 0x1028, 0x00d1, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di */
|
||||
{ 0x1028, 0x0002, 0x1028, 0x00d9, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di */
|
||||
{ 0x1028, 0x000a, 0x1028, 0x0106, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di */
|
||||
{ 0x1028, 0x000a, 0x1028, 0x011b, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di */
|
||||
{ 0x1028, 0x000a, 0x1028, 0x0121, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di */
|
||||
{ 0x9005, 0x0283, 0x9005, 0x0283, aac_rx_init, "aacraid", "ADAPTEC ", "catapult ", 2 }, /* catapult*/
|
||||
{ 0x9005, 0x0284, 0x9005, 0x0284, aac_rx_init, "aacraid", "ADAPTEC ", "tomcat ", 2 }, /* tomcat*/
|
||||
{ 0x9005, 0x0285, 0x9005, 0x0286, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2120S ", 1 }, /* Adaptec 2120S (Crusader)*/
|
||||
{ 0x9005, 0x0285, 0x9005, 0x0285, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2 }, /* Adaptec 2200S (Vulcan)*/
|
||||
{ 0x9005, 0x0285, 0x9005, 0x0287, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2 }, /* Adaptec 2200S (Vulcan-2m)*/
|
||||
{ 0x9005, 0x0285, 0x1028, 0x0287, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* Dell PERC 320/DC */
|
||||
{ 0x1011, 0x0046, 0x9005, 0x0365, aac_sa_init, "aacraid", "ADAPTEC ", "Adaptec 5400S ", 4 }, /* Adaptec 5400S (Mustang)*/
|
||||
{ 0x1011, 0x0046, 0x9005, 0x0364, aac_sa_init, "aacraid", "ADAPTEC ", "AAC-364 ", 4 }, /* Adaptec 5400S (Mustang)*/
|
||||
{ 0x1011, 0x0046, 0x9005, 0x1364, aac_sa_init, "percraid", "DELL ", "PERCRAID ", 4 }, /* Dell PERC2 "Quad Channel" */
|
||||
{ 0x1011, 0x0046, 0x103c, 0x10c2, aac_sa_init, "hpnraid", "HP ", "NetRAID-4M ", 4 } /* HP NetRAID-4M */
|
||||
{ 0x1028, 0x0001, 0x1028, 0x0001, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 2/Si (Iguana/PERC2Si) */
|
||||
{ 0x1028, 0x0002, 0x1028, 0x0002, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Opal/PERC3Di) */
|
||||
{ 0x1028, 0x0003, 0x1028, 0x0003, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Si (SlimFast/PERC3Si */
|
||||
{ 0x1028, 0x0004, 0x1028, 0x00d0, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Iguana FlipChip/PERC3DiF */
|
||||
{ 0x1028, 0x0002, 0x1028, 0x00d1, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Viper/PERC3DiV) */
|
||||
{ 0x1028, 0x0002, 0x1028, 0x00d9, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Lexus/PERC3DiL) */
|
||||
{ 0x1028, 0x000a, 0x1028, 0x0106, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Jaguar/PERC3DiJ) */
|
||||
{ 0x1028, 0x000a, 0x1028, 0x011b, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Dagger/PERC3DiD) */
|
||||
{ 0x1028, 0x000a, 0x1028, 0x0121, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Boxster/PERC3DiB) */
|
||||
{ 0x9005, 0x0283, 0x9005, 0x0283, aac_rx_init, "aacraid", "ADAPTEC ", "catapult ", 2 }, /* catapult */
|
||||
{ 0x9005, 0x0284, 0x9005, 0x0284, aac_rx_init, "aacraid", "ADAPTEC ", "tomcat ", 2 }, /* tomcat */
|
||||
{ 0x9005, 0x0285, 0x9005, 0x0286, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2120S ", 1, AAC_QUIRK_31BIT },/* Adaptec 2120S (Crusader) */
|
||||
{ 0x9005, 0x0285, 0x9005, 0x0285, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT },/* Adaptec 2200S (Vulcan) */
|
||||
{ 0x9005, 0x0285, 0x9005, 0x0287, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT },/* Adaptec 2200S (Vulcan-2m) */
|
||||
{ 0x9005, 0x0285, 0x17aa, 0x0286, aac_rx_init, "aacraid", "Legend ", "Legend S220 ", 1 }, /* Legend S220 (Legend Crusader) */
|
||||
{ 0x9005, 0x0285, 0x17aa, 0x0287, aac_rx_init, "aacraid", "Legend ", "Legend S230 ", 2 }, /* Legend S230 (Legend Vulcan) */
|
||||
|
||||
{ 0x9005, 0x0285, 0x9005, 0x0288, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 3230S ", 2 }, /* Adaptec 3230S (Harrier) */
|
||||
{ 0x9005, 0x0285, 0x9005, 0x0289, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 3240S ", 2 }, /* Adaptec 3240S (Tornado) */
|
||||
{ 0x9005, 0x0285, 0x9005, 0x028a, aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020S PCI-X ", 2 }, /* ASR-2020S PCI-X ZCR (Skyhawk) */
|
||||
{ 0x9005, 0x0285, 0x9005, 0x028b, aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020S PCI-X ", 2 }, /* ASR-2020S SO-DIMM PCI-X ZCR (Terminator) */
|
||||
{ 0x9005, 0x0285, 0x9005, 0x0290, aac_rx_init, "aacraid", "ADAPTEC ", "AAR-2410SA SATA ", 2 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */
|
||||
{ 0x9005, 0x0285, 0x1028, 0x0291, aac_rx_init, "aacraid", "DELL ", "CERC SATA RAID 2 ", 2 }, /* CERC SATA RAID 2 PCI SATA 8ch (DellCorsair) */
|
||||
{ 0x9005, 0x0285, 0x9005, 0x0292, aac_rx_init, "aacraid", "ADAPTEC ", "AAR-2810SA SATA ", 2 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */
|
||||
{ 0x9005, 0x0285, 0x9005, 0x0293, aac_rx_init, "aacraid", "ADAPTEC ", "AAR-21610SA SATA ", 2 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */
|
||||
{ 0x9005, 0x0285, 0x9005, 0x0294, aac_rx_init, "aacraid", "ADAPTEC ", "SO-DIMM SATA ZCR ", 2 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
|
||||
/* ServeRAID */
|
||||
/* { 0x9005, 0x0250, 0x1014, 0x0279, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec ", 2 }, */ /* (Marco) */
|
||||
/* { 0x9005, 0x0250, 0x1014, 0x028c, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec ", 2 }, */ /* (Sebring)*/
|
||||
|
||||
{ 0x9005, 0x0285, 0x1028, 0x0287, aac_rx_init, "percraid", "DELL ", "PERC 320/DC ", 2 }, /* Perc 320/DC*/
|
||||
{ 0x1011, 0x0046, 0x9005, 0x0365, aac_sa_init, "aacraid", "ADAPTEC ", "Adaptec 5400S ", 4 }, /* Adaptec 5400S (Mustang)*/
|
||||
{ 0x1011, 0x0046, 0x9005, 0x0364, aac_sa_init, "aacraid", "ADAPTEC ", "AAC-364 ", 4 }, /* Adaptec 5400S (Mustang)*/
|
||||
{ 0x1011, 0x0046, 0x9005, 0x1364, aac_sa_init, "percraid", "DELL ", "PERCRAID ", 4 }, /* Dell PERC2 "Quad Channel" */
|
||||
{ 0x1011, 0x0046, 0x103c, 0x10c2, aac_sa_init, "hpnraid", "HP ", "NetRAID ", 4 } /* HP NetRAID-4M */
|
||||
};
|
||||
|
||||
#define NUM_AACTYPES (sizeof(aac_drivers) / sizeof(struct aac_driver_ident))
|
||||
@@ -111,7 +129,7 @@ static int aac_cfg_open(struct inode * inode, struct file * file);
|
||||
static int aac_cfg_release(struct inode * inode,struct file * file);
|
||||
|
||||
static struct file_operations aac_cfg_fops = {
|
||||
/* owner: THIS_MODULE, */
|
||||
owner: THIS_MODULE,
|
||||
ioctl: aac_cfg_ioctl,
|
||||
open: aac_cfg_open,
|
||||
release: aac_cfg_release
|
||||
@@ -151,194 +169,156 @@ static void aac_queuedepth(struct Scsi_Host *, Scsi_Device *);
|
||||
* scsi_malloc/scsi_free must not be called.
|
||||
*
|
||||
*/
|
||||
|
||||
static int aac_detect(Scsi_Host_Template *template)
|
||||
{
|
||||
int index;
|
||||
int container;
|
||||
u16 vendor_id, device_id;
|
||||
struct Scsi_Host *host_ptr;
|
||||
struct pci_dev *dev = NULL;
|
||||
struct aac_dev *aac;
|
||||
struct fsa_scsi_hba *fsa_dev_ptr;
|
||||
char *name = NULL;
|
||||
int index;
|
||||
int container;
|
||||
u16 vendor_id, device_id;
|
||||
struct Scsi_Host *host_ptr;
|
||||
struct pci_dev *dev = NULL;
|
||||
struct aac_dev *aac;
|
||||
struct fsa_scsi_hba *fsa_dev_ptr;
|
||||
char *name = NULL;
|
||||
|
||||
printk(KERN_INFO "Red Hat/Adaptec aacraid driver, %s\n",
|
||||
AAC_DRIVER_BUILD_DATE);
|
||||
printk(KERN_INFO "Red Hat/Adaptec aacraid driver (%s %s)\n", AAC_DRIVER_VERSION, AAC_DRIVER_BUILD_DATE);
|
||||
|
||||
/* setting up the proc directory structure */
|
||||
template->proc_name = "aacraid";
|
||||
spin_unlock_irq(&io_request_lock);
|
||||
|
||||
/*
|
||||
** XXX SMH: we need to take interrupts during detect, but the SCSI
|
||||
** layer is holding this lock with interrupts disabled. I don't
|
||||
** know how this works on vanilla linux (we 'down' on a semaphone
|
||||
** at one point during the process -- how do we wake?)
|
||||
*/
|
||||
spin_unlock_irq(&io_request_lock);
|
||||
for( index = 0; index != num_aacdrivers; index++ )
|
||||
{
|
||||
device_id = aac_drivers[index].device;
|
||||
vendor_id = aac_drivers[index].vendor;
|
||||
name = aac_drivers[index].name;
|
||||
dprintk((KERN_DEBUG "Checking %s %x/%x/%x/%x.\n",
|
||||
name, vendor_id, device_id,
|
||||
aac_drivers[index].subsystem_vendor,
|
||||
aac_drivers[index].subsystem_device));
|
||||
|
||||
|
||||
/* setting up the proc directory structure */
|
||||
template->proc_name = "aacraid";
|
||||
|
||||
for( index = 0; index != num_aacdrivers; index++ )
|
||||
{
|
||||
device_id = aac_drivers[index].device;
|
||||
vendor_id = aac_drivers[index].vendor;
|
||||
name = aac_drivers[index].name;
|
||||
dprintk((KERN_DEBUG "Checking %s %x/%x/%x/%x.\n",
|
||||
name, vendor_id, device_id,
|
||||
aac_drivers[index].subsystem_vendor,
|
||||
aac_drivers[index].subsystem_device));
|
||||
|
||||
dev = NULL;
|
||||
while((dev = pci_find_device(vendor_id, device_id, dev))) {
|
||||
if (pci_enable_device(dev))
|
||||
continue;
|
||||
pci_set_master(dev);
|
||||
pci_set_dma_mask(dev, 0xFFFFFFFFULL);
|
||||
|
||||
if((dev->subsystem_vendor != aac_drivers[index].subsystem_vendor) ||
|
||||
(dev->subsystem_device != aac_drivers[index].subsystem_device))
|
||||
continue;
|
||||
|
||||
dprintk((KERN_DEBUG "%s device detected.\n", name));
|
||||
dprintk((KERN_DEBUG "%x/%x/%x/%x.\n", vendor_id, device_id,
|
||||
aac_drivers[index].subsystem_vendor,
|
||||
aac_drivers[index].subsystem_device));
|
||||
/* Increment the host adapter count */
|
||||
aac_count++;
|
||||
/*
|
||||
* scsi_register() allocates memory for a Scsi_Hosts
|
||||
* structure and links it into the linked list of host
|
||||
* adapters. This linked list contains the data for all
|
||||
* possible <supported> scsi hosts. This is similar to
|
||||
* the Scsi_Host_Template, except that we have one entry
|
||||
* for each actual physical host adapter on the system,
|
||||
* stored as a linked list. If there are two AAC boards,
|
||||
* then we will need to make two Scsi_Host entries, but
|
||||
* there will be only one Scsi_Host_Template entry. The
|
||||
* second argument to scsi_register() specifies the size
|
||||
* of the extra memory we want to hold any device specific
|
||||
* information. */
|
||||
host_ptr = scsi_register( template, sizeof(struct aac_dev) );
|
||||
/*
|
||||
* These three parameters can be used to allow for wide SCSI
|
||||
* and for host adapters that support multiple buses.
|
||||
*/
|
||||
host_ptr->max_id = 17;
|
||||
host_ptr->max_lun = 8;
|
||||
host_ptr->max_channel = 1;
|
||||
host_ptr->irq = dev->irq; /* Adapter IRQ number */
|
||||
/* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
|
||||
host_ptr->base = dev->resource[0].start;
|
||||
scsi_set_pci_device(host_ptr, dev);
|
||||
dprintk((KERN_DEBUG "Device base address = 0x%lx [0x%lx].\n",
|
||||
host_ptr->base, dev->resource[0].start));
|
||||
dprintk((KERN_DEBUG "Device irq = 0x%x.\n", dev->irq));
|
||||
/*
|
||||
* The unique_id field is a unique identifier that must
|
||||
* be assigned so that we have some way of identifying
|
||||
* each host adapter properly and uniquely. For hosts
|
||||
* that do not support more than one card in the
|
||||
* system, this does not need to be set. It is
|
||||
* initialized to zero in scsi_register(). This is the
|
||||
* value returned as aac->id.
|
||||
*/
|
||||
host_ptr->unique_id = aac_count - 1;
|
||||
/*
|
||||
* This function is called after the device list has
|
||||
* been built to find the tagged queueing depth
|
||||
* supported for each device.
|
||||
*/
|
||||
host_ptr->select_queue_depths = aac_queuedepth;
|
||||
aac = (struct aac_dev *)host_ptr->hostdata;
|
||||
/* attach a pointer back to Scsi_Host */
|
||||
aac->scsi_host_ptr = host_ptr;
|
||||
aac->pdev = dev;
|
||||
aac->cardtype = index;
|
||||
aac->name = aac->scsi_host_ptr->hostt->name;
|
||||
aac->id = aac->scsi_host_ptr->unique_id;
|
||||
/* Initialize the ordinal number of the device to -1 */
|
||||
fsa_dev_ptr = &(aac->fsa_dev);
|
||||
for( container=0; container < MAXIMUM_NUM_CONTAINERS; container++)
|
||||
fsa_dev_ptr->devno[container] = -1;
|
||||
|
||||
dprintk((KERN_DEBUG "Initializing Hardware...\n"));
|
||||
|
||||
if((*aac_drivers[index].init)(aac , host_ptr->unique_id) != 0)
|
||||
{
|
||||
/* device initialization failed */
|
||||
printk(KERN_WARNING
|
||||
"aacraid: device initialization failed.\n");
|
||||
scsi_unregister(host_ptr);
|
||||
aac_count--;
|
||||
continue;
|
||||
}
|
||||
dprintk((KERN_DEBUG "%s:%d device initialization successful.\n",
|
||||
name, host_ptr->unique_id));
|
||||
aac_get_adapter_info(aac);
|
||||
|
||||
dprintk((KERN_DEBUG "%s got adapter info.\n", name));
|
||||
|
||||
if(nondasd != -1)
|
||||
{
|
||||
/* someone told us how to set this on the cmdline */
|
||||
aac->nondasd_support = (nondasd!=0);
|
||||
}
|
||||
if(aac->nondasd_support != 0){
|
||||
printk(KERN_INFO "%s%d: Non-DASD support enabled\n",
|
||||
aac->name, aac->id);
|
||||
}
|
||||
dprintk((KERN_DEBUG "%s:%d options flag %04x.\n", name,
|
||||
host_ptr->unique_id, aac->adapter_info.options));
|
||||
if(aac->nondasd_support == 1)
|
||||
{
|
||||
/*
|
||||
* max channel will be the physical
|
||||
* channels plus 1 virtual channel all
|
||||
* containers are on the virtual
|
||||
* channel 0 physical channels are
|
||||
* address by their actual physical
|
||||
* number+1 */
|
||||
host_ptr->max_channel = aac_drivers[index].channels+1;
|
||||
} else {
|
||||
host_ptr->max_channel = 1;
|
||||
}
|
||||
dprintk((KERN_DEBUG "Device has %d logical channels\n",
|
||||
host_ptr->max_channel));
|
||||
aac_get_containers(aac);
|
||||
aac_devices[aac_count-1] = aac;
|
||||
|
||||
/*
|
||||
* dmb - we may need to move these 3 parms somewhere else once
|
||||
* we get a fib that can report the actual numbers
|
||||
*/
|
||||
host_ptr->max_id = AAC_MAX_TARGET;
|
||||
host_ptr->max_lun = AAC_MAX_LUN;
|
||||
dev = NULL;
|
||||
while((dev = pci_find_device(vendor_id, device_id, dev))) {
|
||||
if (pci_enable_device(dev))
|
||||
continue;
|
||||
pci_set_master(dev);
|
||||
|
||||
/*
|
||||
* If we are PAE capable then our future DMA mappings
|
||||
* (for read/write commands) are 64bit clean and don't
|
||||
* need bouncing. This assumes we do no other 32bit only
|
||||
* allocations (eg fib table expands) after this point.
|
||||
*/
|
||||
|
||||
if(aac->pae_support)
|
||||
pci_set_dma_mask(dev, 0xFFFFFFFFFFFFFFFFUL);
|
||||
if(aac_drivers[index].quirks & AAC_QUIRK_31BIT)
|
||||
pci_set_dma_mask(dev, 0x7FFFFFFFULL);
|
||||
else
|
||||
pci_set_dma_mask(dev, 0xFFFFFFFFULL);
|
||||
|
||||
if((dev->subsystem_vendor != aac_drivers[index].subsystem_vendor) ||
|
||||
(dev->subsystem_device != aac_drivers[index].subsystem_device))
|
||||
continue;
|
||||
|
||||
dprintk((KERN_DEBUG "%s device detected.\n", name));
|
||||
dprintk((KERN_DEBUG "%x/%x/%x/%x.\n", vendor_id, device_id,
|
||||
aac_drivers[index].subsystem_vendor, aac_drivers[index].subsystem_device));
|
||||
/*
|
||||
* scsi_register() allocates memory for a Scsi_Hosts structure and
|
||||
* links it into the linked list of host adapters. This linked list
|
||||
* contains the data for all possible <supported> scsi hosts.
|
||||
* This is similar to the Scsi_Host_Template, except that we have
|
||||
* one entry for each actual physical host adapter on the system,
|
||||
* stored as a linked list. If there are two AAC boards, then we
|
||||
* will need to make two Scsi_Host entries, but there will be only
|
||||
* one Scsi_Host_Template entry. The second argument to scsi_register()
|
||||
* specifies the size of the extra memory we want to hold any device
|
||||
* specific information.
|
||||
*/
|
||||
host_ptr = scsi_register( template, sizeof(struct aac_dev) );
|
||||
if(host_ptr == NULL)
|
||||
continue;
|
||||
/* Increment the host adapter count */
|
||||
aac_count++;
|
||||
/*
|
||||
* These three parameters can be used to allow for wide SCSI
|
||||
* and for host adapters that support multiple buses.
|
||||
*/
|
||||
host_ptr->irq = dev->irq; /* Adapter IRQ number */
|
||||
/* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
|
||||
host_ptr->base = dev->resource[0].start;
|
||||
scsi_set_pci_device(host_ptr, dev);
|
||||
dprintk((KERN_DEBUG "Device base address = 0x%lx [0x%lx].\n", host_ptr->base, dev->resource[0].start));
|
||||
dprintk((KERN_DEBUG "Device irq = 0x%x.\n", dev->irq));
|
||||
/*
|
||||
* The unique_id field is a unique identifier that must
|
||||
* be assigned so that we have some way of identifying
|
||||
* each host adapter properly and uniquely. For hosts
|
||||
* that do not support more than one card in the
|
||||
* system, this does not need to be set. It is
|
||||
* initialized to zero in scsi_register(). This is the
|
||||
* value returned as aac->id.
|
||||
*/
|
||||
host_ptr->unique_id = aac_count - 1;
|
||||
/*
|
||||
* This function is called after the device list has
|
||||
* been built to find the tagged queueing depth
|
||||
* supported for each device.
|
||||
*/
|
||||
host_ptr->select_queue_depths = aac_queuedepth;
|
||||
aac = (struct aac_dev *)host_ptr->hostdata;
|
||||
/* attach a pointer back to Scsi_Host */
|
||||
aac->scsi_host_ptr = host_ptr;
|
||||
aac->pdev = dev;
|
||||
aac->name = aac->scsi_host_ptr->hostt->name;
|
||||
aac->id = aac->scsi_host_ptr->unique_id;
|
||||
aac->cardtype = index;
|
||||
|
||||
aac->fibs = (struct fib*) kmalloc(sizeof(struct fib)*AAC_NUM_FIB, GFP_KERNEL);
|
||||
spin_lock_init(&aac->fib_lock);
|
||||
|
||||
/* Initialize the ordinal number of the device to -1 */
|
||||
fsa_dev_ptr = &(aac->fsa_dev);
|
||||
for( container = 0; container < MAXIMUM_NUM_CONTAINERS; container++ )
|
||||
fsa_dev_ptr->devno[container] = -1;
|
||||
|
||||
dprintk((KERN_DEBUG "Initializing Hardware...\n"));
|
||||
if((*aac_drivers[index].init)(aac , host_ptr->unique_id) != 0)
|
||||
{
|
||||
/* device initialization failed */
|
||||
printk(KERN_WARNING "aacraid: device initialization failed.\n");
|
||||
scsi_unregister(host_ptr);
|
||||
aac_count--;
|
||||
continue;
|
||||
}
|
||||
dprintk((KERN_DEBUG "%s:%d device initialization successful.\n", name, host_ptr->unique_id));
|
||||
aac_get_adapter_info(aac);
|
||||
if(aac->nondasd_support == 1)
|
||||
{
|
||||
/*
|
||||
* max channel will be the physical channels plus 1 virtual channel
|
||||
* all containers are on the virtual channel 0
|
||||
* physical channels are address by their actual physical number+1
|
||||
*/
|
||||
host_ptr->max_channel = aac_drivers[index].channels+1;
|
||||
} else {
|
||||
host_ptr->max_channel = 1;
|
||||
}
|
||||
dprintk((KERN_DEBUG "Device has %d logical channels\n", host_ptr->max_channel));
|
||||
aac_get_containers(aac);
|
||||
aac_devices[aac_count-1] = aac;
|
||||
|
||||
/*
|
||||
* dmb - we may need to move the setting of these parms somewhere else once
|
||||
* we get a fib that can report the actual numbers
|
||||
*/
|
||||
host_ptr->max_id = AAC_MAX_TARGET;
|
||||
host_ptr->max_lun = AAC_MAX_LUN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX SMH: restore lock and IPL for SCSI layer */
|
||||
spin_lock_irq(&io_request_lock);
|
||||
|
||||
|
||||
#if 0
|
||||
if( aac_count ){
|
||||
if((aac_cfg_major = register_chrdev( 0, "aac", &aac_cfg_fops))<0)
|
||||
printk(KERN_WARNING "aacraid: unable to register 'aac' device.\n");
|
||||
}
|
||||
if( aac_count ){
|
||||
if((aac_cfg_major = register_chrdev( 0, "aac", &aac_cfg_fops))<0)
|
||||
printk(KERN_WARNING "aacraid: unable to register \"aac\" device.\n");
|
||||
}
|
||||
#endif
|
||||
spin_lock_irq(&io_request_lock);
|
||||
|
||||
template->present = aac_count; /* # of cards of this type found */
|
||||
return aac_count;
|
||||
template->present = aac_count; /* # of cards of this type found */
|
||||
return aac_count;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -353,38 +333,37 @@ static int aac_detect(Scsi_Host_Template *template)
|
||||
|
||||
static int aac_release(struct Scsi_Host *host_ptr)
|
||||
{
|
||||
struct aac_dev *dev;
|
||||
dprintk((KERN_DEBUG "aac_release.\n"));
|
||||
dev = (struct aac_dev *)host_ptr->hostdata;
|
||||
|
||||
struct aac_dev *dev;
|
||||
dprintk((KERN_DEBUG "aac_release.\n"));
|
||||
dev = (struct aac_dev *)host_ptr->hostdata;
|
||||
#if 0
|
||||
/*
|
||||
* kill any threads we started
|
||||
*/
|
||||
kill_proc(dev->thread_pid, SIGKILL, 0);
|
||||
wait_for_completion(&dev->aif_completion);
|
||||
/*
|
||||
* kill any threads we started
|
||||
*/
|
||||
kill_proc(dev->thread_pid, SIGKILL, 0);
|
||||
wait_for_completion(&dev->aif_completion);
|
||||
#endif
|
||||
/*
|
||||
* Call the comm layer to detach from this adapter
|
||||
*/
|
||||
aac_detach(dev);
|
||||
/* Check free orderings... */
|
||||
/* remove interrupt binding */
|
||||
free_irq(host_ptr->irq, dev);
|
||||
iounmap((void * )dev->regs.sa);
|
||||
/* unregister adapter */
|
||||
scsi_unregister(host_ptr);
|
||||
/*
|
||||
* FIXME: This assumes no hot plugging is going on...
|
||||
*/
|
||||
if( aac_cfg_major >= 0 )
|
||||
{
|
||||
/*
|
||||
* Call the comm layer to detach from this adapter
|
||||
*/
|
||||
aac_detach(dev);
|
||||
/* Check free orderings... */
|
||||
/* remove interrupt binding */
|
||||
free_irq(host_ptr->irq, dev);
|
||||
iounmap((void * )dev->regs.sa);
|
||||
/* unregister adapter */
|
||||
scsi_unregister(host_ptr);
|
||||
/*
|
||||
* FIXME: This assumes no hot plugging is going on...
|
||||
*/
|
||||
if( aac_cfg_major >= 0 )
|
||||
{
|
||||
#if 0
|
||||
unregister_chrdev(aac_cfg_major, "aac");
|
||||
unregister_chrdev(aac_cfg_major, "aac");
|
||||
#endif
|
||||
aac_cfg_major = -1;
|
||||
}
|
||||
return 0;
|
||||
aac_cfg_major = -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -397,16 +376,16 @@ static int aac_release(struct Scsi_Host *host_ptr)
|
||||
|
||||
static int aac_queuecommand(Scsi_Cmnd *scsi_cmnd_ptr, void (*complete)(Scsi_Cmnd *))
|
||||
{
|
||||
int ret;
|
||||
|
||||
scsi_cmnd_ptr->scsi_done = complete;
|
||||
/*
|
||||
* aac_scsi_cmd() handles command processing, setting the
|
||||
* result code and calling completion routine.
|
||||
*/
|
||||
if((ret = aac_scsi_cmd(scsi_cmnd_ptr)) != 0)
|
||||
dprintk((KERN_DEBUG "aac_scsi_cmd failed.\n"));
|
||||
return ret;
|
||||
int ret;
|
||||
|
||||
scsi_cmnd_ptr->scsi_done = complete;
|
||||
/*
|
||||
* aac_scsi_cmd() handles command processing, setting the
|
||||
* result code and calling completion routine.
|
||||
*/
|
||||
if((ret = aac_scsi_cmd(scsi_cmnd_ptr)) != 0)
|
||||
dprintk((KERN_DEBUG "aac_scsi_cmd failed.\n"));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -418,8 +397,8 @@ static int aac_queuecommand(Scsi_Cmnd *scsi_cmnd_ptr, void (*complete)(Scsi_Cmnd
|
||||
|
||||
const char *aac_driverinfo(struct Scsi_Host *host_ptr)
|
||||
{
|
||||
struct aac_dev *dev = (struct aac_dev *)host_ptr->hostdata;
|
||||
return aac_drivers[dev->cardtype].name;
|
||||
struct aac_dev *dev = (struct aac_dev *)host_ptr->hostdata;
|
||||
return aac_drivers[dev->cardtype].name;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -456,111 +435,110 @@ struct aac_driver_ident* aac_get_driver_ident(int devtype)
|
||||
|
||||
static int aac_biosparm(Scsi_Disk *disk, kdev_t dev, int *geom)
|
||||
{
|
||||
struct diskparm *param = (struct diskparm *)geom;
|
||||
/*struct buffer_head * buf;*/
|
||||
|
||||
dprintk((KERN_DEBUG "aac_biosparm.\n"));
|
||||
struct diskparm *param = (struct diskparm *)geom;
|
||||
#if 0
|
||||
struct buffer_head * buf;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Assuming extended translation is enabled - #REVISIT#
|
||||
*/
|
||||
if( disk->capacity >= 2 * 1024 * 1024 ) /* 1 GB in 512 byte sectors */
|
||||
{
|
||||
if( disk->capacity >= 4 * 1024 * 1024 ) /* 2 GB in 512 byte sectors */
|
||||
dprintk((KERN_DEBUG "aac_biosparm.\n"));
|
||||
|
||||
/*
|
||||
* Assuming extended translation is enabled - #REVISIT#
|
||||
*/
|
||||
if( disk->capacity >= 2 * 1024 * 1024 ) /* 1 GB in 512 byte sectors */
|
||||
{
|
||||
param->heads = 255;
|
||||
param->sectors = 63;
|
||||
if( disk->capacity >= 4 * 1024 * 1024 ) /* 2 GB in 512 byte sectors */
|
||||
{
|
||||
param->heads = 255;
|
||||
param->sectors = 63;
|
||||
}
|
||||
else
|
||||
{
|
||||
param->heads = 128;
|
||||
param->sectors = 32;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
param->heads = 128;
|
||||
param->sectors = 32;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
param->heads = 64;
|
||||
param->sectors = 32;
|
||||
}
|
||||
|
||||
param->cylinders = disk->capacity/(param->heads * param->sectors);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Read the first 1024 bytes from the disk device
|
||||
*/
|
||||
|
||||
buf = bread(MKDEV(MAJOR(dev), MINOR(dev)&~0xf), 0, block_size(dev));
|
||||
if(buf == NULL)
|
||||
return 0;
|
||||
/*
|
||||
* If the boot sector partition table is valid, search for a partition
|
||||
* table entry whose end_head matches one of the standard geometry
|
||||
* translations ( 64/32, 128/32, 255/63 ).
|
||||
*/
|
||||
|
||||
|
||||
if(*(unsigned short *)(buf->b_data + 0x1fe) == cpu_to_le16(0xaa55))
|
||||
{
|
||||
struct partition *first = (struct partition * )(buf->b_data + 0x1be);
|
||||
struct partition *entry = first;
|
||||
int saved_cylinders = param->cylinders;
|
||||
int num;
|
||||
unsigned char end_head, end_sec;
|
||||
|
||||
for(num = 0; num < 4; num++)
|
||||
{
|
||||
end_head = entry->end_head;
|
||||
end_sec = entry->end_sector & 0x3f;
|
||||
|
||||
if(end_head == 63)
|
||||
{
|
||||
param->heads = 64;
|
||||
param->sectors = 32;
|
||||
break;
|
||||
}
|
||||
else if(end_head == 127)
|
||||
{
|
||||
param->heads = 128;
|
||||
param->sectors = 32;
|
||||
break;
|
||||
}
|
||||
else if(end_head == 254)
|
||||
{
|
||||
param->heads = 255;
|
||||
param->sectors = 63;
|
||||
break;
|
||||
}
|
||||
entry++;
|
||||
}
|
||||
|
||||
if(num == 4)
|
||||
|
||||
param->cylinders = disk->capacity/(param->heads * param->sectors);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Read the first 1024 bytes from the disk device
|
||||
*/
|
||||
|
||||
buf = bread(MKDEV(MAJOR(dev), MINOR(dev)&~0xf), 0, block_size(dev));
|
||||
if(buf == NULL)
|
||||
return 0;
|
||||
/*
|
||||
* If the boot sector partition table is valid, search for a partition
|
||||
* table entry whose end_head matches one of the standard geometry
|
||||
* translations ( 64/32, 128/32, 255/63 ).
|
||||
*/
|
||||
|
||||
if(*(unsigned short *)(buf->b_data + 0x1fe) == cpu_to_le16(0xaa55))
|
||||
{
|
||||
end_head = first->end_head;
|
||||
end_sec = first->end_sector & 0x3f;
|
||||
struct partition *first = (struct partition * )(buf->b_data + 0x1be);
|
||||
struct partition *entry = first;
|
||||
int saved_cylinders = param->cylinders;
|
||||
int num;
|
||||
unsigned char end_head, end_sec;
|
||||
|
||||
for(num = 0; num < 4; num++)
|
||||
{
|
||||
end_head = entry->end_head;
|
||||
end_sec = entry->end_sector & 0x3f;
|
||||
|
||||
if(end_head == 63)
|
||||
{
|
||||
param->heads = 64;
|
||||
param->sectors = 32;
|
||||
break;
|
||||
}
|
||||
else if(end_head == 127)
|
||||
{
|
||||
param->heads = 128;
|
||||
param->sectors = 32;
|
||||
break;
|
||||
}
|
||||
else if(end_head == 254)
|
||||
{
|
||||
param->heads = 255;
|
||||
param->sectors = 63;
|
||||
break;
|
||||
}
|
||||
entry++;
|
||||
}
|
||||
|
||||
if(num == 4)
|
||||
{
|
||||
end_head = first->end_head;
|
||||
end_sec = first->end_sector & 0x3f;
|
||||
}
|
||||
|
||||
param->cylinders = disk->capacity / (param->heads * param->sectors);
|
||||
|
||||
if(num < 4 && end_sec == param->sectors)
|
||||
{
|
||||
if(param->cylinders != saved_cylinders)
|
||||
dprintk((KERN_DEBUG "Adopting geometry: heads=%d, sectors=%d from partition table %d.\n",
|
||||
param->heads, param->sectors, num));
|
||||
}
|
||||
else if(end_head > 0 || end_sec > 0)
|
||||
{
|
||||
dprintk((KERN_DEBUG "Strange geometry: heads=%d, sectors=%d in partition table %d.\n",
|
||||
end_head + 1, end_sec, num));
|
||||
dprintk((KERN_DEBUG "Using geometry: heads=%d, sectors=%d.\n",
|
||||
param->heads, param->sectors));
|
||||
}
|
||||
}
|
||||
|
||||
param->cylinders = disk->capacity / (param->heads * param->sectors);
|
||||
|
||||
if(num < 4 && end_sec == param->sectors)
|
||||
{
|
||||
if(param->cylinders != saved_cylinders)
|
||||
dprintk((KERN_DEBUG "Adopting geometry: heads=%d, "
|
||||
"sectors=%d from partition table %d.\n",
|
||||
param->heads, param->sectors, num));
|
||||
}
|
||||
else if(end_head > 0 || end_sec > 0)
|
||||
{
|
||||
dprintk((KERN_DEBUG "Strange geometry: heads=%d, "
|
||||
"sectors=%d in partition table %d.\n",
|
||||
end_head + 1, end_sec, num));
|
||||
dprintk((KERN_DEBUG "Using geometry: heads=%d, sectors=%d.\n",
|
||||
param->heads, param->sectors));
|
||||
}
|
||||
}
|
||||
brelse(buf);
|
||||
brelse(buf);
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -575,20 +553,20 @@ static int aac_biosparm(Scsi_Disk *disk, kdev_t dev, int *geom)
|
||||
|
||||
static void aac_queuedepth(struct Scsi_Host * host, Scsi_Device * dev )
|
||||
{
|
||||
Scsi_Device * dptr;
|
||||
|
||||
dprintk((KERN_DEBUG "aac_queuedepth.\n"));
|
||||
dprintk((KERN_DEBUG "Device # Q Depth Online\n"));
|
||||
dprintk((KERN_DEBUG "---------------------------\n"));
|
||||
for(dptr = dev; dptr != NULL; dptr = dptr->next)
|
||||
{
|
||||
if(dptr->host == host)
|
||||
Scsi_Device * dptr;
|
||||
|
||||
dprintk((KERN_DEBUG "aac_queuedepth.\n"));
|
||||
dprintk((KERN_DEBUG "Device # Q Depth Online\n"));
|
||||
dprintk((KERN_DEBUG "---------------------------\n"));
|
||||
for(dptr = dev; dptr != NULL; dptr = dptr->next)
|
||||
{
|
||||
dptr->queue_depth = 10;
|
||||
dprintk((KERN_DEBUG " %2d %d %d\n",
|
||||
dptr->id, dptr->queue_depth, dptr->online));
|
||||
if(dptr->host == host)
|
||||
{
|
||||
dptr->queue_depth = 10;
|
||||
dprintk((KERN_DEBUG " %2d %d %d\n",
|
||||
dptr->id, dptr->queue_depth, dptr->online));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -603,7 +581,7 @@ static void aac_queuedepth(struct Scsi_Host * host, Scsi_Device * dev )
|
||||
|
||||
static int aac_eh_abort(Scsi_Cmnd *cmd)
|
||||
{
|
||||
return FAILED;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -617,7 +595,7 @@ static int aac_eh_abort(Scsi_Cmnd *cmd)
|
||||
|
||||
static int aac_eh_device_reset(Scsi_Cmnd *cmd)
|
||||
{
|
||||
return FAILED;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -631,7 +609,7 @@ static int aac_eh_device_reset(Scsi_Cmnd *cmd)
|
||||
|
||||
static int aac_eh_bus_reset(Scsi_Cmnd* cmd)
|
||||
{
|
||||
return FAILED;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -645,8 +623,8 @@ static int aac_eh_bus_reset(Scsi_Cmnd* cmd)
|
||||
|
||||
static int aac_eh_reset(Scsi_Cmnd* cmd)
|
||||
{
|
||||
printk(KERN_ERR "aacraid: Host adapter reset request. SCSI hang ?\n");
|
||||
return FAILED;
|
||||
printk(KERN_ERR "aacraid: Host adapter reset request. SCSI hang ?\n");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -661,10 +639,10 @@ static int aac_eh_reset(Scsi_Cmnd* cmd)
|
||||
|
||||
static int aac_ioctl(Scsi_Device * scsi_dev_ptr, int cmd, void * arg)
|
||||
{
|
||||
struct aac_dev *dev;
|
||||
dprintk((KERN_DEBUG "aac_ioctl.\n"));
|
||||
dev = (struct aac_dev *)scsi_dev_ptr->host->hostdata;
|
||||
return aac_do_ioctl(dev, cmd, arg);
|
||||
struct aac_dev *dev;
|
||||
dprintk((KERN_DEBUG "aac_ioctl.\n"));
|
||||
dev = (struct aac_dev *)scsi_dev_ptr->host->hostdata;
|
||||
return aac_do_ioctl(dev, cmd, arg);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -681,10 +659,10 @@ static int aac_ioctl(Scsi_Device * scsi_dev_ptr, int cmd, void * arg)
|
||||
|
||||
static int aac_cfg_open(struct inode * inode, struct file * file )
|
||||
{
|
||||
unsigned minor_number = MINOR(inode->i_rdev);
|
||||
if(minor_number >= aac_count)
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
unsigned minor_number = MINOR(inode->i_rdev);
|
||||
if(minor_number >= aac_count)
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -698,7 +676,7 @@ static int aac_cfg_open(struct inode * inode, struct file * file )
|
||||
|
||||
static int aac_cfg_release(struct inode * inode, struct file * file )
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -717,8 +695,8 @@ static int aac_cfg_release(struct inode * inode, struct file * file )
|
||||
|
||||
static int aac_cfg_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg )
|
||||
{
|
||||
struct aac_dev *dev = aac_devices[MINOR(inode->i_rdev)];
|
||||
return aac_do_ioctl(dev, cmd, (void *)arg);
|
||||
struct aac_dev *dev = aac_devices[MINOR(inode->i_rdev)];
|
||||
return aac_do_ioctl(dev, cmd, (void *)arg);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -728,9 +706,13 @@ static int aac_cfg_ioctl(struct inode * inode, struct file * file, unsigned int
|
||||
*/
|
||||
|
||||
static Scsi_Host_Template driver_template = {
|
||||
/* module: THIS_MODULE, */
|
||||
#if 0
|
||||
module: THIS_MODULE,
|
||||
#endif
|
||||
name: "AAC",
|
||||
/* proc_info: aac_procinfo, */
|
||||
#if 0
|
||||
proc_info: aac_procinfo,
|
||||
#endif
|
||||
detect: aac_detect,
|
||||
release: aac_release,
|
||||
info: aac_driverinfo,
|
||||
@@ -780,11 +762,13 @@ static Scsi_Host_Template driver_template = {
|
||||
static int aac_procinfo(char *proc_buffer, char **start_ptr,off_t offset,
|
||||
int bytes_available, int host_no, int write)
|
||||
{
|
||||
if(write || offset > 0)
|
||||
return 0;
|
||||
*start_ptr = proc_buffer;
|
||||
return sprintf(proc_buffer, "%s %d\n",
|
||||
"Raid Controller, scsi hba number", host_no);
|
||||
if(write || offset > 0)
|
||||
return 0;
|
||||
*start_ptr = proc_buffer;
|
||||
return sprintf(proc_buffer,
|
||||
"Adaptec Raid Controller %s %s, scsi hba number %d\n",
|
||||
AAC_DRIVER_VERSION, AAC_DRIVER_BUILD_DATE,
|
||||
host_no);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+291
-319
@@ -28,18 +28,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xeno/config.h>
|
||||
#include <xeno/kernel.h>
|
||||
#include <xeno/init.h>
|
||||
#include <xeno/types.h>
|
||||
#include <xeno/sched.h>
|
||||
#include <xeno/pci.h>
|
||||
/* #include <xeno/spinlock.h> */
|
||||
/* #include <xeno/slab.h> */
|
||||
#include <xeno/blk.h>
|
||||
#include <xeno/delay.h>
|
||||
/* #include <xeno/completion.h> */
|
||||
/* #include <asm/semaphore.h> */
|
||||
#include <linux/config.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/blk.h>
|
||||
#include <linux/delay.h>
|
||||
/*#include <linux/completion.h>*/
|
||||
/*#include <asm/semaphore.h>*/
|
||||
#include "scsi.h"
|
||||
#include "hosts.h"
|
||||
|
||||
@@ -47,42 +47,41 @@
|
||||
|
||||
static void aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
struct aac_dev *dev = dev_id;
|
||||
unsigned long bellbits;
|
||||
u8 intstat, mask;
|
||||
intstat = rx_readb(dev, MUnit.OISR);
|
||||
/*
|
||||
* Read mask and invert because drawbridge is reversed.
|
||||
* This allows us to only service interrupts that have
|
||||
* been enabled.
|
||||
*/
|
||||
mask = ~(rx_readb(dev, MUnit.OIMR));
|
||||
/* Check to see if this is our interrupt. If it isn't just return */
|
||||
|
||||
if (intstat & mask)
|
||||
{
|
||||
bellbits = rx_readl(dev, OutboundDoorbellReg);
|
||||
if (bellbits & DoorBellPrintfReady) {
|
||||
aac_printf(dev, le32_to_cpu(rx_readl (dev, IndexRegs.Mailbox[5])));
|
||||
rx_writel(dev, MUnit.ODR,DoorBellPrintfReady);
|
||||
rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
|
||||
struct aac_dev *dev = dev_id;
|
||||
unsigned long bellbits;
|
||||
u8 intstat, mask;
|
||||
intstat = rx_readb(dev, MUnit.OISR);
|
||||
/*
|
||||
* Read mask and invert because drawbridge is reversed.
|
||||
* This allows us to only service interrupts that have
|
||||
* been enabled.
|
||||
*/
|
||||
mask = ~(rx_readb(dev, MUnit.OIMR));
|
||||
/* Check to see if this is our interrupt. If it isn't just return */
|
||||
if (intstat & mask)
|
||||
{
|
||||
bellbits = rx_readl(dev, OutboundDoorbellReg);
|
||||
if (bellbits & DoorBellPrintfReady) {
|
||||
aac_printf(dev, le32_to_cpu(rx_readl (dev, IndexRegs.Mailbox[5])));
|
||||
rx_writel(dev, MUnit.ODR,DoorBellPrintfReady);
|
||||
rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
|
||||
}
|
||||
else if (bellbits & DoorBellAdapterNormCmdReady) {
|
||||
aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
|
||||
rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
|
||||
}
|
||||
else if (bellbits & DoorBellAdapterNormRespReady) {
|
||||
aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
|
||||
rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady);
|
||||
}
|
||||
else if (bellbits & DoorBellAdapterNormCmdNotFull) {
|
||||
rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
|
||||
}
|
||||
else if (bellbits & DoorBellAdapterNormRespNotFull) {
|
||||
rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
|
||||
rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull);
|
||||
}
|
||||
}
|
||||
else if (bellbits & DoorBellAdapterNormCmdReady) {
|
||||
aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
|
||||
rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
|
||||
}
|
||||
else if (bellbits & DoorBellAdapterNormRespReady) {
|
||||
aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
|
||||
rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady);
|
||||
}
|
||||
else if (bellbits & DoorBellAdapterNormCmdNotFull) {
|
||||
rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
|
||||
}
|
||||
else if (bellbits & DoorBellAdapterNormRespNotFull) {
|
||||
rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
|
||||
rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,24 +94,24 @@ static void aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs)
|
||||
|
||||
static void aac_rx_enable_interrupt(struct aac_dev * dev, u32 event)
|
||||
{
|
||||
switch (event) {
|
||||
|
||||
case HostNormCmdQue:
|
||||
dev->irq_mask &= ~(OUTBOUNDDOORBELL_1);
|
||||
break;
|
||||
|
||||
case HostNormRespQue:
|
||||
dev->irq_mask &= ~(OUTBOUNDDOORBELL_2);
|
||||
break;
|
||||
|
||||
case AdapNormCmdNotFull:
|
||||
dev->irq_mask &= ~(OUTBOUNDDOORBELL_3);
|
||||
break;
|
||||
|
||||
case AdapNormRespNotFull:
|
||||
dev->irq_mask &= ~(OUTBOUNDDOORBELL_4);
|
||||
break;
|
||||
}
|
||||
switch (event) {
|
||||
|
||||
case HostNormCmdQue:
|
||||
dev->irq_mask &= ~(OUTBOUNDDOORBELL_1);
|
||||
break;
|
||||
|
||||
case HostNormRespQue:
|
||||
dev->irq_mask &= ~(OUTBOUNDDOORBELL_2);
|
||||
break;
|
||||
|
||||
case AdapNormCmdNotFull:
|
||||
dev->irq_mask &= ~(OUTBOUNDDOORBELL_3);
|
||||
break;
|
||||
|
||||
case AdapNormRespNotFull:
|
||||
dev->irq_mask &= ~(OUTBOUNDDOORBELL_4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,24 +124,24 @@ static void aac_rx_enable_interrupt(struct aac_dev * dev, u32 event)
|
||||
|
||||
static void aac_rx_disable_interrupt(struct aac_dev *dev, u32 event)
|
||||
{
|
||||
switch (event) {
|
||||
|
||||
case HostNormCmdQue:
|
||||
dev->irq_mask |= (OUTBOUNDDOORBELL_1);
|
||||
break;
|
||||
|
||||
case HostNormRespQue:
|
||||
dev->irq_mask |= (OUTBOUNDDOORBELL_2);
|
||||
break;
|
||||
|
||||
case AdapNormCmdNotFull:
|
||||
dev->irq_mask |= (OUTBOUNDDOORBELL_3);
|
||||
break;
|
||||
|
||||
case AdapNormRespNotFull:
|
||||
dev->irq_mask |= (OUTBOUNDDOORBELL_4);
|
||||
break;
|
||||
}
|
||||
switch (event) {
|
||||
|
||||
case HostNormCmdQue:
|
||||
dev->irq_mask |= (OUTBOUNDDOORBELL_1);
|
||||
break;
|
||||
|
||||
case HostNormRespQue:
|
||||
dev->irq_mask |= (OUTBOUNDDOORBELL_2);
|
||||
break;
|
||||
|
||||
case AdapNormCmdNotFull:
|
||||
dev->irq_mask |= (OUTBOUNDDOORBELL_3);
|
||||
break;
|
||||
|
||||
case AdapNormRespNotFull:
|
||||
dev->irq_mask |= (OUTBOUNDDOORBELL_4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,91 +157,89 @@ static void aac_rx_disable_interrupt(struct aac_dev *dev, u32 event)
|
||||
|
||||
static int rx_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status)
|
||||
{
|
||||
unsigned long start;
|
||||
int ok;
|
||||
/*
|
||||
* Write the command into Mailbox 0
|
||||
*/
|
||||
rx_writel(dev, InboundMailbox0, cpu_to_le32(command));
|
||||
/*
|
||||
* Write the parameters into Mailboxes 1 - 4
|
||||
*/
|
||||
rx_writel(dev, InboundMailbox1, cpu_to_le32(p1));
|
||||
rx_writel(dev, InboundMailbox2, 0);
|
||||
rx_writel(dev, InboundMailbox3, 0);
|
||||
rx_writel(dev, InboundMailbox4, 0);
|
||||
/*
|
||||
* Clear the synch command doorbell to start on a clean slate.
|
||||
*/
|
||||
rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
|
||||
/*
|
||||
* Disable doorbell interrupts
|
||||
*/
|
||||
rx_writeb(dev, MUnit.OIMR, rx_readb(dev, MUnit.OIMR) | 0x04);
|
||||
/*
|
||||
* Force the completion of the mask register write before issuing
|
||||
* the interrupt.
|
||||
*/
|
||||
rx_readb (dev, MUnit.OIMR);
|
||||
/*
|
||||
* Signal that there is a new synch command
|
||||
*/
|
||||
rx_writel(dev, InboundDoorbellReg, INBOUNDDOORBELL_0);
|
||||
|
||||
ok = 0;
|
||||
start = jiffies;
|
||||
|
||||
/*
|
||||
* Wait up to 30 seconds
|
||||
*/
|
||||
while (time_before(jiffies, start+30*HZ))
|
||||
{
|
||||
/* Delay 5 microseconds to let Mon960 get info. */
|
||||
udelay(5);
|
||||
unsigned long start;
|
||||
int ok;
|
||||
/*
|
||||
* Mon960 will set doorbell0 bit when its completed the command.
|
||||
* Write the command into Mailbox 0
|
||||
*/
|
||||
if (rx_readl(dev, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
|
||||
/*
|
||||
* Clear the doorbell.
|
||||
*/
|
||||
rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
|
||||
ok = 1;
|
||||
break;
|
||||
}
|
||||
rx_writel(dev, InboundMailbox0, cpu_to_le32(command));
|
||||
/*
|
||||
* Write the parameters into Mailboxes 1 - 4
|
||||
*/
|
||||
rx_writel(dev, InboundMailbox1, cpu_to_le32(p1));
|
||||
rx_writel(dev, InboundMailbox2, 0);
|
||||
rx_writel(dev, InboundMailbox3, 0);
|
||||
rx_writel(dev, InboundMailbox4, 0);
|
||||
/*
|
||||
* Clear the synch command doorbell to start on a clean slate.
|
||||
*/
|
||||
rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
|
||||
/*
|
||||
* Disable doorbell interrupts
|
||||
*/
|
||||
rx_writeb(dev, MUnit.OIMR, rx_readb(dev, MUnit.OIMR) | 0x04);
|
||||
/*
|
||||
* Force the completion of the mask register write before issuing
|
||||
* the interrupt.
|
||||
*/
|
||||
rx_readb (dev, MUnit.OIMR);
|
||||
/*
|
||||
* Signal that there is a new synch command
|
||||
*/
|
||||
rx_writel(dev, InboundDoorbellReg, INBOUNDDOORBELL_0);
|
||||
|
||||
ok = 0;
|
||||
start = jiffies;
|
||||
|
||||
/*
|
||||
* Wait up to 30 seconds
|
||||
*/
|
||||
while (time_before(jiffies, start+30*HZ))
|
||||
{
|
||||
udelay(5); /* Delay 5 microseconds to let Mon960 get info. */
|
||||
/*
|
||||
* Mon960 will set doorbell0 bit when it has completed the command.
|
||||
*/
|
||||
if (rx_readl(dev, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
|
||||
/*
|
||||
* Clear the doorbell.
|
||||
*/
|
||||
rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
|
||||
ok = 1;
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
* Yield the processor in case we are slow
|
||||
*/
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
schedule_timeout(1);
|
||||
#else
|
||||
/* XXX SMH: not in xen we don't */
|
||||
mdelay(50);
|
||||
/*
|
||||
* Yield the processor in case we are slow
|
||||
*/
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
schedule_timeout(1);
|
||||
#else
|
||||
/* XXX SMH: not in xen we don't */
|
||||
mdelay(50);
|
||||
#endif
|
||||
|
||||
}
|
||||
if (ok != 1) {
|
||||
}
|
||||
if (ok != 1) {
|
||||
/*
|
||||
* Restore interrupt mask even though we timed out
|
||||
*/
|
||||
rx_writeb(dev, MUnit.OIMR, rx_readl(dev, MUnit.OIMR) & 0xfb);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
/*
|
||||
* Restore interrupt mask even though we timed out
|
||||
* Pull the synch status from Mailbox 0.
|
||||
*/
|
||||
*status = le32_to_cpu(rx_readl(dev, IndexRegs.Mailbox[0]));
|
||||
/*
|
||||
* Clear the synch command doorbell.
|
||||
*/
|
||||
rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
|
||||
/*
|
||||
* Restore interrupt mask
|
||||
*/
|
||||
rx_writeb(dev, MUnit.OIMR, rx_readl(dev, MUnit.OIMR) & 0xfb);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
/*
|
||||
* Pull the synch status from Mailbox 0.
|
||||
*/
|
||||
*status = le32_to_cpu(rx_readl(dev, IndexRegs.Mailbox[0]));
|
||||
/*
|
||||
* Clear the synch command doorbell.
|
||||
*/
|
||||
rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
|
||||
/*
|
||||
* Restore interrupt mask
|
||||
*/
|
||||
rx_writeb(dev, MUnit.OIMR, rx_readl(dev, MUnit.OIMR) & 0xfb);
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,8 +251,8 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status)
|
||||
|
||||
static void aac_rx_interrupt_adapter(struct aac_dev *dev)
|
||||
{
|
||||
u32 ret;
|
||||
rx_sync_cmd(dev, BREAKPOINT_REQUEST, 0, &ret);
|
||||
u32 ret;
|
||||
rx_sync_cmd(dev, BREAKPOINT_REQUEST, 0, &ret);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -269,33 +266,33 @@ static void aac_rx_interrupt_adapter(struct aac_dev *dev)
|
||||
|
||||
static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event)
|
||||
{
|
||||
switch (event) {
|
||||
|
||||
case AdapNormCmdQue:
|
||||
rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_1);
|
||||
break;
|
||||
case HostNormRespNotFull:
|
||||
rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_4);
|
||||
break;
|
||||
case AdapNormRespQue:
|
||||
rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_2);
|
||||
break;
|
||||
case HostNormCmdNotFull:
|
||||
rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3);
|
||||
break;
|
||||
case HostShutdown:
|
||||
switch (event) {
|
||||
|
||||
case AdapNormCmdQue:
|
||||
rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_1);
|
||||
break;
|
||||
case HostNormRespNotFull:
|
||||
rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_4);
|
||||
break;
|
||||
case AdapNormRespQue:
|
||||
rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_2);
|
||||
break;
|
||||
case HostNormCmdNotFull:
|
||||
rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3);
|
||||
break;
|
||||
case HostShutdown:
|
||||
// rx_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, &ret);
|
||||
break;
|
||||
case FastIo:
|
||||
rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6);
|
||||
break;
|
||||
case AdapPrintfDone:
|
||||
rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_5);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FastIo:
|
||||
rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6);
|
||||
break;
|
||||
case AdapPrintfDone:
|
||||
rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_5);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,31 +304,27 @@ static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event)
|
||||
|
||||
static void aac_rx_start_adapter(struct aac_dev *dev)
|
||||
{
|
||||
u32 status;
|
||||
struct aac_init *init;
|
||||
|
||||
init = dev->init;
|
||||
u32 status;
|
||||
struct aac_init *init;
|
||||
|
||||
init->HostElapsedSeconds = cpu_to_le32(jiffies/HZ);
|
||||
/*
|
||||
* Tell the adapter we are back and up and running so it will scan
|
||||
* its command queues and enable our interrupts
|
||||
*/
|
||||
dev->irq_mask = (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 |
|
||||
OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 |
|
||||
OUTBOUNDDOORBELL_4);
|
||||
/*
|
||||
* First clear out all interrupts. Then enable the one's that we
|
||||
* can handle.
|
||||
*/
|
||||
rx_writeb(dev, MUnit.OIMR, 0xff);
|
||||
rx_writel(dev, MUnit.ODR, 0xffffffff);
|
||||
init = dev->init;
|
||||
init->HostElapsedSeconds = cpu_to_le32(jiffies/HZ);
|
||||
/*
|
||||
* Tell the adapter we are back and up and running so it will scan
|
||||
* its command queues and enable our interrupts
|
||||
*/
|
||||
dev->irq_mask = (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
|
||||
/*
|
||||
* First clear out all interrupts. Then enable the one's that we
|
||||
* can handle.
|
||||
*/
|
||||
rx_writeb(dev, MUnit.OIMR, 0xff);
|
||||
rx_writel(dev, MUnit.ODR, 0xffffffff);
|
||||
// rx_writeb(dev, MUnit.OIMR, ~(u8)OUTBOUND_DOORBELL_INTERRUPT_MASK);
|
||||
rx_writeb(dev, MUnit.OIMR, 0xfb);
|
||||
|
||||
// We can only use a 32 bit address here
|
||||
rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS,
|
||||
(u32)(ulong)dev->init_pa, &status);
|
||||
rx_writeb(dev, MUnit.OIMR, 0xfb);
|
||||
|
||||
// We can only use a 32 bit address here
|
||||
rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &status);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -346,112 +339,91 @@ static void aac_rx_start_adapter(struct aac_dev *dev)
|
||||
|
||||
int aac_rx_init(struct aac_dev *dev, unsigned long num)
|
||||
{
|
||||
unsigned long start;
|
||||
unsigned long status;
|
||||
int instance;
|
||||
const char * name;
|
||||
|
||||
dev->devnum = num;
|
||||
instance = dev->id;
|
||||
name = dev->name;
|
||||
|
||||
dprintk((KERN_ERR "aac_rx_init called, num %ld, scsi host ptr = %p\n",
|
||||
num, (void *)(dev->scsi_host_ptr)));
|
||||
|
||||
dprintk((KERN_ERR "scsi_host_ptr->base is %p\n",
|
||||
(void *)dev->scsi_host_ptr->base));
|
||||
/*
|
||||
* Map in the registers from the adapter.
|
||||
*/
|
||||
if((dev->regs.rx = (struct rx_registers *)
|
||||
ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL)
|
||||
{
|
||||
printk(KERN_WARNING "aacraid: unable to map i960.\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// dprintk((KERN_ERR "aac_rx_init: AAA\n"));
|
||||
/*
|
||||
* Check to see if the board failed any self tests.
|
||||
*/
|
||||
if (rx_readl(dev, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
|
||||
printk(KERN_ERR "%s%d: adapter self-test failed.\n",
|
||||
dev->name, instance);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// dprintk((KERN_ERR "aac_rx_init: BBB\n"));
|
||||
/*
|
||||
* Check to see if the board panic'd while booting.
|
||||
*/
|
||||
if (rx_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
|
||||
printk(KERN_ERR "%s%d: adapter kernel panic'd.\n",
|
||||
dev->name, instance);
|
||||
return -1;
|
||||
}
|
||||
start = jiffies;
|
||||
|
||||
// dprintk((KERN_ERR "aac_rx_init: DDD\n"));
|
||||
/*
|
||||
* Wait for the adapter to be up and running. Wait up to 3 minutes
|
||||
*/
|
||||
while (!(rx_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING))
|
||||
{
|
||||
if(time_after(jiffies, start+180*HZ))
|
||||
{
|
||||
status = rx_readl(dev, IndexRegs.Mailbox[7]) >> 16;
|
||||
printk(KERN_ERR "%s%d: adapter kernel failed to start,"
|
||||
"init status = %ld.\n", dev->name,
|
||||
instance, status);
|
||||
return -1;
|
||||
}
|
||||
// dprintk((KERN_ERR "aac_rx_init: XXX\n"));
|
||||
|
||||
#if 0
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
schedule_timeout(1);
|
||||
#else
|
||||
/* XXX SMH: no sleeping for us (we're the xen idle task) */
|
||||
mdelay(50);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// dprintk((KERN_ERR "aac_rx_init: ZZZ!\n"));
|
||||
if (request_irq(dev->scsi_host_ptr->irq, aac_rx_intr,
|
||||
SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev) < 0)
|
||||
{
|
||||
printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
|
||||
name, instance);
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* Fill in the function dispatch table.
|
||||
*/
|
||||
dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter;
|
||||
dev->a_ops.adapter_enable_int = aac_rx_enable_interrupt;
|
||||
dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt;
|
||||
dev->a_ops.adapter_notify = aac_rx_notify_adapter;
|
||||
dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
|
||||
|
||||
if (aac_init_adapter(dev) == NULL)
|
||||
return -1;
|
||||
#ifdef TRY_TASKLET
|
||||
aac_command_tasklet.data = (unsigned long)dev;
|
||||
tasklet_enable(&aac_command_tasklet);
|
||||
#else
|
||||
/*
|
||||
* Start any kernel threads needed
|
||||
*/
|
||||
dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread,
|
||||
dev, 0);
|
||||
#endif
|
||||
unsigned long start;
|
||||
unsigned long status;
|
||||
int instance;
|
||||
const char * name;
|
||||
|
||||
/*
|
||||
* Tell the adapter that all is configured, and it can start
|
||||
* accepting requests
|
||||
*/
|
||||
aac_rx_start_adapter(dev);
|
||||
return 0;
|
||||
dev->devnum = num;
|
||||
instance = dev->id;
|
||||
name = dev->name;
|
||||
|
||||
/*
|
||||
* Map in the registers from the adapter.
|
||||
*/
|
||||
if((dev->regs.rx = (struct rx_registers *)ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL)
|
||||
{
|
||||
printk(KERN_WARNING "aacraid: unable to map i960.\n" );
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* Check to see if the board failed any self tests.
|
||||
*/
|
||||
if (rx_readl(dev, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
|
||||
printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance);
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* Check to see if the board panic'd while booting.
|
||||
*/
|
||||
if (rx_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
|
||||
printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", dev->name, instance);
|
||||
return -1;
|
||||
}
|
||||
start = jiffies;
|
||||
/*
|
||||
* Wait for the adapter to be up and running. Wait up to 3 minutes
|
||||
*/
|
||||
while (!(rx_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING))
|
||||
{
|
||||
if(time_after(jiffies, start+180*HZ))
|
||||
{
|
||||
status = rx_readl(dev, IndexRegs.Mailbox[7]) >> 16;
|
||||
printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %ld.\n", dev->name, instance, status);
|
||||
return -1;
|
||||
}
|
||||
#if 0
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
schedule_timeout(1);
|
||||
#else
|
||||
/* XXX SMH: no sleeping for us (we're the xen idle task) */
|
||||
mdelay(50);
|
||||
#endif
|
||||
}
|
||||
if (request_irq(dev->scsi_host_ptr->irq, aac_rx_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0)
|
||||
{
|
||||
printk(KERN_ERR "%s%d: Interrupt unavailable.\n", name, instance);
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* Fill in the function dispatch table.
|
||||
*/
|
||||
dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter;
|
||||
dev->a_ops.adapter_enable_int = aac_rx_enable_interrupt;
|
||||
dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt;
|
||||
dev->a_ops.adapter_notify = aac_rx_notify_adapter;
|
||||
dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
|
||||
|
||||
if (aac_init_adapter(dev) == NULL)
|
||||
return -1;
|
||||
#ifdef TRY_TASKLET
|
||||
aac_command_tasklet.data = (unsigned long)dev;
|
||||
tasklet_enable(&aac_command_tasklet);
|
||||
#else
|
||||
/*
|
||||
* Start any kernel threads needed
|
||||
*/
|
||||
dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0);
|
||||
if(dev->thread_pid < 0)
|
||||
{
|
||||
printk(KERN_ERR "aacraid: Unable to create rx thread.\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Tell the adapter that all is configured, and it can start
|
||||
* accepting requests
|
||||
*/
|
||||
aac_rx_start_adapter(dev);
|
||||
return 0;
|
||||
}
|
||||
@@ -28,18 +28,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xeno/config.h>
|
||||
#include <xeno/kernel.h>
|
||||
#include <xeno/init.h>
|
||||
#include <xeno/types.h>
|
||||
#include <xeno/sched.h>
|
||||
/* #include <xeno/pci.h> */
|
||||
/* #include <xeno/spinlock.h> */
|
||||
/* #include <xeno/slab.h> */
|
||||
#include <xeno/blk.h>
|
||||
#include <xeno/delay.h>
|
||||
/* #include <xeno/completion.h> */
|
||||
/* #include <asm/semaphore.h> */
|
||||
#include <linux/config.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/blk.h>
|
||||
#include <linux/delay.h>
|
||||
/*#include <linux/completion.h>*/
|
||||
/*#include <asm/semaphore.h>*/
|
||||
#include "scsi.h"
|
||||
#include "hosts.h"
|
||||
|
||||
@@ -235,9 +235,9 @@ static int sa_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *ret)
|
||||
#if 0
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
schedule_timeout(1);
|
||||
#else
|
||||
mdelay(100);
|
||||
#endif
|
||||
mdelay(100);
|
||||
|
||||
}
|
||||
|
||||
if (ok != 1)
|
||||
@@ -353,7 +353,7 @@ int aac_sa_init(struct aac_dev *dev, unsigned long devnum)
|
||||
* Wait for the adapter to be up and running. Wait up to 3 minutes.
|
||||
*/
|
||||
while (!(sa_readl(dev, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
|
||||
if (time_after(start+180*HZ, jiffies)) {
|
||||
if (time_after(jiffies, start+180*HZ)) {
|
||||
status = sa_readl(dev, Mailbox7) >> 16;
|
||||
printk(KERN_WARNING "%s%d: adapter kernel failed to start, init status = %d.\n", name, instance, le32_to_cpu(status));
|
||||
return -1;
|
||||
@@ -361,8 +361,9 @@ int aac_sa_init(struct aac_dev *dev, unsigned long devnum)
|
||||
#if 0
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
schedule_timeout(1);
|
||||
#else
|
||||
mdelay(100);
|
||||
#endif
|
||||
mdelay(100);
|
||||
}
|
||||
|
||||
dprintk(("ATIRQ\n"));
|
||||
@@ -392,8 +393,11 @@ int aac_sa_init(struct aac_dev *dev, unsigned long devnum)
|
||||
* Start any kernel threads needed
|
||||
*/
|
||||
dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0);
|
||||
if (dev->thread_pid < 0) {
|
||||
printk(KERN_ERR "aacraid: Unable to create command thread.\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Tell the adapter that all is configure, and it can start
|
||||
* accepting requests
|
||||
|
||||