diff options
author | mjacob <mjacob@FreeBSD.org> | 2002-02-18 00:00:34 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 2002-02-18 00:00:34 +0000 |
commit | e4ecbf2c51e25b15585a4d7af9e7ce6f8a56a299 (patch) | |
tree | ddea077bfbe94688db63926550e711f058ff28d1 /sys | |
parent | cdc3c37e6597d9fd5fca412b23c5292c3c45b903 (diff) | |
download | FreeBSD-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.c | 6 | ||||
-rw-r--r-- | sys/dev/isp/isp_freebsd.c | 40 | ||||
-rw-r--r-- | sys/dev/isp/isp_ioctl.h | 2 | ||||
-rw-r--r-- | sys/dev/isp/isp_pci.c | 19 |
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), |