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. ...@@ -827,6 +827,7 @@ The interface functions are listed below in alphabetical order.
Summary: Summary:
bios_param - fetch head, sector, cylinder info for a disk bios_param - fetch head, sector, cylinder info for a disk
detect - detects HBAs this driver wants to control 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_abort_handler - abort given command
eh_bus_reset_handler - issue SCSI bus reset eh_bus_reset_handler - issue SCSI bus reset
eh_device_reset_handler - issue SCSI device reset eh_device_reset_handler - issue SCSI device reset
...@@ -894,6 +895,32 @@ Details: ...@@ -894,6 +895,32 @@ Details:
int detect(struct scsi_host_template * shtp) 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 * eh_abort_handler - abort command associated with scp
* @scp: identifies command to be aborted * @scp: identifies command to be aborted
......
...@@ -332,7 +332,7 @@ NCR_700_detect(struct scsi_host_template *tpnt, ...@@ -332,7 +332,7 @@ NCR_700_detect(struct scsi_host_template *tpnt,
tpnt->can_queue = NCR_700_COMMAND_SLOTS_PER_HOST; tpnt->can_queue = NCR_700_COMMAND_SLOTS_PER_HOST;
tpnt->sg_tablesize = NCR_700_SG_SEGMENTS; tpnt->sg_tablesize = NCR_700_SG_SEGMENTS;
tpnt->cmd_per_lun = NCR_700_CMD_PER_LUN; 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_configure = NCR_700_slave_configure;
tpnt->slave_destroy = NCR_700_slave_destroy; tpnt->slave_destroy = NCR_700_slave_destroy;
......
...@@ -10,20 +10,22 @@ the original). ...@@ -10,20 +10,22 @@ the original).
Supported Cards/Chipsets 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 Quad Channel
Dell PERC 2/Si Dell PERC 2/Si
Dell PERC 3/Si Dell PERC 3/Si
Dell PERC 3/Di Dell PERC 3/Di
Dell CERC 2
HP NetRAID-4M HP NetRAID-4M
ADAPTEC 2120S
ADAPTEC 2200S
ADAPTEC 5400S
Legend S220 Legend S220
Legend S230 Legend S230
Adaptec 3230S
Adaptec 3240S
ASR-2020S PCI-X
AAR-2410SA SATA
People People
------------------------- -------------------------
...@@ -46,7 +48,7 @@ Adaptec Unix OEM Product Group ...@@ -46,7 +48,7 @@ Adaptec Unix OEM Product Group
Mailing List 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) http://mbserver.adaptec.com/ (Currently more Community Support than Devel Support)
Also note this is very different to Brian's original driver Also note this is very different to Brian's original driver
so don't expect him to support it. so don't expect him to support it.
......
...@@ -2,3 +2,5 @@ o Testing ...@@ -2,3 +2,5 @@ o Testing
o More testing o More testing
o Feature request: display the firmware/bios/etc revisions in the o Feature request: display the firmware/bios/etc revisions in the
/proc info /proc info
o Drop irq_mask, basically unused
o I/O size increase
This diff is collapsed.
...@@ -6,14 +6,12 @@ ...@@ -6,14 +6,12 @@
* D E F I N E S * D E F I N E S
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define MAXIMUM_NUM_CONTAINERS 31 #define MAXIMUM_NUM_CONTAINERS 32
#define MAXIMUM_NUM_ADAPTERS 8 #define MAXIMUM_NUM_ADAPTERS 8
#define AAC_NUM_FIB 578 #define AAC_NUM_FIB (256 + 64)
//#define AAC_NUM_IO_FIB 512
#define AAC_NUM_IO_FIB 100 #define AAC_NUM_IO_FIB 100
#define AAC_MAX_TARGET (MAXIMUM_NUM_CONTAINERS+1)
#define AAC_MAX_LUN (8) #define AAC_MAX_LUN (8)
#define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff) #define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff)
...@@ -22,6 +20,11 @@ ...@@ -22,6 +20,11 @@
* These macros convert from physical channels to virtual channels * 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_phys_to_logical(x) (x+1)
#define aac_logical_to_phys(x) (x?x-1:0) #define aac_logical_to_phys(x) (x?x-1:0)
...@@ -73,7 +76,7 @@ struct diskparm ...@@ -73,7 +76,7 @@ struct diskparm
#define FT_SOCK 6 /* socket */ #define FT_SOCK 6 /* socket */
#define FT_FIFO 7 /* fifo */ #define FT_FIFO 7 /* fifo */
#define FT_FILESYS 8 /* ADAPTEC's "FSA"(tm) filesystem */ #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_SLICE 10 /* virtual disk - raw volume - slice */
#define FT_PARTITION 11 /* FSA partition - carved out of a slice - building block for containers */ #define FT_PARTITION 11 /* FSA partition - carved out of a slice - building block for containers */
#define FT_VOLUME 12 /* Container - Volume Set */ #define FT_VOLUME 12 /* Container - Volume Set */
...@@ -433,7 +436,7 @@ struct adapter_ops ...@@ -433,7 +436,7 @@ struct adapter_ops
struct aac_driver_ident struct aac_driver_ident
{ {
int (*init)(struct aac_dev *dev, unsigned long num); int (*init)(struct aac_dev *dev);
char * name; char * name;
char * vname; char * vname;
char * model; char * model;
...@@ -596,6 +599,9 @@ struct rx_inbound { ...@@ -596,6 +599,9 @@ struct rx_inbound {
#define InboundMailbox2 IndexRegs.Mailbox[2] #define InboundMailbox2 IndexRegs.Mailbox[2]
#define InboundMailbox3 IndexRegs.Mailbox[3] #define InboundMailbox3 IndexRegs.Mailbox[3]
#define InboundMailbox4 IndexRegs.Mailbox[4] #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_0 cpu_to_le32(0x00000001)
#define INBOUNDDOORBELL_1 cpu_to_le32(0x00000002) #define INBOUNDDOORBELL_1 cpu_to_le32(0x00000002)
...@@ -825,9 +831,8 @@ struct aac_dev ...@@ -825,9 +831,8 @@ struct aac_dev
} regs; } regs;
u32 OIMR; /* Mask Register Cache */ u32 OIMR; /* Mask Register Cache */
/* /*
* The following is the number of the individual adapter * AIF thread states
*/ */
u32 devnum;
u32 aif_thread; u32 aif_thread;
struct completion aif_completion; struct completion aif_completion;
struct aac_adapter_info adapter_info; struct aac_adapter_info adapter_info;
...@@ -839,19 +844,19 @@ struct aac_dev ...@@ -839,19 +844,19 @@ struct aac_dev
}; };
#define AllocateAndMapFibSpace(dev, MapFibContext) \ #define AllocateAndMapFibSpace(dev, MapFibContext) \
dev->a_ops.AllocateAndMapFibSpace(dev, MapFibContext) (dev)->a_ops.AllocateAndMapFibSpace(dev, MapFibContext)
#define UnmapAndFreeFibSpace(dev, MapFibContext) \ #define UnmapAndFreeFibSpace(dev, MapFibContext) \
dev->a_ops.UnmapAndFreeFibSpace(dev, MapFibContext) (dev)->a_ops.UnmapAndFreeFibSpace(dev, MapFibContext)
#define aac_adapter_interrupt(dev) \ #define aac_adapter_interrupt(dev) \
dev->a_ops.adapter_interrupt(dev) (dev)->a_ops.adapter_interrupt(dev)
#define aac_adapter_notify(dev, event) \ #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) \ #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) \ #define aac_adapter_disable_int(dev, event) \
dev->a_ops.adapter_disable_int(dev, event) dev->a_ops.adapter_disable_int(dev, event)
...@@ -1023,7 +1028,7 @@ struct aac_srb ...@@ -1023,7 +1028,7 @@ struct aac_srb
{ {
u32 function; u32 function;
u32 channel; u32 channel;
u32 target; u32 id;
u32 lun; u32 lun;
u32 timeout; u32 timeout;
u32 flags; u32 flags;
...@@ -1212,7 +1217,7 @@ struct aac_query_disk ...@@ -1212,7 +1217,7 @@ struct aac_query_disk
{ {
s32 cnum; s32 cnum;
s32 bus; s32 bus;
s32 target; s32 id;
s32 lun; s32 lun;
u32 valid; u32 valid;
u32 locked; u32 locked;
...@@ -1323,6 +1328,7 @@ extern struct aac_common aac_config; ...@@ -1323,6 +1328,7 @@ extern struct aac_common aac_config;
#define WRITE_PERMANENT_PARAMETERS cpu_to_le32(0x0000000b) #define WRITE_PERMANENT_PARAMETERS cpu_to_le32(0x0000000b)
#define HOST_CRASHING cpu_to_le32(0x0000000d) #define HOST_CRASHING cpu_to_le32(0x0000000d)
#define SEND_SYNCHRONOUS_FIB cpu_to_le32(0x0000000c) #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 GET_ADAPTER_PROPERTIES cpu_to_le32(0x00000019)
#define RE_INIT_ADAPTER cpu_to_le32(0x000000ee) #define RE_INIT_ADAPTER cpu_to_le32(0x000000ee)
...@@ -1347,14 +1353,16 @@ extern struct aac_common aac_config; ...@@ -1347,14 +1353,16 @@ extern struct aac_common aac_config;
* Phases are bit oriented. It is NOT valid to have multiple bits set * Phases are bit oriented. It is NOT valid to have multiple bits set
*/ */
#define SELF_TEST_FAILED cpu_to_le32(0x00000004) #define SELF_TEST_FAILED (cpu_to_le32(0x00000004))
#define KERNEL_UP_AND_RUNNING cpu_to_le32(0x00000080) #define MONITOR_PANIC (cpu_to_le32(0x00000020))
#define KERNEL_PANIC cpu_to_le32(0x00000100) #define KERNEL_UP_AND_RUNNING (cpu_to_le32(0x00000080))
#define KERNEL_PANIC (cpu_to_le32(0x00000100))
/* /*
* Doorbell bit defines * Doorbell bit defines
*/ */
#define DoorBellSyncCmdAvailable cpu_to_le32(1<<0) // Host -> Adapter
#define DoorBellPrintfDone cpu_to_le32(1<<5) // Host -> Adapter #define DoorBellPrintfDone cpu_to_le32(1<<5) // Host -> Adapter
#define DoorBellAdapterNormCmdReady cpu_to_le32(1<<1) // Adapter -> Host #define DoorBellAdapterNormCmdReady cpu_to_le32(1<<1) // Adapter -> Host
#define DoorBellAdapterNormRespReady cpu_to_le32(1<<2) // Adapter -> Host #define DoorBellAdapterNormRespReady cpu_to_le32(1<<2) // Adapter -> Host
...@@ -1368,9 +1376,22 @@ extern struct aac_common aac_config; ...@@ -1368,9 +1376,22 @@ extern struct aac_common aac_config;
*/ */
#define AifCmdEventNotify 1 /* Notify of event */ #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 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 AifCmdAPIReport 3 /* Report from other user of API */
#define AifCmdDriverNotify 4 /* Notify host driver of event */ #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 AifReqJobList 100 /* Gets back complete job list */
#define AifReqJobsForCtr 101 /* Gets back jobs for specific container */ #define AifReqJobsForCtr 101 /* Gets back jobs for specific container */
#define AifReqJobsForScsi 102 /* Gets back jobs for specific SCSI device */ #define AifReqJobsForScsi 102 /* Gets back jobs for specific SCSI device */
...@@ -1427,9 +1448,9 @@ int aac_get_containers(struct aac_dev *dev); ...@@ -1427,9 +1448,9 @@ int aac_get_containers(struct aac_dev *dev);
int aac_scsi_cmd(struct scsi_cmnd *cmd); int aac_scsi_cmd(struct scsi_cmnd *cmd);
int aac_dev_ioctl(struct aac_dev *dev, int cmd, void *arg); 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_do_ioctl(struct aac_dev * dev, int cmd, void *arg);
int aac_rx_init(struct aac_dev *dev, unsigned long devNumber); int aac_rx_init(struct aac_dev *dev);
int aac_rkt_init(struct aac_dev *dev, unsigned long devNumber); int aac_rkt_init(struct aac_dev *dev);
int aac_sa_init(struct aac_dev *dev, unsigned long devNumber); int aac_sa_init(struct aac_dev *dev);
unsigned int aac_response_normal(struct aac_queue * q); unsigned int aac_response_normal(struct aac_queue * q);
unsigned int aac_command_normal(struct aac_queue * q); unsigned int aac_command_normal(struct aac_queue * q);
int aac_command_thread(struct aac_dev * dev); int aac_command_thread(struct aac_dev * dev);
......
...@@ -431,7 +431,7 @@ int aac_send_raw_srb(struct aac_dev* dev, void* arg) ...@@ -431,7 +431,7 @@ int aac_send_raw_srb(struct aac_dev* dev, void* arg)
// Fix up srb for endian and force some values // Fix up srb for endian and force some values
srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this
srbcmd->channel = cpu_to_le32(srbcmd->channel); 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->lun = cpu_to_le32(srbcmd->lun);
srbcmd->flags = cpu_to_le32(srbcmd->flags); srbcmd->flags = cpu_to_le32(srbcmd->flags);
srbcmd->timeout = cpu_to_le32(srbcmd->timeout); 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 ...@@ -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 * with the math overloading past 32 bits, thus we must limit this
* field. * field.
* *
* FIXME: this assumes the memory is mapped zero->n, which isnt * This assumes the memory is mapped zero->n, which isnt
* always true on real computers. * 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) { if ((num_physpages << (PAGE_SHIFT - 12)) <= AAC_MAX_HOSTPHYSMEMPAGES) {
init->HostPhysMemPages = init->HostPhysMemPages =
cpu_to_le32(num_physpages << (PAGE_SHIFT-12)); cpu_to_le32(num_physpages << (PAGE_SHIFT-12));
} else { } else
#endif
{
init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES); init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
} }
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
* Abstract: Linux Driver entry module for Adaptec RAID Array Controller * 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_DRIVER_BUILD_DATE __DATE__
#define AAC_DRIVERNAME "aacraid" #define AAC_DRIVERNAME "aacraid"
...@@ -355,13 +355,15 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) ...@@ -355,13 +355,15 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
struct Scsi_Host * host = dev->host; struct Scsi_Host * host = dev->host;
struct scsi_cmnd * command; struct scsi_cmnd * command;
int count; int count;
struct aac_dev * aac;
unsigned long flags; unsigned long flags;
printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n", printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n",
AAC_DRIVERNAME); 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", printk(KERN_ERR "%s: Host adapter appears dead\n",
AAC_DRIVERNAME); AAC_DRIVERNAME);
return -ENODEV; return -ENODEV;
...@@ -381,15 +383,13 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) ...@@ -381,15 +383,13 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
} }
} }
spin_unlock_irqrestore(&dev->list_lock, flags); spin_unlock_irqrestore(&dev->list_lock, flags);
if (active)
break;
}
/* /*
* We can exit If all the commands are complete * We can exit If all the commands are complete
*/ */
if (active == 0) if (active == 0)
return SUCCESS; return SUCCESS;
}
spin_unlock_irq(host->host_lock); spin_unlock_irq(host->host_lock);
scsi_sleep(HZ); scsi_sleep(HZ);
spin_lock_irq(host->host_lock); spin_lock_irq(host->host_lock);
...@@ -461,7 +461,11 @@ static struct scsi_host_template aac_driver_template = { ...@@ -461,7 +461,11 @@ static struct scsi_host_template aac_driver_template = {
.this_id = 16, .this_id = 16,
.sg_tablesize = 16, .sg_tablesize = 16,
.max_sectors = 128, .max_sectors = 128,
#if (AAC_NUM_IO_FIB > 256)
.cmd_per_lun = 256,
#else
.cmd_per_lun = AAC_NUM_IO_FIB, .cmd_per_lun = AAC_NUM_IO_FIB,
#endif
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
}; };
...@@ -521,7 +525,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, ...@@ -521,7 +525,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
for (container = 0; container < MAXIMUM_NUM_CONTAINERS; container++) for (container = 0; container < MAXIMUM_NUM_CONTAINERS; container++)
fsa_dev_ptr->devname[container][0] = '\0'; 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; goto out_free_fibs;
/* /*
...@@ -552,7 +556,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, ...@@ -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 * dmb - we may need to move the setting of these parms somewhere else once
* we get a fib that can report the actual numbers * 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; shost->max_lun = AAC_MAX_LUN;
error = scsi_add_host(shost, &pdev->dev); error = scsi_add_host(shost, &pdev->dev);
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/time.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
...@@ -67,8 +68,8 @@ static irqreturn_t aac_rkt_intr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -67,8 +68,8 @@ static irqreturn_t aac_rkt_intr(int irq, void *dev_id, struct pt_regs *regs)
rkt_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); rkt_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
} }
else if (bellbits & DoorBellAdapterNormCmdReady) { else if (bellbits & DoorBellAdapterNormCmdReady) {
aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
} }
else if (bellbits & DoorBellAdapterNormRespReady) { else if (bellbits & DoorBellAdapterNormRespReady) {
aac_response_normal(&dev->queues->queue[HostNormRespQueue]); aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
...@@ -305,7 +306,7 @@ static void aac_rkt_start_adapter(struct aac_dev *dev) ...@@ -305,7 +306,7 @@ static void aac_rkt_start_adapter(struct aac_dev *dev)
struct aac_init *init; struct aac_init *init;
init = dev->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 * Tell the adapter we are back and up and running so it will scan
* its command queues and enable our interrupts * its command queues and enable our interrupts
...@@ -341,12 +342,38 @@ static int aac_rkt_check_health(struct aac_dev *dev) ...@@ -341,12 +342,38 @@ static int aac_rkt_check_health(struct aac_dev *dev)
if (status & SELF_TEST_FAILED) if (status & SELF_TEST_FAILED)
return -1; return -1;
/* /*
* Check to see if the board panic'd while booting. * Check to see if the board panic'd.
*/ */
if (status & KERNEL_PANIC) 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)) if (!(status & KERNEL_UP_AND_RUNNING))
return -3; return -3;
...@@ -354,26 +381,24 @@ static int aac_rkt_check_health(struct aac_dev *dev) ...@@ -354,26 +381,24 @@ static int aac_rkt_check_health(struct aac_dev *dev)
* Everything is OK * Everything is OK
*/ */
return 0; return 0;
} /* aac_rkt_check_health */ }
/** /**
* aac_rkt_init - initialize an i960 based AAC card * aac_rkt_init - initialize an i960 based AAC card
* @dev: device to configure * @dev: device to configure
* @devnum: adapter number
* *
* Allocate and set up resources for the i960 based AAC variants. The * Allocate and set up resources for the i960 based AAC variants. The
* device_interface in the commregion will be allocated and linked * device_interface in the commregion will be allocated and linked
* to the comm region. * 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 start;
unsigned long status; unsigned long status;
int instance; int instance;
const char * name; const char * name;
dev->devnum = num;
instance = dev->id; instance = dev->id;
name = dev->name; name = dev->name;
...@@ -388,14 +413,21 @@ int aac_rkt_init(struct aac_dev *dev, unsigned long num) ...@@ -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. * 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); printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance);
return -1; 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. * 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); printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", dev->name, instance);
return -1; return -1;
} }
...@@ -403,7 +435,7 @@ int aac_rkt_init(struct aac_dev *dev, unsigned long num) ...@@ -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 * 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)) if(time_after(jiffies, start+180*HZ))
{ {
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/time.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
...@@ -67,8 +68,8 @@ static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -67,8 +68,8 @@ static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs)
rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
} }
else if (bellbits & DoorBellAdapterNormCmdReady) { else if (bellbits & DoorBellAdapterNormCmdReady) {
aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
} }
else if (bellbits & DoorBellAdapterNormRespReady) { else if (bellbits & DoorBellAdapterNormRespReady) {
aac_response_normal(&dev->queues->queue[HostNormRespQueue]); aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
...@@ -305,7 +306,7 @@ static void aac_rx_start_adapter(struct aac_dev *dev) ...@@ -305,7 +306,7 @@ static void aac_rx_start_adapter(struct aac_dev *dev)
struct aac_init *init; struct aac_init *init;
init = dev->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 * Tell the adapter we are back and up and running so it will scan
* its command queues and enable our interrupts * its command queues and enable our interrupts
...@@ -341,12 +342,36 @@ static int aac_rx_check_health(struct aac_dev *dev) ...@@ -341,12 +342,36 @@ static int aac_rx_check_health(struct aac_dev *dev)
if (status & SELF_TEST_FAILED) if (status & SELF_TEST_FAILED)
return -1; return -1;
/* /*
* Check to see if the board panic'd while booting. * Check to see if the board panic'd.
*/ */
if (status & KERNEL_PANIC) if (status & KERNEL_PANIC) {
return -2; 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)) if (!(status & KERNEL_UP_AND_RUNNING))
return -3; return -3;
...@@ -359,21 +384,19 @@ static int aac_rx_check_health(struct aac_dev *dev) ...@@ -359,21 +384,19 @@ static int aac_rx_check_health(struct aac_dev *dev)
/** /**
* aac_rx_init - initialize an i960 based AAC card * aac_rx_init - initialize an i960 based AAC card
* @dev: device to configure * @dev: device to configure
* @devnum: adapter number
* *
* Allocate and set up resources for the i960 based AAC variants. The * Allocate and set up resources for the i960 based AAC variants. The
* device_interface in the commregion will be allocated and linked * device_interface in the commregion will be allocated and linked
* to the comm region. * 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 start;
unsigned long status; unsigned long status;
int instance; int instance;
const char * name; const char * name;
dev->devnum = num;
instance = dev->id; instance = dev->id;
name = dev->name; name = dev->name;
...@@ -388,22 +411,30 @@ int aac_rx_init(struct aac_dev *dev, unsigned long num) ...@@ -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. * 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); printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance);
return -1; return -1;
} }
/* /*
* Check to see if the board panic'd while booting. * Check to see if the board panic'd while booting.
*/ */
if (rx_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_PANIC) { if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) {
printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", dev->name, instance); 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; return -1;
} }
start = jiffies; start = jiffies;
/* /*
* Wait for the adapter to be up and running. Wait up to 3 minutes * 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)) if(time_after(jiffies, start+180*HZ))
{ {
...@@ -435,6 +466,11 @@ int aac_rx_init(struct aac_dev *dev, unsigned long num) ...@@ -435,6 +466,11 @@ int aac_rx_init(struct aac_dev *dev, unsigned long num)
* Start any kernel threads needed * Start any kernel threads needed
*/ */
dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0); 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 * Tell the adapter that all is configured, and it can start
* accepting requests * accepting requests
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/time.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
...@@ -329,27 +330,24 @@ static int aac_sa_check_health(struct aac_dev *dev) ...@@ -329,27 +330,24 @@ static int aac_sa_check_health(struct aac_dev *dev)
* Everything is OK * Everything is OK
*/ */
return 0; return 0;
} /* aac_sa_check_health */ }
/** /**
* aac_sa_init - initialize an ARM based AAC card * aac_sa_init - initialize an ARM based AAC card
* @dev: device to configure * @dev: device to configure
* @devnum: adapter number
* *
* Allocate and set up resources for the ARM based AAC variants. The * Allocate and set up resources for the ARM based AAC variants. The
* device_interface in the commregion will be allocated and linked * device_interface in the commregion will be allocated and linked
* to the comm region. * 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 start;
unsigned long status; unsigned long status;
int instance; int instance;
const char *name; const char *name;
dev->devnum = devnum;
dprintk(("PREINST\n")); dprintk(("PREINST\n"));
instance = dev->id; instance = dev->id;
name = dev->name; name = dev->name;
......
...@@ -689,8 +689,6 @@ static DEFINE_PER_CPU(struct list_head, scsi_done_q); ...@@ -689,8 +689,6 @@ static DEFINE_PER_CPU(struct list_head, scsi_done_q);
*/ */
void scsi_done(struct scsi_cmnd *cmd) void scsi_done(struct scsi_cmnd *cmd)
{ {
unsigned long flags;
/* /*
* We don't have to worry about this one timing out any more. * We don't have to worry about this one timing out any more.
* If we are unable to remove the timer, then the command * If we are unable to remove the timer, then the command
...@@ -701,6 +699,14 @@ void scsi_done(struct scsi_cmnd *cmd) ...@@ -701,6 +699,14 @@ void scsi_done(struct scsi_cmnd *cmd)
*/ */
if (!scsi_delete_timer(cmd)) if (!scsi_delete_timer(cmd))
return; 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 * Set the serial numbers back to zero
......
...@@ -163,7 +163,7 @@ static struct { ...@@ -163,7 +163,7 @@ static struct {
{"Medion", "Flash XL MMC/SD", "2.6D", BLIST_FORCELUN}, {"Medion", "Flash XL MMC/SD", "2.6D", BLIST_FORCELUN},
{"MegaRAID", "LD", NULL, BLIST_FORCELUN}, {"MegaRAID", "LD", NULL, BLIST_FORCELUN},
{"MICROP", "4110", NULL, BLIST_NOTQ}, {"MICROP", "4110", NULL, BLIST_NOTQ},
{"MYLEX", "DACARMRB", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"MYLEX", "DACARMRB", "*", BLIST_REPORTLUN2},
{"nCipher", "Fastness Crypto", NULL, BLIST_FORCELUN}, {"nCipher", "Fastness Crypto", NULL, BLIST_FORCELUN},
{"NAKAMICH", "MJ-4.8S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"NAKAMICH", "MJ-4.8S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
{"NAKAMICH", "MJ-5.16S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"NAKAMICH", "MJ-5.16S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
...@@ -177,7 +177,7 @@ static struct { ...@@ -177,7 +177,7 @@ static struct {
{"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN}, {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN},
{"SGI", "RAID3", "*", BLIST_SPARSELUN}, {"SGI", "RAID3", "*", BLIST_SPARSELUN},
{"SGI", "RAID5", "*", BLIST_SPARSELUN}, {"SGI", "RAID5", "*", BLIST_SPARSELUN},
{"SGI", "TP9100", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"SGI", "TP9100", "*", BLIST_REPORTLUN2},
{"SMSC", "USB 2 HS-CF", NULL, BLIST_SPARSELUN}, {"SMSC", "USB 2 HS-CF", NULL, BLIST_SPARSELUN},
{"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN}, {"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN},
{"SONY", "TSL", NULL, BLIST_FORCELUN}, /* DDS3 & DDS4 autoloaders */ {"SONY", "TSL", NULL, BLIST_FORCELUN}, /* DDS3 & DDS4 autoloaders */
......
...@@ -162,6 +162,24 @@ int scsi_delete_timer(struct scsi_cmnd *scmd) ...@@ -162,6 +162,24 @@ int scsi_delete_timer(struct scsi_cmnd *scmd)
void scsi_times_out(struct scsi_cmnd *scmd) void scsi_times_out(struct scsi_cmnd *scmd)
{ {
scsi_log_completion(scmd, TIMEOUT_ERROR); 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))) { if (unlikely(!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) {
panic("Error handler thread not present at %p %p %s %d", panic("Error handler thread not present at %p %p %s %d",
scmd, scmd->device->host, __FILE__, __LINE__); scmd, scmd->device->host, __FILE__, __LINE__);
......
...@@ -82,6 +82,7 @@ extern int scsi_insert_special_req(struct scsi_request *sreq, int); ...@@ -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, extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
struct scsi_request *sreq); struct scsi_request *sreq);
extern void __scsi_release_request(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 #ifdef CONFIG_SCSI_LOGGING
void scsi_log_send(struct scsi_cmnd *cmd); void scsi_log_send(struct scsi_cmnd *cmd);
void scsi_log_completion(struct scsi_cmnd *cmd, int disposition); void scsi_log_completion(struct scsi_cmnd *cmd, int disposition);
......
...@@ -30,6 +30,12 @@ struct scsi_transport_template; ...@@ -30,6 +30,12 @@ struct scsi_transport_template;
#define DISABLE_CLUSTERING 0 #define DISABLE_CLUSTERING 0
#define ENABLE_CLUSTERING 1 #define ENABLE_CLUSTERING 1
enum scsi_eh_timer_return {
EH_NOT_HANDLED,
EH_HANDLED,
EH_RESET_TIMER,
};
struct scsi_host_template { struct scsi_host_template {
struct module *module; struct module *module;
...@@ -125,6 +131,20 @@ struct scsi_host_template { ...@@ -125,6 +131,20 @@ struct scsi_host_template {
int (* eh_bus_reset_handler)(struct scsi_cmnd *); int (* eh_bus_reset_handler)(struct scsi_cmnd *);
int (* eh_host_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 * Old EH handlers, no longer used. Make them warn the user of old
* drivers by using a wrong type * 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