diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -1539,7 +1539,15 @@ chan, id, pdb->portid, un.bill.pdb_flags, un.bill.pdb_curstate, un.bill.pdb_laststate); - if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE || un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) { + /* + * XXX KDM this is broken for NVMe. Need to determine whether this + * is an NVMe target, and if so, check the NVMe status bits. We are + * probably missing more bits for proper NVMe support, though. + */ + if (((un.bill.pdb_curstate & PDB2400_STATE_FCP_MASK) < + PDB2400_STATE_PLOGI_DONE) + || ((un.bill.pdb_curstate & PDB2400_STATE_FCP_MASK) > + PDB2400_STATE_LOGGED_IN)) { mbs.param[0] = MBOX_NOT_LOGGED_IN; return (mbs.param[0]); } diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h --- a/sys/dev/isp/ispmbox.h +++ b/sys/dev/isp/ispmbox.h @@ -890,6 +890,10 @@ #define PDB2400_CLASS2 0x0010 #define PDB2400_ADDR_VALID 0x0002 +/* + * For NVMe, the state is the high nibble. For FCP, the state is the low + * nibble. This appears to have changed with the 9.x firmware. + */ #define PDB2400_STATE_PLOGI_PEND 0x03 #define PDB2400_STATE_PLOGI_DONE 0x04 #define PDB2400_STATE_PRLI_PEND 0x05 @@ -897,6 +901,8 @@ #define PDB2400_STATE_PORT_UNAVAIL 0x07 #define PDB2400_STATE_PRLO_PEND 0x09 #define PDB2400_STATE_LOGO_PEND 0x0B +#define PDB2400_STATE_FCP_MASK 0x0f +#define PDB2400_STATE_NVME_SHIFT 4 /* * Common elements from the above two structures that are actually useful to us.