summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2002-02-18 00:00:34 +0000
committermjacob <mjacob@FreeBSD.org>2002-02-18 00:00:34 +0000
commite4ecbf2c51e25b15585a4d7af9e7ce6f8a56a299 (patch)
treeddea077bfbe94688db63926550e711f058ff28d1 /sys
parentcdc3c37e6597d9fd5fca412b23c5292c3c45b903 (diff)
downloadFreeBSD-src-e4ecbf2c51e25b15585a4d7af9e7ce6f8a56a299.zip
FreeBSD-src-e4ecbf2c51e25b15585a4d7af9e7ce6f8a56a299.tar.gz
More for f/w crash dumps (bug fixing and adding ioctl entry points
and hints to enable for specific units) MFC after: 1 week
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/isp/isp.c6
-rw-r--r--sys/dev/isp/isp_freebsd.c40
-rw-r--r--sys/dev/isp/isp_ioctl.h2
-rw-r--r--sys/dev/isp/isp_pci.c19
4 files changed, 63 insertions, 4 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 6f95a20..6e10691 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -5814,7 +5814,7 @@ static void isp2300_fw_dump(struct ispsoftc *);
static void
isp2200_fw_dump(struct ispsoftc *isp)
{
- int i, j, k;
+ int i, j;
mbreg_t mbs;
u_int16_t *ptr;
@@ -5957,7 +5957,7 @@ isp2200_fw_dump(struct ispsoftc *isp)
static void
isp2300_fw_dump(struct ispsoftc *isp)
{
- int i, j, k;
+ int i, j;
mbreg_t mbs;
u_int16_t *ptr;
@@ -6121,7 +6121,7 @@ isp_fw_dump(struct ispsoftc *isp)
{
if (IS_2200(isp))
isp2200_fw_dump(isp);
- else if (IS_2300(isp))
+ else if (IS_23XX(isp))
isp2300_fw_dump(isp);
}
#endif
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index 593ac7d..6d9a8fe 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -249,6 +249,46 @@ ispioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
return (ENXIO);
switch (cmd) {
+#ifdef ISP_FW_CRASH_DUMP
+ case ISP_GET_FW_CRASH_DUMP:
+ {
+ u_int16_t *ptr = FCPARAM(isp)->isp_dump_data;
+ size_t sz;
+
+ retval = 0;
+ if (IS_2200(isp))
+ sz = QLA2200_RISC_IMAGE_DUMP_SIZE;
+ else
+ sz = QLA2300_RISC_IMAGE_DUMP_SIZE;
+ ISP_LOCK(isp);
+ if (ptr && *ptr) {
+ void *uaddr = *((void **) addr);
+ if (copyout(ptr, uaddr, sz)) {
+ retval = EFAULT;
+ } else {
+ *ptr = 0;
+ }
+ } else {
+ retval = ENXIO;
+ }
+ ISP_UNLOCK(isp);
+ break;
+ }
+
+ case ISP_FORCE_CRASH_DUMP:
+ ISP_LOCK(isp);
+ if ((isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN) == 0) {
+ isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN;
+ ISPLOCK_2_CAMLOCK(isp);
+ xpt_freeze_simq(isp->isp_sim, 1);
+ CAMLOCK_2_ISPLOCK(isp);
+ }
+ isp_fw_dump(isp);
+ isp_reinit(isp);
+ ISP_UNLOCK(isp);
+ retval = 0;
+ break;
+#endif
case ISP_SDBLEV:
{
int olddblev = isp->isp_dblev;
diff --git a/sys/dev/isp/isp_ioctl.h b/sys/dev/isp/isp_ioctl.h
index d3af96f..c048080 100644
--- a/sys/dev/isp/isp_ioctl.h
+++ b/sys/dev/isp/isp_ioctl.h
@@ -105,5 +105,5 @@ typedef struct {
/*
* Get F/W crash dump
*/
-#define ISP_GET_FW_CRASH_DUMP _IOR(ISP_IOC, 10, void *)
+#define ISP_GET_FW_CRASH_DUMP _IO(ISP_IOC, 10)
#define ISP_FORCE_CRASH_DUMP _IO(ISP_IOC, 11)
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index 02bc05f..49182ae 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -606,6 +606,25 @@ isp_pci_attach(device_t dev)
"fullduplex", &tval) == 0 && tval != 0) {
isp->isp_confopts |= ISP_CFG_FULL_DUPLEX;
}
+#ifdef ISP_FW_CRASH_DUMP
+ tval = 0;
+ if (resource_int_value(device_get_name(dev), device_get_unit(dev),
+ "fw_dump_enable", &tval) == 0 && tval != 0) {
+ size_t amt = 0;
+ if (IS_2200(isp)) {
+ amt = QLA2200_RISC_IMAGE_DUMP_SIZE;
+ } else if (IS_23XX(isp)) {
+ amt = QLA2300_RISC_IMAGE_DUMP_SIZE;
+ }
+ if (amt) {
+ FCPARAM(isp)->isp_dump_data =
+ malloc(amt, M_DEVBUF, M_WAITOK | M_ZERO);
+ } else {
+ device_printf(dev,
+ "f/w crash dumps not supported for this model\n");
+ }
+ }
+#endif
sptr = 0;
if (resource_string_value(device_get_name(dev), device_get_unit(dev),
OpenPOWER on IntegriCloud