diff --git a/sys/dev/mpt/mpt.c b/sys/dev/mpt/mpt.c index 2c289d3a76f..24ef2543056 100644 --- a/sys/dev/mpt/mpt.c +++ b/sys/dev/mpt/mpt.c @@ -1640,13 +1640,26 @@ mpt_write_cfg_page(struct mpt_softc *mpt, int Action, uint32_t PageAddress, hdr->PageType & MPI_CONFIG_PAGETYPE_MASK); return (-1); } - hdr->PageType &= MPI_CONFIG_PAGETYPE_MASK, + +#if 0 + /* + * We shouldn't mask off other bits here. + */ + hdr->PageType &= MPI_CONFIG_PAGETYPE_MASK; +#endif req = mpt_get_request(mpt, sleep_ok); if (req == NULL) return (-1); - memcpy(((caddr_t)req->req_vbuf)+MPT_RQSL(mpt), hdr, len); + memcpy(((caddr_t)req->req_vbuf) + MPT_RQSL(mpt), hdr, len); + + /* + * There isn't any point in restoring stripped out attributes + * if you then mask them going down to issue the request. + */ + +#if 0 /* Restore stripped out attributes */ hdr->PageType |= hdr_attr; @@ -1655,6 +1668,13 @@ mpt_write_cfg_page(struct mpt_softc *mpt, int Action, uint32_t PageAddress, hdr->PageType & MPI_CONFIG_PAGETYPE_MASK, PageAddress, req->req_pbuf + MPT_RQSL(mpt), len, sleep_ok, timeout_ms); +#else + error = mpt_issue_cfg_req(mpt, req, Action, hdr->PageVersion, + hdr->PageLength, hdr->PageNumber, + hdr->PageType, PageAddress, + req->req_pbuf + MPT_RQSL(mpt), + len, sleep_ok, timeout_ms); +#endif if (error != 0) { mpt_prt(mpt, "mpt_write_cfg_page timed out\n"); return (-1); @@ -1936,6 +1956,9 @@ mpt_sysctl_attach(struct mpt_softc *mpt) SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "debug", CTLFLAG_RW, &mpt->verbose, 0, "Debugging/Verbose level"); + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "role", CTLFLAG_RD, &mpt->role, 0, + "HBA role"); #endif } @@ -2454,9 +2477,11 @@ mpt_configure_ioc(struct mpt_softc *mpt) mpt->mpt_max_devices = pfp.MaxDevices; /* - * Set our expected role with what this port supports. + * Set our role with what this port supports. + * + * Note this might be changed later in different modules + * if this is different from what is wanted. */ - mpt->role = MPT_ROLE_NONE; if (pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) { mpt->role |= MPT_ROLE_INITIATOR; @@ -2464,12 +2489,6 @@ mpt_configure_ioc(struct mpt_softc *mpt) if (pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) { mpt->role |= MPT_ROLE_TARGET; } - if (mpt->role == MPT_ROLE_NONE) { - mpt_prt(mpt, "port does not support either target or " - "initiator role\n"); - return (ENXIO); - } - if (mpt_enable_ioc(mpt, 0) != MPT_OK) { mpt_prt(mpt, "unable to initialize IOC\n"); return (ENXIO); diff --git a/sys/dev/mpt/mpt.h b/sys/dev/mpt/mpt.h index bfc134949d4..d2ccbd5949b 100644 --- a/sys/dev/mpt/mpt.h +++ b/sys/dev/mpt/mpt.h @@ -490,13 +490,12 @@ struct mpt_softc { int mpt_locksetup; #endif uint32_t mpt_pers_mask; - uint32_t : 8, + uint32_t unit : 8, - : 1, + : 3, twildcard : 1, tenabled : 1, - role : 2, /* none, ini, target, both */ - : 1, + do_cfg_role : 1, raid_enabled : 1, raid_mwce_set : 1, getreqwaiter : 1, @@ -508,6 +507,9 @@ struct mpt_softc { is_sas : 1, is_fc : 1; + u_int cfg_role; + u_int role; /* role: none, ini, target, both */ + u_int verbose; /* @@ -942,6 +944,7 @@ int mpt_decode_value(mpt_decode_entry_t *table, u_int num_entries, const char *name, u_int value, u_int *cur_column, u_int wrap_point); +void mpt_dump_data(struct mpt_softc *, const char *, void *, int); void mpt_dump_request(struct mpt_softc *, request_t *); enum { diff --git a/sys/dev/mpt/mpt_cam.c b/sys/dev/mpt/mpt_cam.c index 1a53679683a..653997433f3 100644 --- a/sys/dev/mpt/mpt_cam.c +++ b/sys/dev/mpt/mpt_cam.c @@ -436,49 +436,96 @@ mpt_read_config_info_fc(struct mpt_softc *mpt) static int mpt_set_initial_config_fc(struct mpt_softc *mpt) { -#if 0 + CONFIG_PAGE_FC_PORT_1 fc; U32 fl; int r, doit = 0; - - if ((mpt->role & MPT_ROLE_TARGET) == 0) { - return (0); - } + int role; r = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_FC_PORT, 1, 0, &fc.Header, FALSE, 5000); if (r) { + mpt_prt(mpt, "failed to read FC page 1 header\n"); return (mpt_fc_reset_link(mpt, 1)); } - r = mpt_read_cfg_page(mpt, MPI_CONFIG_ACTION_PAGE_READ_CURRENT, 0, + r = mpt_read_cfg_page(mpt, MPI_CONFIG_ACTION_PAGE_READ_NVRAM, 0, &fc.Header, sizeof (fc), FALSE, 5000); if (r) { + mpt_prt(mpt, "failed to read FC page 1\n"); return (mpt_fc_reset_link(mpt, 1)); } - fl = le32toh(fc.Flags); - if ((fl & MPI_FCPORTPAGE1_FLAGS_TARGET_MODE_OXID) == 0) { - fl |= MPI_FCPORTPAGE1_FLAGS_TARGET_MODE_OXID; - doit = 1; - } - if (doit) { - const char *cc; + /* + * Check our flags to make sure we support the role we want. + */ + doit = 0; + role = 0; + fl = le32toh(fc.Flags);; - mpt_lprt(mpt, MPT_PRT_INFO, - "FC Port Page 1: New Flags %x \n", fl); + if (fl & MPI_FCPORTPAGE1_FLAGS_PROT_FCP_INIT) { + role |= MPT_ROLE_INITIATOR; + } + if (fl & MPI_FCPORTPAGE1_FLAGS_PROT_FCP_TARG) { + role |= MPT_ROLE_TARGET; + } + + fl &= ~MPI_FCPORTPAGE1_FLAGS_PROT_MASK; + + if (mpt->do_cfg_role == 0) { + role = mpt->cfg_role; + } else { + mpt->do_cfg_role = 0; + } + + if (role != mpt->cfg_role) { + if (mpt->cfg_role & MPT_ROLE_INITIATOR) { + if ((role & MPT_ROLE_INITIATOR) == 0) { + mpt_prt(mpt, "adding initiator role\n"); + fl |= MPI_FCPORTPAGE1_FLAGS_PROT_FCP_INIT; + doit++; + } else { + mpt_prt(mpt, "keeping initiator role\n"); + } + } else if (role & MPT_ROLE_INITIATOR) { + mpt_prt(mpt, "removing initiator role\n"); + doit++; + } + if (mpt->cfg_role & MPT_ROLE_TARGET) { + if ((role & MPT_ROLE_TARGET) == 0) { + mpt_prt(mpt, "adding target role\n"); + fl |= MPI_FCPORTPAGE1_FLAGS_PROT_FCP_TARG; + doit++; + } else { + mpt_prt(mpt, "keeping target role\n"); + } + } else if (role & MPT_ROLE_TARGET) { + mpt_prt(mpt, "removing target role\n"); + doit++; + } + mpt->role = mpt->cfg_role; + } + + if (fl & MPI_FCPORTPAGE1_FLAGS_PROT_FCP_TARG) { + if ((fl & MPI_FCPORTPAGE1_FLAGS_TARGET_MODE_OXID) == 0) { + mpt_prt(mpt, "adding OXID option\n"); + fl |= MPI_FCPORTPAGE1_FLAGS_TARGET_MODE_OXID; + doit++; + } + } + + if (doit) { fc.Flags = htole32(fl); r = mpt_write_cfg_page(mpt, - MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT, 0, &fc.Header, + MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM, 0, &fc.Header, sizeof(fc), FALSE, 5000); if (r != 0) { - cc = "FC PORT PAGE1 UPDATE: FAILED\n"; - } else { - cc = "FC PORT PAGE1 UPDATED: SYSTEM NEEDS RESET\n"; + mpt_prt(mpt, "failed to update NVRAM with changes\n"); + return (0); } - mpt_prt(mpt, cc); + mpt_prt(mpt, "NOTE: NVRAM changes will not take " + "effect until next reboot or IOC reset\n"); } -#endif return (0); } diff --git a/sys/dev/mpt/mpt_debug.c b/sys/dev/mpt/mpt_debug.c index f5546ad0303..53b0c26431c 100644 --- a/sys/dev/mpt/mpt_debug.c +++ b/sys/dev/mpt/mpt_debug.c @@ -800,6 +800,21 @@ mpt_dump_sgl(SGE_IO_UNION *su, int offset) } while ((flags & MPI_SGE_FLAGS_END_OF_LIST) == 0 && nxtaddr < lim); } +void +mpt_dump_data(struct mpt_softc *mpt, const char *msg, void *addr, int len) +{ + int offset; + uint8_t *cp = addr; + mpt_prt(mpt, "%s:", msg); + for (offset = 0; offset < len; offset++) { + if ((offset & 0xf) == 0) { + mpt_prtc(mpt, "\n"); + } + mpt_prtc(mpt, " %02x", cp[offset]); + } + mpt_prtc(mpt, "\n"); +} + void mpt_dump_request(struct mpt_softc *mpt, request_t *req) { diff --git a/sys/dev/mpt/mpt_pci.c b/sys/dev/mpt/mpt_pci.c index 32f2ebe0b6d..47bbf7bc793 100644 --- a/sys/dev/mpt/mpt_pci.c +++ b/sys/dev/mpt/mpt_pci.c @@ -213,8 +213,9 @@ mpt_pci_probe(device_t dev) { char *desc; - if (pci_get_vendor(dev) != PCI_VENDOR_LSI) + if (pci_get_vendor(dev) != PCI_VENDOR_LSI) { return (ENXIO); + } switch ((pci_get_device(dev) & ~1)) { case PCI_PRODUCT_LSI_FC909: @@ -295,6 +296,29 @@ mpt_set_options(struct mpt_softc *mpt) mpt->verbose = MPT_PRT_DEBUG3; } } + + mpt->cfg_role = MPT_ROLE_DEFAULT; + bitmap = 0; + if (getenv_int("mpt_nil_role", &bitmap)) { + if (bitmap & (1 << mpt->unit)) { + mpt->cfg_role = 0; + } + mpt->do_cfg_role = 1; + } + bitmap = 0; + if (getenv_int("mpt_tgt_role", &bitmap)) { + if (bitmap & (1 << mpt->unit)) { + mpt->cfg_role |= MPT_ROLE_TARGET; + } + mpt->do_cfg_role = 1; + } + bitmap = 0; + if (getenv_int("mpt_ini_role", &bitmap)) { + if (bitmap & (1 << mpt->unit)) { + mpt->cfg_role |= MPT_ROLE_INITIATOR; + } + mpt->do_cfg_role = 1; + } } #else static void @@ -312,11 +336,12 @@ mpt_set_options(struct mpt_softc *mpt) device_get_unit(mpt->dev), "debug", &tval) == 0 && tval != 0) { mpt->verbose = tval; } - tval = 0; + tval = -1; if (resource_int_value(device_get_name(mpt->dev), - device_get_unit(mpt->dev), "role", &tval) == 0 && tval != 0 && + device_get_unit(mpt->dev), "role", &tval) == 0 && tval >= 0 && tval <= 3) { - mpt->role = tval; + mpt->cfg_role = tval; + mpt->do_cfg_role = 1; } } #endif