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:
Matt Jacob 2006-07-12 07:48:50 +00:00
parent a94d3e1f8a
commit b4c618c099
5 changed files with 148 additions and 39 deletions

View File

@ -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);

View File

@ -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 {

View File

@ -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);
}

View File

@ -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)
{

View File

@ -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