Commit 311a8896 authored by James Bottomley's avatar James Bottomley

Merge mulgrave.(none):/home/jejb/BK/linux-2.5

into mulgrave.(none):/home/jejb/BK/scsi-misc-2.6
parents f092d184 ce270e32
......@@ -827,6 +827,7 @@ The interface functions are listed below in alphabetical order.
Summary:
bios_param - fetch head, sector, cylinder info for a disk
detect - detects HBAs this driver wants to control
eh_timed_out - notify the host that a command timer expired
eh_abort_handler - abort given command
eh_bus_reset_handler - issue SCSI bus reset
eh_device_reset_handler - issue SCSI device reset
......@@ -894,6 +895,32 @@ Details:
int detect(struct scsi_host_template * shtp)
/**
* eh_timed_out - The timer for the command has just fired
* @scp: identifies command timing out
*
* Returns:
*
* EH_HANDLED: I fixed the error, please complete the command
* EH_RESET_TIMER: I need more time, reset the timer and
* begin counting again
* EH_NOT_HANDLED Begin normal error recovery
*
* Locks: None held
*
* Calling context: interrupt
*
* Notes: This is to give the LLD an opportunity to do local recovery.
* This recovery is limited to determining if the outstanding command
* will ever complete. You may not abort and restart the command from
* this callback.
*
* Optionally defined in: LLD
**/
int eh_timed_out(struct scsi_cmnd * scp)
/**
* eh_abort_handler - abort command associated with scp
* @scp: identifies command to be aborted
......
......@@ -332,7 +332,7 @@ NCR_700_detect(struct scsi_host_template *tpnt,
tpnt->can_queue = NCR_700_COMMAND_SLOTS_PER_HOST;
tpnt->sg_tablesize = NCR_700_SG_SEGMENTS;
tpnt->cmd_per_lun = NCR_700_CMD_PER_LUN;
tpnt->use_clustering = DISABLE_CLUSTERING;
tpnt->use_clustering = ENABLE_CLUSTERING;
tpnt->slave_configure = NCR_700_slave_configure;
tpnt->slave_destroy = NCR_700_slave_destroy;
......
......@@ -10,20 +10,22 @@ the original).
Supported Cards/Chipsets
-------------------------
AAR-2410SA SATA
Adaptec 2120S
Adaptec 2200S
Adaptec 2230S
Adaptec 3230S
Adaptec 3240S
Adaptec 5400S
ASR-2020S PCI-X
Dell PERC 2 Quad Channel
Dell PERC 2/Si
Dell PERC 3/Si
Dell PERC 3/Di
Dell CERC 2
HP NetRAID-4M
ADAPTEC 2120S
ADAPTEC 2200S
ADAPTEC 5400S
Legend S220
Legend S230
Adaptec 3230S
Adaptec 3240S
ASR-2020S PCI-X
AAR-2410SA SATA
People
-------------------------
......@@ -46,7 +48,7 @@ Adaptec Unix OEM Product Group
Mailing List
-------------------------
linux-aacraid-devel@dell.com (Interested parties troll here)
linux-scsi@vger.kernel.org (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.
......
......@@ -2,3 +2,5 @@ o Testing
o More testing
o Feature request: display the firmware/bios/etc revisions in the
/proc info
o Drop irq_mask, basically unused
o I/O size increase
This diff is collapsed.
......@@ -6,14 +6,12 @@
* D E F I N E S
*----------------------------------------------------------------------------*/
#define MAXIMUM_NUM_CONTAINERS 31
#define MAXIMUM_NUM_CONTAINERS 32
#define MAXIMUM_NUM_ADAPTERS 8
#define AAC_NUM_FIB 578
//#define AAC_NUM_IO_FIB 512
#define AAC_NUM_FIB (256 + 64)
#define AAC_NUM_IO_FIB 100
#define AAC_MAX_TARGET (MAXIMUM_NUM_CONTAINERS+1)
#define AAC_MAX_LUN (8)
#define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff)
......@@ -21,7 +19,12 @@
/*
* These macros convert from physical channels to virtual channels
*/
#define CONTAINER_CHANNEL (0)
#define CONTAINER_CHANNEL (0)
#define ID_LUN_TO_CONTAINER(id, lun) (id)
#define CONTAINER_TO_CHANNEL(cont) (CONTAINER_CHANNEL)
#define CONTAINER_TO_ID(cont) (cont)
#define CONTAINER_TO_LUN(cont) (0)
#define aac_phys_to_logical(x) (x+1)
#define aac_logical_to_phys(x) (x?x-1:0)
......@@ -73,7 +76,7 @@ struct diskparm
#define FT_SOCK 6 /* socket */
#define FT_FIFO 7 /* fifo */
#define FT_FILESYS 8 /* ADAPTEC's "FSA"(tm) filesystem */
#define FT_DRIVE 9 /* physical disk - addressable in scsi by bus/target/lun */
#define FT_DRIVE 9 /* physical disk - addressable in scsi by bus/id/lun */
#define FT_SLICE 10 /* virtual disk - raw volume - slice */
#define FT_PARTITION 11 /* FSA partition - carved out of a slice - building block for containers */
#define FT_VOLUME 12 /* Container - Volume Set */
......@@ -433,7 +436,7 @@ struct adapter_ops
struct aac_driver_ident
{
int (*init)(struct aac_dev *dev, unsigned long num);
int (*init)(struct aac_dev *dev);
char * name;
char * vname;
char * model;
......@@ -596,6 +599,9 @@ struct rx_inbound {
#define InboundMailbox2 IndexRegs.Mailbox[2]
#define InboundMailbox3 IndexRegs.Mailbox[3]
#define InboundMailbox4 IndexRegs.Mailbox[4]
#define InboundMailbox5 IndexRegs.Mailbox[5]
#define InboundMailbox6 IndexRegs.Mailbox[6]
#define InboundMailbox7 IndexRegs.Mailbox[7]
#define INBOUNDDOORBELL_0 cpu_to_le32(0x00000001)
#define INBOUNDDOORBELL_1 cpu_to_le32(0x00000002)
......@@ -825,9 +831,8 @@ struct aac_dev
} regs;
u32 OIMR; /* Mask Register Cache */
/*
* The following is the number of the individual adapter
* AIF thread states
*/
u32 devnum;
u32 aif_thread;
struct completion aif_completion;
struct aac_adapter_info adapter_info;
......@@ -839,19 +844,19 @@ struct aac_dev
};
#define AllocateAndMapFibSpace(dev, MapFibContext) \
dev->a_ops.AllocateAndMapFibSpace(dev, MapFibContext)
(dev)->a_ops.AllocateAndMapFibSpace(dev, MapFibContext)
#define UnmapAndFreeFibSpace(dev, MapFibContext) \
dev->a_ops.UnmapAndFreeFibSpace(dev, MapFibContext)
(dev)->a_ops.UnmapAndFreeFibSpace(dev, MapFibContext)
#define aac_adapter_interrupt(dev) \
dev->a_ops.adapter_interrupt(dev)
(dev)->a_ops.adapter_interrupt(dev)
#define aac_adapter_notify(dev, event) \
dev->a_ops.adapter_notify(dev, event)
(dev)->a_ops.adapter_notify(dev, event)
#define aac_adapter_enable_int(dev, event) \
dev->a_ops.adapter_enable_int(dev, event)
(dev)->a_ops.adapter_enable_int(dev, event)
#define aac_adapter_disable_int(dev, event) \
dev->a_ops.adapter_disable_int(dev, event)
......@@ -1023,7 +1028,7 @@ struct aac_srb
{
u32 function;
u32 channel;
u32 target;
u32 id;
u32 lun;
u32 timeout;
u32 flags;
......@@ -1212,7 +1217,7 @@ struct aac_query_disk
{
s32 cnum;
s32 bus;
s32 target;
s32 id;
s32 lun;
u32 valid;
u32 locked;
......@@ -1323,6 +1328,7 @@ extern struct aac_common aac_config;
#define WRITE_PERMANENT_PARAMETERS cpu_to_le32(0x0000000b)
#define HOST_CRASHING cpu_to_le32(0x0000000d)
#define SEND_SYNCHRONOUS_FIB cpu_to_le32(0x0000000c)
#define COMMAND_POST_RESULTS cpu_to_le32(0x00000014)
#define GET_ADAPTER_PROPERTIES cpu_to_le32(0x00000019)
#define RE_INIT_ADAPTER cpu_to_le32(0x000000ee)
......@@ -1347,14 +1353,16 @@ extern struct aac_common aac_config;
* Phases are bit oriented. It is NOT valid to have multiple bits set
*/
#define SELF_TEST_FAILED cpu_to_le32(0x00000004)
#define KERNEL_UP_AND_RUNNING cpu_to_le32(0x00000080)
#define KERNEL_PANIC cpu_to_le32(0x00000100)
#define SELF_TEST_FAILED (cpu_to_le32(0x00000004))
#define MONITOR_PANIC (cpu_to_le32(0x00000020))
#define KERNEL_UP_AND_RUNNING (cpu_to_le32(0x00000080))
#define KERNEL_PANIC (cpu_to_le32(0x00000100))
/*
* Doorbell bit defines
*/
#define DoorBellSyncCmdAvailable cpu_to_le32(1<<0) // Host -> Adapter
#define DoorBellPrintfDone cpu_to_le32(1<<5) // Host -> Adapter
#define DoorBellAdapterNormCmdReady cpu_to_le32(1<<1) // Adapter -> Host
#define DoorBellAdapterNormRespReady cpu_to_le32(1<<2) // Adapter -> Host
......@@ -1368,9 +1376,22 @@ extern struct aac_common aac_config;
*/
#define AifCmdEventNotify 1 /* Notify of event */
#define AifEnConfigChange 3 /* Adapter configuration change */
#define AifEnContainerChange 4 /* Container configuration change */
#define AifEnDeviceFailure 5 /* SCSI device failed */
#define AifEnAddContainer 15 /* A new array was created */
#define AifEnDeleteContainer 16 /* A container was deleted */
#define AifEnExpEvent 23 /* Firmware Event Log */
#define AifExeFirmwarePanic 3 /* Firmware Event Panic */
#define AifHighPriority 3 /* Highest Priority Event */
#define AifCmdJobProgress 2 /* Progress report */
#define AifJobCtrZero 101 /* Array Zero progress */
#define AifJobStsSuccess 1 /* Job completes */
#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 extend 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 */
......@@ -1427,9 +1448,9 @@ int aac_get_containers(struct aac_dev *dev);
int aac_scsi_cmd(struct scsi_cmnd *cmd);
int aac_dev_ioctl(struct aac_dev *dev, int cmd, void *arg);
int aac_do_ioctl(struct aac_dev * dev, int cmd, void *arg);
int aac_rx_init(struct aac_dev *dev, unsigned long devNumber);
int aac_rkt_init(struct aac_dev *dev, unsigned long devNumber);
int aac_sa_init(struct aac_dev *dev, unsigned long devNumber);
int aac_rx_init(struct aac_dev *dev);
int aac_rkt_init(struct aac_dev *dev);
int aac_sa_init(struct aac_dev *dev);
unsigned int aac_response_normal(struct aac_queue * q);
unsigned int aac_command_normal(struct aac_queue * q);
int aac_command_thread(struct aac_dev * dev);
......
......@@ -431,7 +431,7 @@ int aac_send_raw_srb(struct aac_dev* dev, void* arg)
// Fix up srb for endian and force some values
srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this
srbcmd->channel = cpu_to_le32(srbcmd->channel);
srbcmd->target = cpu_to_le32(srbcmd->target);
srbcmd->id = cpu_to_le32(srbcmd->id);
srbcmd->lun = cpu_to_le32(srbcmd->lun);
srbcmd->flags = cpu_to_le32(srbcmd->flags);
srbcmd->timeout = cpu_to_le32(srbcmd->timeout);
......
......@@ -95,13 +95,18 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
* with the math overloading past 32 bits, thus we must limit this
* field.
*
* FIXME: this assumes the memory is mapped zero->n, which isnt
* always true on real computers.
* This assumes the memory is mapped zero->n, which isnt
* always true on real computers. It also has some slight problems
* with the GART on x86-64. I've btw never tried DMA from PCI space
* on this platform but don't be suprised if its problematic.
*/
#ifndef CONFIG_GART_IOMMU
if ((num_physpages << (PAGE_SHIFT - 12)) <= AAC_MAX_HOSTPHYSMEMPAGES) {
init->HostPhysMemPages =
cpu_to_le32(num_physpages << (PAGE_SHIFT-12));
} else {
} else
#endif
{
init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
}
......
......@@ -27,7 +27,7 @@
* Abstract: Linux Driver entry module for Adaptec RAID Array Controller
*/
#define AAC_DRIVER_VERSION "1.1.2-lk1"
#define AAC_DRIVER_VERSION "1.1.2-lk2"
#define AAC_DRIVER_BUILD_DATE __DATE__
#define AAC_DRIVERNAME "aacraid"
......@@ -355,13 +355,15 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
struct Scsi_Host * host = dev->host;
struct scsi_cmnd * command;
int count;
struct aac_dev * aac;
unsigned long flags;
printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n",
AAC_DRIVERNAME);
if (aac_adapter_check_health((struct aac_dev *)host->hostdata)) {
aac = (struct aac_dev *)host->hostdata;
if (aac_adapter_check_health(aac)) {
printk(KERN_ERR "%s: Host adapter appears dead\n",
AAC_DRIVERNAME);
return -ENODEV;
......@@ -381,15 +383,13 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
}
}
spin_unlock_irqrestore(&dev->list_lock, flags);
if (active)
break;
/*
* We can exit If all the commands are complete
*/
if (active == 0)
return SUCCESS;
}
/*
* We can exit If all the commands are complete
*/
if (active == 0)
return SUCCESS;
spin_unlock_irq(host->host_lock);
scsi_sleep(HZ);
spin_lock_irq(host->host_lock);
......@@ -461,7 +461,11 @@ static struct scsi_host_template aac_driver_template = {
.this_id = 16,
.sg_tablesize = 16,
.max_sectors = 128,
#if (AAC_NUM_IO_FIB > 256)
.cmd_per_lun = 256,
#else
.cmd_per_lun = AAC_NUM_IO_FIB,
#endif
.use_clustering = ENABLE_CLUSTERING,
};
......@@ -521,7 +525,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
for (container = 0; container < MAXIMUM_NUM_CONTAINERS; container++)
fsa_dev_ptr->devname[container][0] = '\0';
if ((*aac_drivers[index].init)(aac , shost->unique_id))
if ((*aac_drivers[index].init)(aac))
goto out_free_fibs;
/*
......@@ -552,7 +556,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
* dmb - we may need to move the setting of these parms somewhere else once
* we get a fib that can report the actual numbers
*/
shost->max_id = AAC_MAX_TARGET;
shost->max_id = MAXIMUM_NUM_CONTAINERS;
shost->max_lun = AAC_MAX_LUN;
error = scsi_add_host(shost, &pdev->dev);
......
......@@ -38,6 +38,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/completion.h>
#include <linux/time.h>
#include <linux/interrupt.h>
#include <asm/semaphore.h>
......@@ -67,8 +68,8 @@ static irqreturn_t aac_rkt_intr(int irq, void *dev_id, struct pt_regs *regs)
rkt_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
}
else if (bellbits & DoorBellAdapterNormCmdReady) {
aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
}
else if (bellbits & DoorBellAdapterNormRespReady) {
aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
......@@ -305,7 +306,7 @@ static void aac_rkt_start_adapter(struct aac_dev *dev)
struct aac_init *init;
init = dev->init;
init->HostElapsedSeconds = cpu_to_le32(jiffies/HZ);
init->HostElapsedSeconds = cpu_to_le32(get_seconds());
/*
* Tell the adapter we are back and up and running so it will scan
* its command queues and enable our interrupts
......@@ -341,12 +342,38 @@ static int aac_rkt_check_health(struct aac_dev *dev)
if (status & SELF_TEST_FAILED)
return -1;
/*
* Check to see if the board panic'd while booting.
* Check to see if the board panic'd.
*/
if (status & KERNEL_PANIC)
return -2;
{
char * buffer = kmalloc(512, GFP_KERNEL|__GFP_DMA);
struct POSTSTATUS {
u32 Post_Command;
u32 Post_Address;
} * post = kmalloc(sizeof(struct POSTSTATUS), GFP_KERNEL);
dma_addr_t paddr = pci_map_single(dev->pdev, post, sizeof(struct POSTSTATUS), 2);
dma_addr_t baddr = pci_map_single(dev->pdev, buffer, 512, 1);
u32 status = -1;
int ret = -2;
memset(buffer, 0, 512);
post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS);
post->Post_Address = cpu_to_le32(baddr);
rkt_writel(dev, MUnit.IMRx[0], cpu_to_le32(paddr));
rkt_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, &status);
pci_unmap_single(dev->pdev, paddr, sizeof(struct POSTSTATUS),2);
kfree(post);
if ((buffer[0] == '0') && (buffer[1] == 'x')) {
ret = (buffer[2] <= '9') ? (buffer[2] - '0') : (buffer[2] - 'A' + 10);
ret <<= 4;
ret += (buffer[3] <= '9') ? (buffer[3] - '0') : (buffer[3] - 'A' + 10);
}
pci_unmap_single(dev->pdev, baddr, 512, 1);
kfree(buffer);
return ret;
}
/*
* Wait for the adapter to be up and running. Wait up to 3 minutes
* Wait for the adapter to be up and running.
*/
if (!(status & KERNEL_UP_AND_RUNNING))
return -3;
......@@ -354,26 +381,24 @@ static int aac_rkt_check_health(struct aac_dev *dev)
* Everything is OK
*/
return 0;
} /* aac_rkt_check_health */
}
/**
* aac_rkt_init - initialize an i960 based AAC card
* @dev: device to configure
* @devnum: adapter number
*
* Allocate and set up resources for the i960 based AAC variants. The
* device_interface in the commregion will be allocated and linked
* to the comm region.
*/
int aac_rkt_init(struct aac_dev *dev, unsigned long num)
int aac_rkt_init(struct aac_dev *dev)
{
unsigned long start;
unsigned long status;
int instance;
const char * name;
dev->devnum = num;
instance = dev->id;
name = dev->name;
......@@ -388,14 +413,21 @@ int aac_rkt_init(struct aac_dev *dev, unsigned long num)
/*
* Check to see if the board failed any self tests.
*/
if (rkt_readl(dev, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
if (rkt_readl(dev, MUnit.OMRx[0]) & SELF_TEST_FAILED) {
printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance);
return -1;
}
/*
* Check to see if the monitor panic'd while booting.
*/
if (rkt_readl(dev, MUnit.OMRx[0]) & MONITOR_PANIC) {
printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance);
return -1;
}
/*
* Check to see if the board panic'd while booting.
*/
if (rkt_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
if (rkt_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) {
printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", dev->name, instance);
return -1;
}
......@@ -403,7 +435,7 @@ int aac_rkt_init(struct aac_dev *dev, unsigned long num)
/*
* Wait for the adapter to be up and running. Wait up to 3 minutes
*/
while (!(rkt_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING))
while (!(rkt_readl(dev, MUnit.OMRx[0]) & KERNEL_UP_AND_RUNNING))
{
if(time_after(jiffies, start+180*HZ))
{
......
......@@ -38,6 +38,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/completion.h>
#include <linux/time.h>
#include <linux/interrupt.h>
#include <asm/semaphore.h>
......@@ -67,8 +68,8 @@ static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs)
rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
}
else if (bellbits & DoorBellAdapterNormCmdReady) {
aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
}
else if (bellbits & DoorBellAdapterNormRespReady) {
aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
......@@ -305,7 +306,7 @@ static void aac_rx_start_adapter(struct aac_dev *dev)
struct aac_init *init;
init = dev->init;
init->HostElapsedSeconds = cpu_to_le32(jiffies/HZ);
init->HostElapsedSeconds = cpu_to_le32(get_seconds());
/*
* Tell the adapter we are back and up and running so it will scan
* its command queues and enable our interrupts
......@@ -341,12 +342,36 @@ static int aac_rx_check_health(struct aac_dev *dev)
if (status & SELF_TEST_FAILED)
return -1;
/*
* Check to see if the board panic'd while booting.
* Check to see if the board panic'd.
*/
if (status & KERNEL_PANIC)
return -2;
if (status & KERNEL_PANIC) {
char * buffer = kmalloc(512, GFP_KERNEL);
struct POSTSTATUS {
u32 Post_Command;
u32 Post_Address;
} * post = kmalloc(sizeof(struct POSTSTATUS), GFP_KERNEL);
dma_addr_t paddr = pci_map_single(dev->pdev, post, sizeof(struct POSTSTATUS), 2);
dma_addr_t baddr = pci_map_single(dev->pdev, buffer, 512, 1);
u32 status = -1;
int ret = -2;
memset(buffer, 0, 512);
post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS);
post->Post_Address = cpu_to_le32(baddr);
rx_writel(dev, MUnit.IMRx[0], cpu_to_le32(paddr));
rx_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, &status);
pci_unmap_single(dev->pdev, paddr, sizeof(struct POSTSTATUS), 2);
kfree(post);
if ((buffer[0] == '0') && (buffer[1] == 'x')) {
ret = (buffer[2] <= '9') ? (buffer[2] - '0') : (buffer[2] - 'A' + 10);
ret <<= 4;
ret += (buffer[3] <= '9') ? (buffer[3] - '0') : (buffer[3] - 'A' + 10);
}
pci_unmap_single(dev->pdev, baddr, 512, 1);
kfree(buffer);
return ret;
}
/*
* Wait for the adapter to be up and running. Wait up to 3 minutes
* Wait for the adapter to be up and running.
*/
if (!(status & KERNEL_UP_AND_RUNNING))
return -3;
......@@ -359,21 +384,19 @@ static int aac_rx_check_health(struct aac_dev *dev)
/**
* aac_rx_init - initialize an i960 based AAC card
* @dev: device to configure
* @devnum: adapter number
*
* Allocate and set up resources for the i960 based AAC variants. The
* device_interface in the commregion will be allocated and linked
* to the comm region.
*/
int aac_rx_init(struct aac_dev *dev, unsigned long num)
int aac_rx_init(struct aac_dev *dev)
{
unsigned long start;
unsigned long status;
int instance;
const char * name;
dev->devnum = num;
instance = dev->id;
name = dev->name;
......@@ -388,22 +411,30 @@ int aac_rx_init(struct aac_dev *dev, unsigned long num)
/*
* Check to see if the board failed any self tests.
*/
if (rx_readl(dev, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
if (rx_readl(dev, MUnit.OMRx[0]) & 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);
if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) {
printk(KERN_ERR "%s%d: adapter kernel panic.\n", dev->name, instance);
return -1;
}
/*
* Check to see if the monitor panic'd while booting.
*/
if (rx_readl(dev, MUnit.OMRx[0]) & MONITOR_PANIC) {
printk(KERN_ERR "%s%d: adapter monitor panic.\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))
while ((!(rx_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING))
|| (!(rx_readl(dev, MUnit.OMRx[0]) & KERNEL_UP_AND_RUNNING)))
{
if(time_after(jiffies, start+180*HZ))
{
......@@ -435,6 +466,11 @@ int aac_rx_init(struct aac_dev *dev, unsigned long num)
* 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;
}
/*
* Tell the adapter that all is configured, and it can start
* accepting requests
......
......@@ -38,6 +38,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/completion.h>
#include <linux/time.h>
#include <linux/interrupt.h>
#include <asm/semaphore.h>
......@@ -329,27 +330,24 @@ static int aac_sa_check_health(struct aac_dev *dev)
* Everything is OK
*/
return 0;
} /* aac_sa_check_health */
}
/**
* aac_sa_init - initialize an ARM based AAC card
* @dev: device to configure
* @devnum: adapter number
*
* Allocate and set up resources for the ARM based AAC variants. The
* device_interface in the commregion will be allocated and linked
* to the comm region.
*/
int aac_sa_init(struct aac_dev *dev, unsigned long devnum)
int aac_sa_init(struct aac_dev *dev)
{
unsigned long start;
unsigned long status;
int instance;
const char *name;
dev->devnum = devnum;
dprintk(("PREINST\n"));
instance = dev->id;
name = dev->name;
......
......@@ -689,8 +689,6 @@ static DEFINE_PER_CPU(struct list_head, scsi_done_q);
*/
void scsi_done(struct scsi_cmnd *cmd)
{
unsigned long flags;
/*
* We don't have to worry about this one timing out any more.
* If we are unable to remove the timer, then the command
......@@ -701,6 +699,14 @@ void scsi_done(struct scsi_cmnd *cmd)
*/
if (!scsi_delete_timer(cmd))
return;
__scsi_done(cmd);
}
/* Private entry to scsi_done() to complete a command when the timer
* isn't running --- used by scsi_times_out */
void __scsi_done(struct scsi_cmnd *cmd)
{
unsigned long flags;
/*
* Set the serial numbers back to zero
......
......@@ -163,7 +163,7 @@ static struct {
{"Medion", "Flash XL MMC/SD", "2.6D", BLIST_FORCELUN},
{"MegaRAID", "LD", NULL, BLIST_FORCELUN},
{"MICROP", "4110", NULL, BLIST_NOTQ},
{"MYLEX", "DACARMRB", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
{"MYLEX", "DACARMRB", "*", BLIST_REPORTLUN2},
{"nCipher", "Fastness Crypto", NULL, BLIST_FORCELUN},
{"NAKAMICH", "MJ-4.8S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
{"NAKAMICH", "MJ-5.16S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
......@@ -177,7 +177,7 @@ static struct {
{"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN},
{"SGI", "RAID3", "*", BLIST_SPARSELUN},
{"SGI", "RAID5", "*", BLIST_SPARSELUN},
{"SGI", "TP9100", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
{"SGI", "TP9100", "*", BLIST_REPORTLUN2},
{"SMSC", "USB 2 HS-CF", NULL, BLIST_SPARSELUN},
{"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN},
{"SONY", "TSL", NULL, BLIST_FORCELUN}, /* DDS3 & DDS4 autoloaders */
......
......@@ -162,6 +162,24 @@ int scsi_delete_timer(struct scsi_cmnd *scmd)
void scsi_times_out(struct scsi_cmnd *scmd)
{
scsi_log_completion(scmd, TIMEOUT_ERROR);
if (scmd->device->host->hostt->eh_timed_out)
switch (scmd->device->host->hostt->eh_timed_out(scmd)) {
case EH_HANDLED:
__scsi_done(scmd);
return;
case EH_RESET_TIMER:
/* This allows a single retry even of a command
* with allowed == 0 */
if (scmd->retries++ > scmd->allowed)
break;
scsi_add_timer(scmd, scmd->timeout_per_command,
scsi_times_out);
return;
case EH_NOT_HANDLED:
break;
}
if (unlikely(!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) {
panic("Error handler thread not present at %p %p %s %d",
scmd, scmd->device->host, __FILE__, __LINE__);
......
......@@ -82,6 +82,7 @@ extern int scsi_insert_special_req(struct scsi_request *sreq, int);
extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
struct scsi_request *sreq);
extern void __scsi_release_request(struct scsi_request *sreq);
extern void __scsi_done(struct scsi_cmnd *cmd);
#ifdef CONFIG_SCSI_LOGGING
void scsi_log_send(struct scsi_cmnd *cmd);
void scsi_log_completion(struct scsi_cmnd *cmd, int disposition);
......
......@@ -30,6 +30,12 @@ struct scsi_transport_template;
#define DISABLE_CLUSTERING 0
#define ENABLE_CLUSTERING 1
enum scsi_eh_timer_return {
EH_NOT_HANDLED,
EH_HANDLED,
EH_RESET_TIMER,
};
struct scsi_host_template {
struct module *module;
......@@ -125,6 +131,20 @@ struct scsi_host_template {
int (* eh_bus_reset_handler)(struct scsi_cmnd *);
int (* eh_host_reset_handler)(struct scsi_cmnd *);
/*
* This is an optional routine to notify the host that the scsi
* timer just fired. The returns tell the timer routine what to
* do about this:
*
* EH_HANDLED: I fixed the error, please complete the command
* EH_RESET_TIMER: I need more time, reset the timer and
* begin counting again
* EH_NOT_HANDLED Begin normal error recovery
*
* Status: OPTIONAL
*/
enum scsi_eh_timer_return (* eh_timed_out)(struct scsi_cmnd *);
/*
* Old EH handlers, no longer used. Make them warn the user of old
* drivers by using a wrong type
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment