Fix config page writes to not strip out the attributes when you
actually go write the config page. This fixes the long standing problem about updating NVRAM on Fibre Channel cards and seems so far to not break SPI config page writes. Put back role setting into mpt. That is, you can set a desired role for mpt as a hint. On the next reboot, it'll pick that up and redo the NVRAM settings appropriately and warn you that this won't take effect until the next reboot. This saves people the step of having to find a BIOS utilities disk to set target and/or initiator role for the MPT cards.
This commit is contained in:
parent
a94d3e1f8a
commit
b4c618c099
@ -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);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user