diff options
author | Marco Peereboom <marco@cvs.openbsd.org> | 2004-10-22 04:54:27 +0000 |
---|---|---|
committer | Marco Peereboom <marco@cvs.openbsd.org> | 2004-10-22 04:54:27 +0000 |
commit | 4f5a87912a29838d26696f65b9d4ae0288319a0f (patch) | |
tree | cf2e4432b904a8938f124901d4bdac7d3f6c6225 /sys | |
parent | 6ce3fe385804aa9522092341962f67f7ad197856 (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.c | 128 | ||||
-rw-r--r-- | sys/dev/ic/mpt_openbsd.c | 108 | ||||
-rw-r--r-- | sys/dev/ic/mpt_openbsd.h | 25 |
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; |