summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2004-10-22 04:54:27 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2004-10-22 04:54:27 +0000
commit4f5a87912a29838d26696f65b9d4ae0288319a0f (patch)
treecf2e4432b904a8938f124901d4bdac7d3f6c6225 /sys
parent6ce3fe385804aa9522092341962f67f7ad197856 (diff)
Add:
* bio ioctl interface * retrieval of manufacturing pages * retrieval of IOC pages * IM detection during boot This is the initial infrastructure to add IM/IME/IS support to the mpt driver. This is not extremely useful yet. Userland tool to follow.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ic/mpt.c128
-rw-r--r--sys/dev/ic/mpt_openbsd.c108
-rw-r--r--sys/dev/ic/mpt_openbsd.h25
3 files changed, 234 insertions, 27 deletions
diff --git a/sys/dev/ic/mpt.c b/sys/dev/ic/mpt.c
index 36a5e5a6496..186c2d41513 100644
--- a/sys/dev/ic/mpt.c
+++ b/sys/dev/ic/mpt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpt.c,v 1.8 2004/07/12 23:57:14 marco Exp $ */
+/* $OpenBSD: mpt.c,v 1.9 2004/10/22 04:54:26 marco Exp $ */
/* $NetBSD: mpt.c,v 1.4 2003/11/02 11:07:45 wiz Exp $ */
/*
@@ -58,6 +58,9 @@ int mpt_wait_state(mpt_softc_t *, enum DB_STATE_BITS);
int mpt_get_iocfacts(mpt_softc_t *, MSG_IOC_FACTS_REPLY *);
int mpt_get_portfacts(mpt_softc_t *, MSG_PORT_FACTS_REPLY *);
int mpt_send_ioc_init(mpt_softc_t *, u_int32_t);
+void mpt_print_header(mpt_softc_t *, char *, fCONFIG_PAGE_HEADER *);
+int mpt_read_config_info_mfg(mpt_softc_t *);
+int mpt_read_config_info_ioc(mpt_softc_t *);
int mpt_read_config_info_spi(mpt_softc_t *);
int mpt_set_initial_config_spi(mpt_softc_t *);
int mpt_send_port_enable(mpt_softc_t *, int);
@@ -719,6 +722,12 @@ mpt_read_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
cfgp->Header.PageNumber == 1) {
amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1);
+ } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_MANUFACTURING &&
+ cfgp->Header.PageNumber == 0) {
+ amt = sizeof (fCONFIG_PAGE_MANUFACTURING_0);
+ } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_IOC &&
+ cfgp->Header.PageNumber == 2) {
+ amt = sizeof (fCONFIG_PAGE_IOC_2);
}
bcopy(((caddr_t)req->req_vbuf)+CFG_DATA_OFF, hdr, amt);
mpt_free_request(mpt, req);
@@ -810,6 +819,107 @@ mpt_write_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
return (0);
}
+void
+mpt_print_header(mpt_softc_t *mpt, char *s, fCONFIG_PAGE_HEADER *phdr)
+{
+ mpt_prt(mpt, "%s %x: %x %x %x %x",
+ s,
+ phdr->PageNumber,
+ phdr->PageType,
+ phdr->PageNumber,
+ phdr->PageLength,
+ phdr->PageVersion);
+}
+
+/*
+ * Read manufacturing configuration information
+ */
+int
+mpt_read_config_info_mfg(mpt_softc_t *mpt)
+{
+ int rv;
+
+ /* retrieve manufacturing headers */
+ rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0,
+ 0, &mpt->mpt_mfg_page0.Header);
+ if (rv) {
+ mpt_prt(mpt, "Could not retrieve Manufacturing Page 0 Header.");
+ return (-1);
+ } else if (mpt->verbose > 1) {
+ mpt_print_header(mpt, "Manufacturing Header Page",
+ &mpt->mpt_mfg_page0.Header);
+ }
+
+ /* retrieve manufacturing config pages using retrieved headers */
+
+ return (0);
+}
+
+/*
+ * Read IOC configuration information
+ */
+int
+mpt_read_config_info_ioc(mpt_softc_t *mpt)
+{
+ int rv, i;
+ fCONFIG_PAGE_HEADER *phdr[5] = {
+ phdr[0] = &mpt->mpt_ioc_page0.Header,
+ phdr[1] = &mpt->mpt_ioc_page1.Header,
+ phdr[2] = &mpt->mpt_ioc_page2.Header,
+ phdr[3] = &mpt->mpt_ioc_page3.Header,
+ phdr[4] = &mpt->mpt_ioc_page4.Header
+ };
+
+ for (i = 0; i < 5 /* 5 pages total */; i++) {
+ /* retrieve IOC headers */
+ rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_IOC, i,
+ 0, phdr[i]);
+ if (rv) {
+ mpt_prt(mpt, "Could not retrieve IOC Page %i header.",
+ i);
+ return (-1);
+ } else if (mpt->verbose > 1) {
+ mpt_print_header(mpt, "IOC Header Page", phdr[i]);
+ }
+
+ /* retrieve IOC config pages using retrieved headers */
+ rv = mpt_read_cfg_page(mpt, i, phdr[i]);
+ if (rv) {
+ mpt_prt(mpt, "Could not retrieve IOC Page %i", i);
+ return (-1);
+ }
+ }
+
+ /* mpt->verbose = 2; */
+ if (mpt->verbose > 1) {
+ mpt_prt(mpt, "IOC Page 0 data: %x %x %x %x %x %x %x %x",
+ mpt->mpt_ioc_page0.TotalNVStore,
+ mpt->mpt_ioc_page0.FreeNVStore,
+ mpt->mpt_ioc_page0.DeviceID,
+ mpt->mpt_ioc_page0.VendorID,
+ mpt->mpt_ioc_page0.RevisionID,
+ mpt->mpt_ioc_page0.ClassCode,
+ mpt->mpt_ioc_page0.SubsystemID,
+ mpt->mpt_ioc_page0.SubsystemVendorID
+ );
+
+ mpt_prt(mpt, "IOC Page 1 data: %x %x %x",
+ mpt->mpt_ioc_page1.Flags,
+ mpt->mpt_ioc_page1.CoalescingTimeout,
+ mpt->mpt_ioc_page1.CoalescingDepth);
+
+ mpt_prt(mpt, "IOC Page 2 data: %x %x %x %x %x",
+ mpt->mpt_ioc_page2.CapabilitiesFlags,
+ mpt->mpt_ioc_page2.MaxPhysDisks,
+ mpt->mpt_ioc_page2.NumActivePhysDisks,
+ mpt->mpt_ioc_page2.MaxVolumes,
+ mpt->mpt_ioc_page2.NumActiveVolumes);
+ }
+ /* mpt->verbose = 1; */
+
+ return (0);
+}
+
/*
* Read SCSI configuration information
*/
@@ -1278,6 +1388,22 @@ mpt_init(mpt_softc_t *mpt, u_int32_t who)
}
/*
+ * Read manufacturing pages
+ */
+ if (mpt_read_config_info_mfg(mpt)) {
+ mpt_prt(mpt, "could not retrieve manufacturing pages");
+ return (EIO);
+ }
+
+ /*
+ * Read IOC pages
+ */
+ if (mpt_read_config_info_ioc(mpt)) {
+ mpt_prt(mpt, "could not retrieve IOC pages");
+ return (EIO);
+ }
+
+ /*
* Now enable the port
*/
if (mpt_send_port_enable(mpt, 0) != MPT_OK) {
diff --git a/sys/dev/ic/mpt_openbsd.c b/sys/dev/ic/mpt_openbsd.c
index 1d5ca612388..efd2103f4e0 100644
--- a/sys/dev/ic/mpt_openbsd.c
+++ b/sys/dev/ic/mpt_openbsd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpt_openbsd.c,v 1.15 2004/08/23 20:52:15 marco Exp $ */
+/* $OpenBSD: mpt_openbsd.c,v 1.16 2004/10/22 04:54:26 marco Exp $ */
/* $NetBSD: mpt_netbsd.c,v 1.7 2003/07/14 15:47:11 lukem Exp $ */
/*
@@ -119,6 +119,9 @@ void mpt_event_notify_reply(mpt_softc_t *, MSG_EVENT_NOTIFY_REPLY *);
int mpt_action(struct scsi_xfer *);
void mpt_minphys(struct buf *);
+#if NBIO > 0
+int mpt_ioctl(struct device *, u_long, caddr_t);
+#endif
struct cfdriver mpt_cd = {
NULL, "mpt", DV_DULL
};
@@ -403,8 +406,6 @@ void
mpt_attach(mpt_softc_t *mpt)
{
struct scsi_link *lptr = &mpt->sc_link;
- struct _CONFIG_PAGE_IOC_2 iocp2;
- int rv;
mpt->bus = 0; /* XXX ?? */
@@ -432,29 +433,18 @@ mpt_attach(mpt_softc_t *mpt)
mpt->verbose = 2;
#endif
- /* Read IOC page 2 to figure out if we have IM */
- rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_IOC, 2,
- 0, &iocp2.Header);
- if (rv) {
- mpt_prt(mpt, "Could not retrieve IOC PAGE 2 to determine"
- "RAID capabilities.");
- }
- else {
- mpt->im_support = iocp2.CapabilitiesFlags &
- (MPI_IOCPAGE2_CAP_FLAGS_IS_SUPPORT |
- MPI_IOCPAGE2_CAP_FLAGS_IME_SUPPORT |
- MPI_IOCPAGE2_CAP_FLAGS_IM_SUPPORT);
+#if NBIO > 0
+ if (bio_register(&mpt->mpt_dev, mpt_ioctl) != 0)
+ panic("%s: controller registration failed",
+ mpt->mpt_dev.dv_xname);
+#endif
- if (mpt->verbose > 1) {
- mpt_prt(mpt, "IOC Page 2: %x %x %x %x %x",
- iocp2.CapabilitiesFlags,
- iocp2.NumActiveVolumes,
- iocp2.MaxVolumes,
- iocp2.NumActivePhysDisks,
- iocp2.MaxPhysDisks);
- mpt_prt(mpt, "IM support: %x", mpt->im_support);
- }
- }
+ mpt->im_support = mpt->mpt_ioc_page2.CapabilitiesFlags &
+ (MPI_IOCPAGE2_CAP_FLAGS_IS_SUPPORT |
+ MPI_IOCPAGE2_CAP_FLAGS_IME_SUPPORT |
+ MPI_IOCPAGE2_CAP_FLAGS_IM_SUPPORT);
+
+ mpt_prt(mpt, "IM support: %x", mpt->im_support);
(void) config_found(&mpt->mpt_dev, lptr, scsiprint);
@@ -1625,3 +1615,71 @@ mpt_free_fw_mem(mpt_softc_t *mpt)
bus_dmamem_unmap(mpt->sc_dmat, (caddr_t)mpt->fw, mpt->fw_image_size);
bus_dmamem_free(mpt->sc_dmat, &mpt->fw_seg, mpt->fw_rseg);
}
+
+#if NBIO > 0
+int
+mpt_ioctl(dev, cmd, addr)
+ struct device *dev;
+ u_long cmd;
+ caddr_t addr;
+{
+ int error = 0;
+ int rv;
+ struct mpt_dummy *dummy;
+ struct mpt_mfg0 *pmfg0;
+ fCONFIG_PAGE_MANUFACTURING_0 mfgp0;
+ mpt_softc_t *mpt = (mpt_softc_t *)dev;
+
+ switch (cmd) {
+ case MPT_IOCTL_DUMMY:
+ dummy = (struct mpt_dummy *)addr;
+ if (mpt->verbose > 2) {
+ printf("%s: MPT_IOCTL_DUMMY %d\n",
+ dev->dv_xname, dummy->x++);
+ }
+ break;
+ /* Retrieve Manufacturing Page 0 */
+ case MPT_IOCTL_MFG0:
+ mfgp0.Header.PageNumber = 0;
+ mfgp0.Header.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
+ rv = mpt_read_cfg_page(mpt, 0, &mfgp0.Header);
+ if (rv) {
+ mpt_prt(mpt, "Could not retrieve MFG PAGE 0.");
+ error = EINVAL;
+ }
+ else {
+ if (mpt->verbose > 2) {
+ printf("Chip name: %s\n",
+ mfgp0.ChipName);
+ printf("Chip Revision: %s\n",
+ mfgp0.ChipRevision);
+ printf("Board name: %s\n",
+ mfgp0.BoardName);
+ printf("Board assembly: %s\n",
+ mfgp0.BoardAssembly);
+ printf("Board tracer number: %s\n",
+ mfgp0.BoardTracerNumber);
+ }
+ pmfg0 = (struct mpt_mfg0 *)addr;
+ memcpy(&pmfg0->cpm0, &mfgp0,
+ sizeof(fCONFIG_PAGE_MANUFACTURING_0));
+ }
+ break;
+ /* Retrieve Manufacturing Page 1 */
+ case MPT_IOCTL_MFG1:
+ break;
+ /* Retrieve Manufacturing Page 2 */
+ case MPT_IOCTL_MFG2:
+ break;
+ /* Retrieve Manufacturing Page 3 */
+ case MPT_IOCTL_MFG3:
+ break;
+ /* Retrieve Manufacturing Page 4 */
+ case MPT_IOCTL_MFG4:
+ break;
+ default:
+ error = EINVAL;
+ }
+ return (error);
+}
+#endif
diff --git a/sys/dev/ic/mpt_openbsd.h b/sys/dev/ic/mpt_openbsd.h
index e9710f5b862..a27537c768d 100644
--- a/sys/dev/ic/mpt_openbsd.h
+++ b/sys/dev/ic/mpt_openbsd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpt_openbsd.h,v 1.9 2004/08/23 20:52:15 marco Exp $ */
+/* $OpenBSD: mpt_openbsd.h,v 1.10 2004/10/22 04:54:26 marco Exp $ */
/* $NetBSD: mpt_netbsd.h,v 1.2 2003/04/16 23:02:14 thorpej Exp $ */
/*
@@ -106,6 +106,7 @@
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/device.h>
+#include <sys/ioctl.h>
#include <sys/kernel.h>
#include <sys/timeout.h>
#include <sys/errno.h>
@@ -120,8 +121,12 @@
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
+#include <dev/biovar.h>
+#include <dev/ic/mpt_ioctl.h>
#include <dev/ic/mpt_mpilib.h>
+#include "bio.h"
+
/*
* macro to convert from milliseconds to hz without integer overflow
* Default version using only 32bits arithmetics.
@@ -245,6 +250,24 @@ typedef struct mpt_softc {
struct mpt_fc_cfg {
uint8_t nada;
} fc;
+
+ struct mpt_mfg_cfg {
+ fCONFIG_PAGE_MANUFACTURING_0 _mfg_page0;
+ } mfg;
+#define mpt_mfg_page0 cfg.mfg._mfg_page0
+
+ struct mpt_ioc_cfg {
+ fCONFIG_PAGE_IOC_0 _ioc_page0;
+ fCONFIG_PAGE_IOC_1 _ioc_page1;
+ fCONFIG_PAGE_IOC_2 _ioc_page2;
+ fCONFIG_PAGE_IOC_3 _ioc_page3;
+ fCONFIG_PAGE_IOC_4 _ioc_page4;
+ } ioc;
+#define mpt_ioc_page0 cfg.ioc._ioc_page0
+#define mpt_ioc_page1 cfg.ioc._ioc_page1
+#define mpt_ioc_page2 cfg.ioc._ioc_page2
+#define mpt_ioc_page3 cfg.ioc._ioc_page3
+#define mpt_ioc_page4 cfg.ioc._ioc_page4
} cfg;
bus_space_tag_t sc_st;