Various buglets- hopefully now fixed the case where 24XX fails to start.

Some stuff for multiple channels and internal f/w.




git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@971 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Dotan Barak
2009-07-23 15:37:47 +00:00
parent c811b44224
commit 0a4165980d
3 changed files with 109 additions and 35 deletions
+66 -33
View File
@@ -2958,14 +2958,12 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
isp_dump_portdb(isp, bus);
}
}
isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "arrived", (ull) lp->node_wwn, (ull) lp->port_wwn);
if (lp->dev_map_idx) {
unsigned long arg;
tgt = lp->dev_map_idx - 1;
isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "arrived at", tgt, (ull) lp->node_wwn, (ull) lp->port_wwn);
arg = tgt | (bus << 16);
isp_thread_event(isp, ISP_THREAD_SCSI_SCAN, (void *)arg, 0, __func__, __LINE__);
} else {
isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "arrived", (ull) lp->node_wwn, (ull) lp->port_wwn);
lp->dirty = 0;
if (isp->isp_osinfo.scan_timeout == 0) {
isp->isp_osinfo.scan_timeout = ISP_SCAN_TIMEOUT;
}
}
break;
case ISPASYNC_DEV_CHANGED:
@@ -3004,15 +3002,13 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
va_end(ap);
fcp = FCPARAM(isp, bus);
if (lp->dev_map_idx) {
unsigned long arg;
tgt = lp->dev_map_idx - 1;
fcp->isp_dev_map[tgt] = 0;
lp->state = FC_PORTDB_STATE_NIL;
lp->dev_map_idx = 0;
isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "departed", tgt, (ull) lp->node_wwn, (ull) lp->port_wwn);
arg = tgt | (bus << 16) | (1 << 31);
isp_thread_event(isp, ISP_THREAD_SCSI_SCAN, (void *)arg, 0, __func__, __LINE__);
} else if (lp->reserved == 0) {
lp->reserved = 2;
if (isp->isp_osinfo.rescan_timeout == 0) {
isp->isp_osinfo.rescan_timeout = ISP_RESCAN_TIMEOUT;
}
isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "zombie", (ull) lp->node_wwn, (ull) lp->port_wwn);
lp->state = FC_PORTDB_STATE_ZOMBIE;
} else {
isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "departed", (ull) lp->node_wwn, (ull) lp->port_wwn);
}
break;
@@ -3786,6 +3782,16 @@ isplinux_timer(unsigned long arg)
isp->isp_osinfo.dqnext = isp->isp_osinfo.dqtail = NULL;
}
/*
* Check for any rescan activity that needs running
*/
if (isp->isp_osinfo.scan_timeout && --isp->isp_osinfo.scan_timeout == 0) {
isp_thread_event(isp, ISP_THREAD_SCSI_SCAN, (void *)1, 0, __func__, __LINE__);
}
if (isp->isp_osinfo.rescan_timeout && --isp->isp_osinfo.rescan_timeout == 0) {
isp_thread_event(isp, ISP_THREAD_SCSI_SCAN, (void *)0, 0, __func__, __LINE__);
}
/*
* Set up the timer again
*/
@@ -4262,6 +4268,7 @@ isplinux_reinit(ispsoftc_t *isp, int doset_defaults)
* Bus Reset delay handled by firmware.
*/
}
isp->mbintsok = 1;
isp->isp_state = ISP_RUNSTATE;
return (0);
}
@@ -4332,6 +4339,48 @@ isp_thread_event(ispsoftc_t *isp, int action, void *a, int dowait, const char *f
return (0);
}
static void
isp_scsi_scan(ispsoftc_t *isp)
{
unsigned long flags;
int chan, tgt, i;
if (!IS_FC(isp)) {
return;
}
ISP_LOCKU_SOFTC(isp);
for (chan = 0; chan < isp->isp_nchan; chan++) {
fcparam *fcp = FCPARAM(isp, chan);
for (i = 0; i < MAX_FC_TARG; i++) {
fcportdb_t *lp = &fcp->portdb[i];
if (lp->dev_map_idx == 0) {
continue;
}
tgt = lp->dev_map_idx - 1;
if (lp->state == FC_PORTDB_STATE_VALID && lp->dirty == 0) {
ISP_UNLKU_SOFTC(isp);
scsi_scan_target(&isp->isp_osinfo.host->shost_gendev, chan, tgt, 0, 0);
ISP_LOCKU_SOFTC(isp);
} else if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
struct scsi_device *sdev;
fcp->isp_dev_map[tgt] = 0;
lp->state = FC_PORTDB_STATE_NIL;
lp->dev_map_idx = 0;
lp->dirty = 0;
ISP_UNLKU_SOFTC(isp);
sdev = scsi_device_lookup(isp->isp_osinfo.host, 0, tgt, 0);
if (sdev) {
scsi_remove_device(sdev);
scsi_device_put(sdev);
}
ISP_LOCKU_SOFTC(isp);
}
}
}
ISP_UNLKU_SOFTC(isp);
}
static int
isp_task_thread(void *arg)
{
@@ -4365,24 +4414,8 @@ isp_task_thread(void *arg)
case ISP_THREAD_NIL:
break;
case ISP_THREAD_SCSI_SCAN:
{
unsigned long arg = (unsigned long) tap->arg;
int tgt, chan, rescan;
tgt = arg & 0xffff;
chan = (arg >> 16) & 0xff;
rescan = (arg >> 31) & 1;
if (rescan == 0) {
scsi_scan_target(&isp->isp_osinfo.host->shost_gendev, chan, tgt, 0, rescan);
} else {
struct scsi_device *sdev;
sdev = scsi_device_lookup(isp->isp_osinfo.host, 0, tgt, 0);
if (sdev) {
scsi_remove_device(sdev);
scsi_device_put(sdev);
}
}
isp_scsi_scan(isp);
break;
}
case ISP_THREAD_REINIT:
ISP_LOCKU_SOFTC(isp);
if (isp->isp_dead) {
+5 -1
View File
@@ -1,4 +1,4 @@
/* $Id: isp_linux.h,v 1.173 2009/05/10 16:25:09 mjacob Exp $ */
/* $Id: isp_linux.h,v 1.174 2009/06/07 04:36:38 mjacob Exp $ */
/*
* Copyright (c) 1997-2009 by Matthew Jacob
* All rights reserved.
@@ -339,6 +339,8 @@ struct isposinfo {
mboxcmd_done : 1,
mbintsok : 1,
intsok : 1;
u16 scan_timeout;
u16 rescan_timeout;
u16 frame_size;
u16 exec_throttle;
struct task_struct *thread_task;
@@ -698,6 +700,8 @@ extern int api_channel;
#define ISP_WATCH_TPS 10
#define ISP_WATCH_TIME (HZ / ISP_WATCH_TPS)
#define ISP_SCAN_TIMEOUT (2 * ISP_WATCH_TPS)
#define ISP_RESCAN_TIMEOUT ISP_WATCH_TPS
#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
+38 -1
View File
@@ -122,28 +122,52 @@ static int isplinux_pci_exclude(struct pci_dev *);
#if defined(DISABLE_FW_LOADER) || !(defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE))
#ifndef ISP_DISABLE_1020_SUPPORT
#include "asm_1040.h"
#undef ISP_1040_RISC_CODE
#define ISP_1040_RISC_CODE (const uint16_t *) isp_1040_risc_code
#endif
#ifndef ISP_DISABLE_1080_SUPPORT
#include "asm_1080.h"
#undef ISP_1080_RISC_CODE
#define ISP_1080_RISC_CODE (const uint16_t *) isp_1080_risc_code
#endif
#ifndef ISP_DISABLE_12160_SUPPORT
#include "asm_12160.h"
#undef ISP_12160_RISC_CODE
#define ISP_12160_RISC_CODE (const uint16_t *) isp_12160_risc_code
#endif
#ifndef ISP_DISABLE_2100_SUPPORT
#include "asm_2100.h"
#undef ISP_2100_RISC_CODE
#define ISP_2100_RISC_CODE (const uint16_t *) isp_2100_risc_code
#endif
#ifndef ISP_DISABLE_2200_SUPPORT
#include "asm_2200.h"
#undef ISP_2200_RISC_CODE
#define ISP_2200_RISC_CODE (const uint16_t *) isp_2200_risc_code
#endif
#ifndef ISP_DISABLE_2300_SUPPORT
#include "asm_2300.h"
#undef ISP_2300_RISC_CODE
#define ISP_2300_RISC_CODE (const uint16_t *) isp_2300_risc_code
#endif
#ifndef ISP_DISABLE_2322_SUPPORT
#include "asm_2322.h"
#undef ISP_2322_RISC_CODE
#define ISP_2322_RISC_CODE (const uint16_t *) isp_2322_risc_code
#endif
#ifndef ISP_DISABLE_2400_SUPPORT
#define ISP_2400
#define ISP_2400_MULTI
#define ISP_2500
#define ISP_2500_MULTI
#include "asm_2400.h"
#include "asm_2500.h"
#undef ISP_2400_RISC_CODE
#undef ISP_2500_RISC_CODE
#define ISP_2400_RISC_CODE (const uint32_t *) isp_2400_risc_code
#define ISP_2500_RISC_CODE (const uint32_t *) isp_2500_risc_code
#define ISP_2400_MULTI_RISC_CODE (const uint32_t *) isp_2400_multi_risc_code
#define ISP_2500_MULTI_RISC_CODE (const uint32_t *) isp_2500_multi_risc_code
#endif
#endif
@@ -939,6 +963,14 @@ isplinux_pci_init_one(struct Scsi_Host *host)
isp->isp_osinfo.fwp = NULL;
}
}
#else
if (isp_vports) {
if (IS_25XX(isp)) {
isp->isp_mdvec->dv_ispfw = ISP_2500_MULTI_RISC_CODE;
} else if (IS_24XX(isp)) {
isp->isp_mdvec->dv_ispfw = ISP_2400_MULTI_RISC_CODE;
}
}
#endif
if (isplinux_common_init(isp)) {
@@ -1855,7 +1887,10 @@ isp_pci_reset1(ispsoftc_t *isp)
}
ISP_ENABLE_INTS(isp);
isp->intsok = 1;
isp->mbintsok = 1;
/*
* We used to enable mbintsok here.
* This seemed to nuke 24XX cards in some, but not all cases.
*/
}
static void
@@ -2169,6 +2204,8 @@ isplinux_pci_init(void)
ret = pci_register_driver(&isplinux_pci_driver);
if (ret < 0) {
printk(KERN_ERR "%s: unable to register driver (return value %d)", __func__, ret);
DESTROY_ISP_CLASS(isp_class);
cdev_del(&isp_cdev);
unregister_chrdev_region(isp_dev, MAX_ISP);
return (ret);
}