patch-2.4.20 linux-2.4.20/drivers/scsi/ips.c
Next file: linux-2.4.20/drivers/scsi/ips.h
Previous file: linux-2.4.20/drivers/scsi/imm.c
Back to the patch index
Back to the overall index
- Lines: 1281
- Date:
Thu Nov 28 15:53:14 2002
- Orig file:
linux-2.4.19/drivers/scsi/ips.c
- Orig date:
Fri Aug 2 17:39:44 2002
diff -urN linux-2.4.19/drivers/scsi/ips.c linux-2.4.20/drivers/scsi/ips.c
@@ -2,6 +2,8 @@
/* ips.c -- driver for the IBM ServeRAID controller */
/* */
/* Written By: Keith Mitchell, IBM Corporation */
+/* Jack Hammer, Adaptec, Inc. */
+/* David Jeffery, Adaptec, Inc. */
/* */
/* Copyright (C) 2000 IBM Corporation */
/* */
@@ -40,7 +42,7 @@
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* */
/* Bugs/Comments/Suggestions about this driver should be mailed to: */
-/* ipslinux@us.ibm.com */
+/* ipslinux@adaptec.com */
/* */
/* For system support issues, contact your local IBM Customer support. */
/* Directions to find IBM Customer Support for each country can be found at: */
@@ -121,6 +123,9 @@
/* 4.90.08 - Data Corruption if First Scatter Gather Element is > 64K */
/* 4.90.11 - Don't actually RESET unless it's physically required */
/* - Remove unused compile options */
+/* 5.00.01 - Sarasota ( 5i ) adapters must always be scanned first */
+/* - Get rid on IOCTL_NEW_COMMAND code */
+/* - Add Extended DCDB Commands for Tape Support in 5I */
/*****************************************************************************/
/*
@@ -193,8 +198,9 @@
/*
* DRIVER_VER
*/
-#define IPS_VERSION_HIGH "4.90"
-#define IPS_VERSION_LOW ".18 "
+#define IPS_VERSION_HIGH "5.10"
+#define IPS_VERSION_LOW ".21 "
+
#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
struct proc_dir_entry proc_scsi_ips = {
@@ -262,17 +268,32 @@
static int ips_cd_boot = 0; /* Booting from ServeRAID Manager CD */
static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */
static int ips_FlashDataInUse = 0; /* CD Boot - Flash Data In Use Flag */
+static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */
IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Table */
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+ /* This table describes any / all ServeRAID Adapters */
static struct pci_device_id ips_pci_table[] __devinitdata = {
- { 0x1014, 0x002E, PCI_ANY_ID,PCI_ANY_ID, 0, 0, 0 },
- { 0x1014, 0x01BD, PCI_ANY_ID,PCI_ANY_ID, 0, 0, 0 },
+ { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
+ { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
{ 0, }
};
+ /* This table describes only Sarasota ( ServeRAID 5i ) Adapters */
+ static struct pci_device_id ips_pci_table_5i[] __devinitdata = {
+ { 0x1014, 0x01BD, PCI_ANY_ID, 0x259, 0, 0 },
+ { 0x1014, 0x01BD, PCI_ANY_ID, 0x258, 0, 0 },
+ { 0, }
+ };
+
+ /* This table describes all i960 Adapters */
+ static struct pci_device_id ips_pci_table_i960[] __devinitdata = {
+ { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
+ { 0, }
+ };
+
MODULE_DEVICE_TABLE( pci, ips_pci_table );
static char ips_hot_plug_name[] = "ips";
@@ -285,7 +306,22 @@
id_table: ips_pci_table,
probe: ips_insert_device,
remove: __devexit_p(ips_remove_device),
+ };
+
+ struct pci_driver ips_pci_driver_5i = {
+ name: ips_hot_plug_name,
+ id_table: ips_pci_table_5i,
+ probe: ips_insert_device,
+ remove: __devexit_p(ips_remove_device),
};
+
+ struct pci_driver ips_pci_driver_i960 = {
+ name: ips_hot_plug_name,
+ id_table: ips_pci_table_i960,
+ probe: ips_insert_device,
+ remove: __devexit_p(ips_remove_device),
+ };
+
#endif
/*
@@ -307,8 +343,8 @@
"ServeRAID 4L",
"ServeRAID 4Mx",
"ServeRAID 4Lx",
- "ServeRAID 5I",
- "ServeRAID 5I"
+ "ServeRAID 5i",
+ "ServeRAID 5i"
};
static struct notifier_block ips_notifier = {
@@ -322,7 +358,7 @@
IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT,
IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK,
IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT,
+IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT,
IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_IN,
@@ -385,7 +421,6 @@
void do_ipsintr(int, void *, struct pt_regs *);
static int ips_hainit(ips_ha_t *);
static int ips_map_status(ips_ha_t *, ips_scb_t *, ips_stat_t *);
-static int ips_send(ips_ha_t *, ips_scb_t *, ips_scb_callback);
static int ips_send_wait(ips_ha_t *, ips_scb_t *, int, int);
static int ips_send_cmd(ips_ha_t *, ips_scb_t *);
static int ips_online(ips_ha_t *, ips_scb_t *);
@@ -424,13 +459,10 @@
static int ips_erase_bios_memio(ips_ha_t *);
static int ips_program_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
static int ips_verify_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
-static void ips_flash_bios_section(void *);
-static void ips_flash_bios_segment(void *);
static int ips_flash_copperhead(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
static int ips_flash_bios(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
static int ips_flash_firmware(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
static void ips_free_flash_copperhead(ips_ha_t *ha);
-static void ips_scheduled_flash_bios(void *);
static void ips_get_bios_version(ips_ha_t *, int);
static void ips_identify_controller(ips_ha_t *);
static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *);
@@ -472,7 +504,6 @@
static int ips_is_passthru(Scsi_Cmnd *);
static int ips_make_passthru(ips_ha_t *, Scsi_Cmnd *, ips_scb_t *, int);
static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
-static int ips_newusrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *);
int ips_proc_info(char *, char **, off_t, int, int, int);
@@ -516,6 +547,7 @@
{"nommap", &ips_force_memio, 0},
{"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE},
{"cdboot", &ips_cd_boot, 0},
+ {"maxcmds", &MaxLiteCmds, 32},
};
/* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */
@@ -543,7 +575,6 @@
}
return (1);
-}
#else
@@ -578,10 +609,14 @@
}
}
}
-}
#endif
+}
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+__setup("ips=", ips_setup);
+#endif
/****************************************************************************/
/* */
@@ -622,6 +657,7 @@
uint32_t maskbar;
uint8_t barnum;
#endif
+ uint32_t IsDead;
METHOD_TRACE("ips_detect", 1);
@@ -706,12 +742,23 @@
/**********************************************************************************/
/* For Kernel Versions 2.4 or greater, use new PCI ( Hot Pluggable ) architecture */
/**********************************************************************************/
+
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
spin_unlock_irq(&io_request_lock);
- pci_module_init(&ips_pci_driver);
+
+ /* By definition, a Sarasota ( 5i ) Adapter MUST be enumerated first or the */
+ /* server may not boot properly. The adapters must be enumerated in exactly */
+ /* the same order as ServeRAID BIOS for the machine to come up properly. */
+
+ pci_module_init(&ips_pci_driver_5i); /* Ask for 5i Adapters First */
+ if (ips_num_controllers) /* If there is a 5i Adapter */
+ pci_module_init(&ips_pci_driver_i960); /* Get all i960's next */
+ pci_module_init(&ips_pci_driver); /* Get all remaining Adapters */
+ /* ( in normal BUS order ) */
spin_lock_irq(&io_request_lock);
if (ips_num_controllers > 0)
register_reboot_notifier(&ips_notifier);
+
return (ips_num_controllers);
#endif
@@ -1111,6 +1158,14 @@
else
ha->func.issue = ips_issue_copperhead;
}
+
+ /* If Morpheus appears dead, reset it */
+ if ( IPS_IS_MORPHEUS( ha ) ) {
+ IsDead = readl( ha->mem_ptr + IPS_REG_I960_MSG1 );
+ if ( IsDead == 0xDEADBEEF ) {
+ ips_reset_morpheus( ha );
+ }
+ }
/*
* Initialize the card if it isn't already
@@ -1639,10 +1694,6 @@
}
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
-__setup("ips=", ips_setup);
-#endif
-
/****************************************************************************/
/* */
/* Routine Name: ips_queue */
@@ -1717,21 +1768,7 @@
if (ips_is_passthru(SC)) {
ips_copp_wait_item_t *scratch;
-
- /* The IPS_IOCTL_NEW_COMMAND is only used to flash an adapter. This should */
- /* never happen when the adapter is active. Just in case, check here, and */
- /* reject the command if anything else is going on. */
- if (SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
- if (ha->scb_activelist.count != 0) {
- /* printk( KERN_WARNING "New IOCTL Cmd Return BUSY: %d Cmds Active\n", */
- /* ha->scb_activelist.count ); */
- SC->result = DID_BUS_BUSY << 16;
- done(SC);
-
- return (0);
- }
- }
-
+
/* A Reset IOCTL is only sent by the ServeRAID boot CD in extreme cases. */
/* There can never be any system activity ( network or disk ), but check */
/* anyway just as a good practice. */
@@ -1770,6 +1807,9 @@
else
ips_putq_wait_tail(&ha->scb_waitlist, SC);
+ if(ha->scb_waitlist.count + ha->scb_activelist.count > 32)
+ mod_timer(&SC->eh_timeout, jiffies + 120 * HZ);
+
IPS_HA_LOCK(cpu_flags);
if ((!test_bit(IPS_IN_INTR, &ha->flags)) &&
(!test_bit(IPS_IN_ABORT, &ha->flags)) &&
@@ -1779,43 +1819,7 @@
} else {
IPS_HA_UNLOCK(cpu_flags);
}
-
- /*
- * If this request was a new style IOCTL wait
- * for it to finish.
- *
- * NOTE: we relinquished the lock above so this should
- * not cause contention problems
- */
- if (ips_is_passthru(SC) && SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
- char *user_area;
- char *kern_area;
- uint32_t datasize;
-
- /* free io_request_lock */
- spin_unlock_irq(&io_request_lock);
-
- /* wait for the command to finish */
- down(&ha->ioctl_sem);
-
- /* command finished -- copy back */
- user_area = *((char **) &SC->cmnd[4]);
- kern_area = ha->ioctl_data;
- datasize = *((uint32_t *) &SC->cmnd[8]);
-
- if (datasize) {
- if (copy_to_user(user_area, kern_area, datasize) > 0) {
- DEBUG_VAR(1, "(%s%d) passthru failed - unable to copy out user data",
- ips_name, ha->host_num);
- SC->result = DID_ERROR << 16;
- }
- }
-
- /* reobtain the lock */
- spin_lock_irq(&io_request_lock);
- SC->scsi_done(SC);
- }
-
+
/* If We were using the CD Boot Flash Buffer, Restore the Old Values */
if ( ips_FlashData == ha->ioctl_data ) {
ha->ioctl_data = ha->flash_data;
@@ -2214,7 +2218,7 @@
if (!SC)
return (0);
- if (((SC->cmnd[0] == IPS_IOCTL_COMMAND) || (SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND)) &&
+ if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) &&
(SC->channel == 0) &&
(SC->target == IPS_ADAPTER_ID) &&
(SC->lun == 0) &&
@@ -2361,314 +2365,13 @@
if(ha->device_id == IPS_DEVICEID_COPPERHEAD &&
pt->CoppCP.cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW)
return ips_flash_copperhead(ha, pt, scb);
- if (ips_usrcmd(ha, pt, scb))
- return (IPS_SUCCESS);
- else
- return (IPS_FAILURE);
- } else if (SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
-
- if (SC->request_bufflen < (sizeof(ips_passthru_t))) {
- /* wrong size */
- DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
- ips_name, ha->host_num);
-
- SC->result = DID_ERROR << 16;
-
- return (IPS_FAILURE);
- }
-
- /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can */
- /* avoid allocating a huge buffer per adapter ( which can fail ). */
- if ( (ips_FlashData) &&
- (pt->CmdBSize == IPS_IMAGE_SIZE) &&
- (ips_FlashDataInUse == 0) ) {
- ips_FlashDataInUse = 1;
- ha->flash_data = ha->ioctl_data;
- ha->flash_order = ha->ioctl_order;
- ha->flash_datasize = ha->ioctl_datasize;
- ha->ioctl_data = ips_FlashData;
- ha->ioctl_order = 7;
- ha->ioctl_datasize = IPS_IMAGE_SIZE;
- }
-
- /*
- * IPSSEND flashing BIOS
- */
- if ((pt->CoppCP.cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW) &&
- (pt->CoppCP.cmd.flashfw.type == 1) &&
- (pt->CoppCP.cmd.flashfw.direction == 2) &&
- (ha->device_id == IPS_DEVICEID_COPPERHEAD)) {
- struct tq_struct task;
- IPS_FLASH_DATA flash_data;
-
- /* We only support one packet */
- if (pt->CoppCP.cmd.flashfw.total_packets != 1) {
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- SC->result = DID_ERROR << 16;
-
- return (IPS_FAILURE);
- }
-
- /* copy in the size/buffer ptr from the scsi command */
- memcpy(&pt->CmdBuffer, &SC->cmnd[4], 4);
- memcpy(&pt->CmdBSize, &SC->cmnd[8], 4);
-
- if (pt->CmdBSize > le32_to_cpu(pt->CoppCP.cmd.flashfw.count)) {
- pt->CmdBSize = le32_to_cpu(pt->CoppCP.cmd.flashfw.count);
- } else {
- /* ERROR: Command/Buffer mismatch */
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- SC->result = DID_ERROR << 16;
-
- return (IPS_FAILURE);
- }
-
- if ((!ha->func.programbios) ||
- (!ha->func.erasebios) ||
- (!ha->func.verifybios)) {
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- SC->result = DID_ERROR << 16;
-
- return (IPS_FAILURE);
- }
-
- /* must have a buffer */
- if ((!pt->CmdBSize) || (!pt->CmdBuffer)) {
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- SC->result = DID_ERROR << 16;
-
- return (IPS_FAILURE);
- }
-
- /* make sure buffer is big enough */
- if (pt->CmdBSize > ha->ioctl_datasize) {
- void *bigger_struct;
- uint32_t count;
- uint32_t order;
-
- /* try to allocate a bigger struct */
- for (count = PAGE_SIZE, order = 0;
- count < pt->CmdBSize;
- order++, count <<= 1);
-
- bigger_struct = (void *) __get_free_pages(GFP_ATOMIC, order);
- if (bigger_struct) {
- /* free the old memory */
- free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
-
- /* use the new memory */
- ha->ioctl_data = (char *) bigger_struct;
- ha->ioctl_order = order;
- ha->ioctl_datasize = count;
- } else {
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- SC->result = DID_ERROR << 16;
-
- spin_unlock(&ha->ips_lock);
-
- return (IPS_FAILURE);
- }
- }
-
- /* copy in the buffer */
- if (copy_from_user(ha->ioctl_data, pt->CmdBuffer, pt->CmdBSize) > 0) {
- DEBUG_VAR(1, "(%s%d) flash bios failed - unable to copy user buffer",
- ips_name, ha->host_num);
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- SC->result = DID_ERROR << 16;
-
- return (IPS_FAILURE);
- }
-
- flash_data.userbuffer = pt->CmdBuffer;
- flash_data.usersize = pt->CmdBSize;
- flash_data.kernbuffer = ha->ioctl_data;
- flash_data.kernsize = ha->ioctl_datasize;
- flash_data.offset = 0;
- flash_data.SC = (void *) SC;
- flash_data.pt = (void *) pt;
- flash_data.ha = (void *) ha;
- sema_init( &ha->flash_ioctl_sem, 0 );
- flash_data.sem = &ha->flash_ioctl_sem;
-
- task.sync = 0;
- task.routine = ips_scheduled_flash_bios;
- task.data = (void *) &flash_data;
-
- /* Unlock the master lock */
- spin_unlock_irq(&io_request_lock);
-
- queue_task(&task, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-
- /* Wait for the flash to complete */
- down(&ha->flash_ioctl_sem);
-
- /* Obtain the master lock */
- spin_lock_irq(&io_request_lock);
-
- return (flash_data.retcode);
- }
-
- /*
- * IPSSEND flashing BIOS in sectioned mode
- */
- if ((pt->CoppCP.cmd.flashbios.op_code == IPS_CMD_RW_BIOSFW) &&
- (pt->CoppCP.cmd.flashbios.type == 1) &&
- (pt->CoppCP.cmd.flashbios.direction == 4) &&
- (ha->device_id == IPS_DEVICEID_COPPERHEAD)) {
- struct tq_struct task;
- IPS_FLASH_DATA flash_data;
-
- /* copy in the size/buffer ptr from the scsi command */
- memcpy(&pt->CmdBuffer, &SC->cmnd[4], 4);
- memcpy(&pt->CmdBSize, &SC->cmnd[8], 4);
-
- if (pt->CmdBSize > le32_to_cpu(pt->CoppCP.cmd.flashbios.count)) {
- pt->CmdBSize = le32_to_cpu(pt->CoppCP.cmd.flashbios.count);
- } else {
- /* ERROR: Command/Buffer mismatch */
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- SC->result = DID_ERROR << 16;
-
- return (IPS_FAILURE);
- }
-
- /* Update the Card BIOS */
- if ((!ha->func.programbios) ||
- (!ha->func.erasebios) ||
- (!ha->func.verifybios)) {
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- SC->result = DID_ERROR << 16;
-
- return (IPS_FAILURE);
- }
-
- /* must have a buffer */
- if ((!pt->CmdBSize) || (!pt->CmdBuffer)) {
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- SC->result = DID_ERROR << 16;
-
- return (IPS_FAILURE);
- }
-
- /* make sure buffer is big enough */
- if (pt->CmdBSize > ha->ioctl_datasize) {
- void *bigger_struct;
- uint32_t count;
- uint32_t order;
-
- /* try to allocate a bigger struct */
- for (count = PAGE_SIZE, order = 0;
- count < pt->CmdBSize;
- order++, count <<= 1);
- bigger_struct = (void *) __get_free_pages(GFP_ATOMIC, order);
- if (bigger_struct) {
- /* free the old memory */
- free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
-
- /* use the new memory */
- ha->ioctl_data = (char *) bigger_struct;
- ha->ioctl_order = order;
- ha->ioctl_datasize = count;
- } else {
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- SC->result = DID_ERROR << 16;
-
- spin_unlock(&ha->ips_lock);
-
- return (IPS_FAILURE);
- }
- }
-
- /* copy in the buffer */
- if (copy_from_user(ha->ioctl_data, pt->CmdBuffer, pt->CmdBSize) > 0) {
- DEBUG_VAR(1, "(%s%d) flash bios failed - unable to copy user buffer",
- ips_name, ha->host_num);
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- SC->result = DID_ERROR << 16;
-
- return (EFAULT);
- }
-
- flash_data.userbuffer = pt->CmdBuffer;
- flash_data.usersize = pt->CmdBSize;
- flash_data.kernbuffer = ha->ioctl_data;
- flash_data.kernsize = ha->ioctl_datasize;
- flash_data.offset = le32_to_cpu(pt->CoppCP.cmd.flashbios.offset);
- flash_data.SC = (void *) SC;
- flash_data.pt = (void *) pt;
- flash_data.ha = (void *) ha;
- sema_init( &ha->flash_ioctl_sem, 0 );
- flash_data.sem = &ha->flash_ioctl_sem;
-
- task.sync = 0;
- task.routine = ips_flash_bios_section;
- task.data = (void *) &flash_data;
-
- /* Unlock the master lock */
- spin_unlock_irq(&io_request_lock);
-
- queue_task(&task, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-
- /* Wait for the flash to complete */
- down(&ha->flash_ioctl_sem);
-
- /* Obtain the master lock */
- spin_lock_irq(&io_request_lock);
-
- return (flash_data.retcode);
- }
-
- if ((pt->CoppCP.cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW) &&
- (pt->CoppCP.cmd.flashfw.type == 1) &&
- (pt->CoppCP.cmd.flashfw.direction == 3) &&
- (ha->device_id == IPS_DEVICEID_COPPERHEAD)) {
- /* Erase the Card BIOS */
- if (!ha->func.erasebios) {
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- SC->result = DID_ERROR << 16;
-
- return (IPS_FAILURE);
- }
-
- if ((*ha->func.erasebios)(ha)) {
- DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
- ips_name, ha->host_num);
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- SC->result = DID_ERROR << 16;
-
- return (IPS_FAILURE);
- }
-
- SC->result = DID_OK << 16;
- pt->BasicStatus = 0x00;
- pt->ExtendedStatus = 0x00;
-
- return (IPS_SUCCESS_IMM);
- }
-
- if (ips_newusrcmd(ha, pt, scb))
+ if (ips_usrcmd(ha, pt, scb))
return (IPS_SUCCESS);
else
return (IPS_FAILURE);
- }
-
+ }
+
break;
} /* end switch */
@@ -2848,149 +2551,6 @@
/****************************************************************************/
/* */
-/* Routine Name: ips_scheduled_flash_bios */
-/* */
-/* Routine Description: */
-/* */
-/* Flash the BIOS on a Copperhead style controller */
-/* To be called from a task queue */
-/* */
-/****************************************************************************/
-static void
-ips_scheduled_flash_bios(void *data) {
- ips_ha_t *ha;
- Scsi_Cmnd *SC;
- ips_passthru_t *pt;
- IPS_FLASH_DATA *fd;
-
- fd = (IPS_FLASH_DATA *) data;
- ha = (ips_ha_t *) fd->ha;
- pt = (ips_passthru_t *) fd->pt;
- SC = (Scsi_Cmnd *) fd->SC;
-
- /*
- * Set initial return codes
- */
- SC->result = DID_OK << 16;
- pt->BasicStatus = 0x00;
- pt->ExtendedStatus = 0x00;
- fd->retcode = IPS_SUCCESS_IMM;
-
- /*
- * Fix the size/ptr to account for the
- * flash header
- */
- fd->kernbuffer += 0xC0;
- fd->kernsize -= 0xC0;
- fd->userbuffer += 0xC0;
- fd->usersize -= 0xC0;
-
- if ((*ha->func.erasebios)(ha)) {
- DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
- ips_name, ha->host_num);
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- SC->result = DID_ERROR << 16;
- fd->retcode = IPS_FAILURE;
- up(fd->sem);
-
- return ;
- }
-
- ips_flash_bios_segment(data);
-
- if (fd->retcode == IPS_FAILURE)
- return ;
-
- if ((*ha->func.verifybios)(ha, fd->kernbuffer, fd->usersize, fd->offset)) {
- DEBUG_VAR(1, "(%s%d) flash bios failed - unable to verify flash",
- ips_name, ha->host_num);
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- SC->result = DID_ERROR << 16;
- fd->retcode = IPS_FAILURE;
- up(fd->sem);
-
- return ;
- }
-
- /* Tell them we are done */
- if (fd->retcode != IPS_FAILURE)
- up(fd->sem);
-}
-
-/****************************************************************************/
-/* */
-/* Routine Name: ips_flash_bios_section */
-/* */
-/* Routine Description: */
-/* */
-/* wrapper for ips_flash_bios_segment that raises the semaphore */
-/* */
-/****************************************************************************/
-static void
-ips_flash_bios_section(void *data) {
- ips_ha_t *ha;
- Scsi_Cmnd *SC;
- ips_passthru_t *pt;
- IPS_FLASH_DATA *fd;
-
- fd = (IPS_FLASH_DATA *) data;
- ha = (ips_ha_t *) fd->ha;
- pt = (ips_passthru_t *) fd->pt;
- SC = (Scsi_Cmnd *) fd->SC;
-
- /*
- * Set initial return codes
- */
- SC->result = DID_OK << 16;
- pt->BasicStatus = 0x00;
- pt->ExtendedStatus = 0x00;
- fd->retcode = IPS_SUCCESS_IMM;
-
- ips_flash_bios_segment(data);
-
- if (fd->retcode != IPS_FAILURE)
- up(fd->sem);
-}
-
-/****************************************************************************/
-/* */
-/* Routine Name: ips_flash_bios_segment */
-/* */
-/* Routine Description: */
-/* */
-/* Flash a portion of the BIOS on a Copperhead style controller */
-/* To be called from a task queue */
-/* */
-/****************************************************************************/
-static void
-ips_flash_bios_segment(void *data) {
- ips_ha_t *ha;
- Scsi_Cmnd *SC;
- ips_passthru_t *pt;
- IPS_FLASH_DATA *fd;
-
- fd = (IPS_FLASH_DATA *) data;
- ha = (ips_ha_t *) fd->ha;
- pt = (ips_passthru_t *) fd->pt;
- SC = (Scsi_Cmnd *) fd->SC;
-
- if ((*ha->func.programbios)(ha, fd->kernbuffer, fd->usersize, fd->offset)) {
- DEBUG_VAR(1, "(%s%d) flash bios failed - unable to program flash",
- ips_name, ha->host_num);
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- SC->result = DID_ERROR << 16;
- fd->retcode = IPS_FAILURE;
- up(fd->sem);
-
- return ;
- }
-}
-
-/****************************************************************************/
-/* */
/* Routine Name: ips_usrcmd */
/* */
/* Routine Description: */
@@ -3074,126 +2634,6 @@
/****************************************************************************/
/* */
-/* Routine Name: ips_newusrcmd */
-/* */
-/* Routine Description: */
-/* */
-/* Process a user command and make it ready to send */
-/* */
-/****************************************************************************/
-static int
-ips_newusrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) {
- IPS_SG_LIST *sg_list;
- char *user_area;
- char *kern_area;
- uint32_t datasize;
-
- METHOD_TRACE("ips_newusrcmd", 1);
-
- if ((!scb) || (!pt) || (!ha))
- return (0);
-
- /* Save the S/G list pointer so it doesn't get clobbered */
- sg_list = scb->sg_list;
-
- /* copy in the CP */
- memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD));
- memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof(IPS_DCDB_TABLE));
-
- /* FIX stuff that might be wrong */
- scb->sg_list = sg_list;
- scb->scb_busaddr = VIRT_TO_BUS(scb);
- scb->bus = scb->scsi_cmd->channel;
- scb->target_id = scb->scsi_cmd->target;
- scb->lun = scb->scsi_cmd->lun;
- scb->sg_len = 0;
- scb->data_len = 0;
- scb->flags = 0;
- scb->op_code = 0;
- scb->callback = ipsintr_done;
- scb->timeout = ips_cmd_timeout;
- scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
-
- /* we don't support DCDB/READ/WRITE Scatter Gather */
- if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) ||
- (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) ||
- (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG))
- return (0);
-
- if (pt->CmdBSize) {
- if (pt->CmdBSize > ha->ioctl_datasize) {
- void *bigger_struct;
- uint32_t count;
- uint32_t order;
-
- /* try to allocate a bigger struct */
- for (count = PAGE_SIZE, order = 0;
- count < pt->CmdBSize;
- order++, count <<= 1);
-
- bigger_struct = (void *) __get_free_pages(GFP_ATOMIC, order);
- if (bigger_struct) {
- /* free the old memory */
- free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
-
- /* use the new memory */
- ha->ioctl_data = (char *) bigger_struct;
- ha->ioctl_order = order;
- ha->ioctl_datasize = count;
- } else
- return (0);
-
- }
-
- scb->data_busaddr = VIRT_TO_BUS(ha->ioctl_data);
-
- /* Attempt to copy in the data */
- user_area = *((char **) &scb->scsi_cmd->cmnd[4]);
- kern_area = ha->ioctl_data;
- datasize = *((uint32_t *) &scb->scsi_cmd->cmnd[8]);
-
- if (copy_from_user(kern_area, user_area, datasize) > 0) {
- DEBUG_VAR(1, "(%s%d) passthru failed - unable to copy in user data",
- ips_name, ha->host_num);
-
- return (0);
- }
-
- } else {
- scb->data_busaddr = 0L;
- }
-
- if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
- scb->cmd.dcdb.dcdb_address = cpu_to_le32(VIRT_TO_BUS(&scb->dcdb));
-
- if (pt->CmdBSize) {
- if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
- scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr);
- else
- scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr);
- }
-
- /* set timeouts */
- if (pt->TimeOut) {
- scb->timeout = pt->TimeOut;
-
- if (pt->TimeOut <= 10)
- scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
- else if (pt->TimeOut <= 60)
- scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
- else
- scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
- }
-
- /* assume success */
- scb->scsi_cmd->result = DID_OK << 16;
-
- /* success */
- return (1);
-}
-
-/****************************************************************************/
-/* */
/* Routine Name: ips_cleanup_passthru */
/* */
/* Routine Description: */
@@ -3225,8 +2665,6 @@
pt->BasicStatus = scb->basic_status;
pt->ExtendedStatus = scb->extended_status;
pt->AdapterType = ha->ad_type;
- if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND)
- up(&ha->ioctl_sem);
if(ha->device_id == IPS_DEVICEID_COPPERHEAD &&
(scb->cmd.flashfw.op_code == IPS_CMD_DOWNLOAD ||
@@ -3725,6 +3163,14 @@
}
}
+ /* Limit the Active Commands on a Lite Adapter */
+ if ((ha->ad_type == IPS_ADTYPE_SERVERAID3L) ||
+ (ha->ad_type == IPS_ADTYPE_SERVERAID4L) ||
+ (ha->ad_type == IPS_ADTYPE_SERVERAID4LX)) {
+ if ((ha->max_cmds > MaxLiteCmds) && (MaxLiteCmds))
+ ha->max_cmds = MaxLiteCmds;
+ }
+
/* set controller IDs */
ha->ha_id[0] = IPS_ADAPTER_ID;
for (i = 1; i < ha->nbus; i++) {
@@ -3812,17 +3258,7 @@
case IPS_FAILURE:
if (scb->scsi_cmd) {
scb->scsi_cmd->result = DID_ERROR << 16;
-
- /* raise the semaphore */
- if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
- uint32_t datasize;
-
- datasize = 0;
- memcpy(&scb->scsi_cmd->cmnd[8], &datasize, 4);
- up(&ha->ioctl_sem);
- } else {
- scb->scsi_cmd->scsi_done(scb->scsi_cmd);
- }
+ scb->scsi_cmd->scsi_done(scb->scsi_cmd);
}
ips_freescb(ha, scb);
@@ -3830,17 +3266,7 @@
case IPS_SUCCESS_IMM:
if (scb->scsi_cmd) {
scb->scsi_cmd->result = DID_OK << 16;
-
- /* raise the semaphore */
- if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
- uint32_t datasize;
-
- datasize = 0;
- memcpy(&scb->scsi_cmd->cmnd[8], &datasize, 4);
- up(&ha->ioctl_sem);
- } else {
- scb->scsi_cmd->scsi_done(scb->scsi_cmd);
- }
+ scb->scsi_cmd->scsi_done(scb->scsi_cmd);
}
ips_freescb(ha, scb);
@@ -3866,22 +3292,12 @@
switch(ret) {
case IPS_FAILURE:
if (scb->scsi_cmd) {
- /* raise the semaphore */
- if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND)
- up(&ha->ioctl_sem);
-
scb->scsi_cmd->result = DID_ERROR << 16;
}
ips_freescb(ha, scb);
break;
case IPS_SUCCESS_IMM:
- if (scb->scsi_cmd) {
- /* raise the semaphore */
- if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND)
- up(&ha->ioctl_sem);
- }
-
ips_freescb(ha, scb);
break;
default:
@@ -4012,8 +3428,7 @@
}
- scb->dcdb.cmd_attribute |=
- ips_command_direction[scb->scsi_cmd->cmnd[0]];
+ scb->dcdb.cmd_attribute = ips_command_direction[scb->scsi_cmd->cmnd[0]];
if (!scb->dcdb.cmd_attribute & 0x3)
scb->dcdb.transfer_length = 0;
@@ -4626,6 +4041,7 @@
bk_save = scb->breakup;
scb->breakup = 0;
+ mod_timer(&scb->scsi_cmd->eh_timeout, jiffies + 120 * HZ);
if (scb->sg_count) {
/* S/G request */
@@ -4727,8 +4143,7 @@
scb->sg_len = 0;
}
- scb->dcdb.cmd_attribute |=
- ips_command_direction[scb->scsi_cmd->cmnd[0]];
+ scb->dcdb.cmd_attribute |= ips_command_direction[scb->scsi_cmd->cmnd[0]];
if (!scb->dcdb.cmd_attribute & 0x3)
scb->dcdb.transfer_length = 0;
@@ -4771,9 +4186,7 @@
IPS_HA_UNLOCK(cpu_flags);
}
- /* call back to SCSI layer */
- if (scb->scsi_cmd && scb->scsi_cmd->cmnd[0] != IPS_IOCTL_NEW_COMMAND)
- scb->scsi_cmd->scsi_done(scb->scsi_cmd);
+ scb->scsi_cmd->scsi_done(scb->scsi_cmd);
ips_freescb(ha, scb);
}
@@ -4791,6 +4204,8 @@
ips_map_status(ips_ha_t *ha, ips_scb_t *scb, ips_stat_t *sp) {
int errcode;
int device_error;
+ uint32_t transfer_len;
+ IPS_DCDB_TABLE_TAPE *tapeDCDB;
METHOD_TRACE("ips_map_status", 1);
@@ -4832,8 +4247,16 @@
break;
- case IPS_ERR_OU_RUN:
- if ((scb->bus) && (scb->dcdb.transfer_length < scb->data_len)) {
+ case IPS_ERR_OU_RUN:
+ if ( ( scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB ) ||
+ ( scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG ) ) {
+ tapeDCDB = ( IPS_DCDB_TABLE_TAPE * ) &scb->dcdb;
+ transfer_len = tapeDCDB->transfer_length;
+ } else {
+ transfer_len = ( uint32_t ) scb->dcdb.transfer_length;
+ }
+
+ if ((scb->bus) && (transfer_len < scb->data_len)) {
/* Underrun - set default to no error */
errcode = DID_OK;
@@ -4864,9 +4287,15 @@
case IPS_ERR_CKCOND:
if (scb->bus) {
- memcpy(scb->scsi_cmd->sense_buffer, scb->dcdb.sense_info,
- sizeof(scb->scsi_cmd->sense_buffer));
-
+ if ((scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB) ||
+ (scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG)) {
+ tapeDCDB = (IPS_DCDB_TABLE_TAPE *) &scb->dcdb;
+ memcpy(scb->scsi_cmd->sense_buffer, tapeDCDB->sense_info,
+ sizeof(scb->scsi_cmd->sense_buffer));
+ } else {
+ memcpy(scb->scsi_cmd->sense_buffer, scb->dcdb.sense_info,
+ sizeof(scb->scsi_cmd->sense_buffer));
+ }
device_error = 2; /* check condition */
}
@@ -4888,28 +4317,6 @@
/****************************************************************************/
/* */
-/* Routine Name: ips_send */
-/* */
-/* Routine Description: */
-/* */
-/* Wrapper for ips_send_cmd */
-/* */
-/****************************************************************************/
-static int
-ips_send(ips_ha_t *ha, ips_scb_t *scb, ips_scb_callback callback) {
- int ret;
-
- METHOD_TRACE("ips_send", 1);
-
- scb->callback = callback;
-
- ret = ips_send_cmd(ha, scb);
-
- return (ret);
-}
-
-/****************************************************************************/
-/* */
/* Routine Name: ips_send_wait */
/* */
/* Routine Description: */
@@ -4928,9 +4335,9 @@
if (intr != IPS_FFDC) { /* Won't be Waiting if this is a Time Stamp */
ha->waitflag = TRUE;
ha->cmd_in_progress = scb->cdb[0];
- }
-
- ret = ips_send(ha, scb, ipsintr_blocking);
+ }
+ scb->callback = ipsintr_blocking;
+ ret = ips_send_cmd(ha, scb);
if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
return (ret);
@@ -4955,6 +4362,7 @@
int ret;
char *sp;
int device_error;
+ IPS_DCDB_TABLE_TAPE *tapeDCDB;
METHOD_TRACE("ips_send_cmd", 1);
@@ -5183,26 +4591,63 @@
scb->cmd.dcdb.reserved2 = 0;
scb->cmd.dcdb.reserved3 = 0;
- scb->dcdb.device_address = ((scb->bus - 1) << 4) | scb->target_id;
- scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED;
-
- if (scb->timeout) {
- if (scb->timeout <= 10)
- scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
- else if (scb->timeout <= 60)
- scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
+ if (ha->subsys->param[4] & 0x00100000) { /* If NEW Tape DCDB is Supported */
+ if (!scb->sg_len)
+ scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB;
else
- scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
- }
+ scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB_SG;
+
+ tapeDCDB = (IPS_DCDB_TABLE_TAPE *) &scb->dcdb; /* Use Same Data Area as Old DCDB Struct */
+ tapeDCDB->device_address = ((scb->bus - 1) << 4) | scb->target_id;
+ tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED;
+ tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K; /* Always Turn OFF 64K Size Flag */
+
+ if (scb->timeout) {
+ if (scb->timeout <= 10)
+ tapeDCDB->cmd_attribute |= IPS_TIMEOUT10;
+ else if (scb->timeout <= 60)
+ tapeDCDB->cmd_attribute |= IPS_TIMEOUT60;
+ else
+ tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M;
+ }
- if (!(scb->dcdb.cmd_attribute & IPS_TIMEOUT20M))
- scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
+ if (!(tapeDCDB->cmd_attribute & IPS_TIMEOUT20M))
+ tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M;
- scb->dcdb.sense_length = sizeof(scb->scsi_cmd->sense_buffer);
- scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr);
- scb->dcdb.sg_count = scb->sg_len;
- scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len;
- memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len);
+ tapeDCDB->sense_length = sizeof(tapeDCDB->sense_info);
+ tapeDCDB->transfer_length = scb->data_len;
+ tapeDCDB->buffer_pointer = cpu_to_le32(scb->data_busaddr);
+ tapeDCDB->sg_count = scb->sg_len;
+ tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len;
+ tapeDCDB->reserved_for_LUN = 0;
+ tapeDCDB->reserved = 0;
+ tapeDCDB->scsi_status = 0;
+ memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len);
+ } else {
+ scb->dcdb.device_address = ((scb->bus - 1) << 4) | scb->target_id;
+ scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED;
+
+ if (scb->timeout) {
+ if (scb->timeout <= 10)
+ scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
+ else if (scb->timeout <= 60)
+ scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
+ else
+ scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
+ }
+
+ if (!(scb->dcdb.cmd_attribute & IPS_TIMEOUT20M))
+ scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
+
+ scb->dcdb.sense_length = sizeof(scb->dcdb.sense_info);
+ scb->dcdb.transfer_length = scb->data_len;
+ if ( scb->dcdb.cmd_attribute & IPS_TRANSFER64K )
+ scb->dcdb.transfer_length = 0;
+ scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr);
+ scb->dcdb.sg_count = scb->sg_len;
+ scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len;
+ memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len);
+ }
}
return ((*ha->func.issue)(ha, scb));
@@ -7808,17 +7253,17 @@
if (strncmp(FirmwareVersion, Compatable[ ha->nvram->adapter_type ], IPS_COMPAT_ID_LENGTH) != 0)
{
- /* if (ips_cd_boot == 0) */
- /* printk(KERN_WARNING "Warning: Adapter %d Firmware Compatible Version is %s, but should be %s\n", */
- /* ha->host_num, FirmwareVersion, Compatable[ ha->nvram->adapter_type ]); */
+ if (ips_cd_boot == 0)
+ printk(KERN_WARNING "Warning: Adapter %d Firmware Compatible Version is %s, but should be %s\n",
+ ha->host_num, FirmwareVersion, Compatable[ ha->nvram->adapter_type ]);
MatchError = 1;
}
if (strncmp(BiosVersion, IPS_COMPAT_BIOS, IPS_COMPAT_ID_LENGTH) != 0)
{
- /* if (ips_cd_boot == 0) */
- /* printk(KERN_WARNING "Warning: Adapter %d BIOS Compatible Version is %s, but should be %s\n", */
- /* ha->host_num, BiosVersion, IPS_COMPAT_BIOS); */
+ if (ips_cd_boot == 0)
+ printk(KERN_WARNING "Warning: Adapter %d BIOS Compatible Version is %s, but should be %s\n",
+ ha->host_num, BiosVersion, IPS_COMPAT_BIOS);
MatchError = 1;
}
@@ -7827,8 +7272,8 @@
if (MatchError)
{
ha->nvram->version_mismatch = 1;
- /* if (ips_cd_boot == 0) */
- /* printk(KERN_WARNING "Warning ! ! ! ServeRAID Version Mismatch\n"); */
+ if (ips_cd_boot == 0)
+ printk(KERN_WARNING "Warning ! ! ! ServeRAID Version Mismatch\n");
}
else
{
@@ -7964,6 +7409,7 @@
uint32_t count;
char *ioremap_ptr;
char *mem_ptr;
+ uint32_t IsDead
METHOD_TRACE("ips_init_phase1", 1);
index = IPS_MAX_ADAPTERS;
@@ -8227,6 +7673,14 @@
ha->func.issue = ips_issue_copperhead;
}
+ if ( IPS_IS_MORPHEUS( ha ) ) {
+ /* If Morpheus appears dead, reset it */
+ IsDead = readl( ha->mem_ptr + IPS_REG_I960_MSG1 );
+ if ( IsDead == 0xDEADBEEF ) {
+ ips_reset_morpheus( ha );
+ }
+ }
+
/*
* Initialize the card if it isn't already
*/
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)