Add support for the Broadcom (Avago/LSI) 9305 16 and 24 port HBA's.
Reviewed by: ken, scottl, ambrisko, asomers Approved by: ken, scottl, ambrisko MFC after: 1 week Relnotes: yes Differential Revision: https://reviews.freebsd.org/D6098
This commit is contained in:
parent
9b9ab04340
commit
1f91a62e29
@ -441,6 +441,8 @@ mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t attaching)
|
||||
(saved_facts.IOCCapabilities != sc->facts->IOCCapabilities) ||
|
||||
(saved_facts.IOCRequestFrameSize !=
|
||||
sc->facts->IOCRequestFrameSize) ||
|
||||
(saved_facts.IOCMaxChainSegmentSize !=
|
||||
sc->facts->IOCMaxChainSegmentSize) ||
|
||||
(saved_facts.MaxTargets != sc->facts->MaxTargets) ||
|
||||
(saved_facts.MaxSasExpanders != sc->facts->MaxSasExpanders) ||
|
||||
(saved_facts.MaxEnclosures != sc->facts->MaxEnclosures) ||
|
||||
@ -1188,7 +1190,28 @@ mpr_alloc_requests(struct mpr_softc *sc)
|
||||
bus_dmamap_load(sc->req_dmat, sc->req_map, sc->req_frames, rsize,
|
||||
mpr_memaddr_cb, &sc->req_busaddr, 0);
|
||||
|
||||
rsize = sc->facts->IOCRequestFrameSize * sc->max_chains * 4;
|
||||
/*
|
||||
* Gen3 and beyond uses the IOCMaxChainSegmentSize from IOC Facts to
|
||||
* get the size of a Chain Frame. Previous versions use the size as a
|
||||
* Request Frame for the Chain Frame size. If IOCMaxChainSegmentSize
|
||||
* is 0, use the default value. The IOCMaxChainSegmentSize is the
|
||||
* number of 16-byte elelements that can fit in a Chain Frame, which is
|
||||
* the size of an IEEE Simple SGE.
|
||||
*/
|
||||
if (sc->facts->MsgVersion >= MPI2_VERSION_02_05) {
|
||||
sc->chain_seg_size =
|
||||
htole16(sc->facts->IOCMaxChainSegmentSize);
|
||||
if (sc->chain_seg_size == 0) {
|
||||
sc->chain_frame_size = MPR_DEFAULT_CHAIN_SEG_SIZE *
|
||||
MPR_MAX_CHAIN_ELEMENT_SIZE;
|
||||
} else {
|
||||
sc->chain_frame_size = sc->chain_seg_size *
|
||||
MPR_MAX_CHAIN_ELEMENT_SIZE;
|
||||
}
|
||||
} else {
|
||||
sc->chain_frame_size = sc->facts->IOCRequestFrameSize * 4;
|
||||
}
|
||||
rsize = sc->chain_frame_size * sc->max_chains;
|
||||
if (bus_dma_tag_create( sc->mpr_parent_dmat, /* parent */
|
||||
16, 0, /* algnmnt, boundary */
|
||||
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||
@ -1246,9 +1269,9 @@ mpr_alloc_requests(struct mpr_softc *sc)
|
||||
for (i = 0; i < sc->max_chains; i++) {
|
||||
chain = &sc->chains[i];
|
||||
chain->chain = (MPI2_SGE_IO_UNION *)(sc->chain_frames +
|
||||
i * sc->facts->IOCRequestFrameSize * 4);
|
||||
i * sc->chain_frame_size);
|
||||
chain->chain_busaddr = sc->chain_busaddr +
|
||||
i * sc->facts->IOCRequestFrameSize * 4;
|
||||
i * sc->chain_frame_size;
|
||||
mpr_free_chain(sc, chain);
|
||||
sc->chain_free_lowwater++;
|
||||
}
|
||||
@ -2169,7 +2192,7 @@ mpr_add_chain(struct mpr_command *cm, int segsleft)
|
||||
MPI2_REQUEST_HEADER *req;
|
||||
MPI25_IEEE_SGE_CHAIN64 *ieee_sgc;
|
||||
struct mpr_chain *chain;
|
||||
int space, sgc_size, current_segs, rem_segs, segs_per_frame;
|
||||
int sgc_size, current_segs, rem_segs, segs_per_frame;
|
||||
uint8_t next_chain_offset = 0;
|
||||
|
||||
/*
|
||||
@ -2191,8 +2214,6 @@ mpr_add_chain(struct mpr_command *cm, int segsleft)
|
||||
if (chain == NULL)
|
||||
return (ENOBUFS);
|
||||
|
||||
space = (int)cm->cm_sc->facts->IOCRequestFrameSize * 4;
|
||||
|
||||
/*
|
||||
* Note: a double-linked list is used to make it easier to walk for
|
||||
* debugging.
|
||||
@ -2218,13 +2239,14 @@ mpr_add_chain(struct mpr_command *cm, int segsleft)
|
||||
*/
|
||||
current_segs = (cm->cm_sglsize / sgc_size) - 1;
|
||||
rem_segs = segsleft - current_segs;
|
||||
segs_per_frame = space / sgc_size;
|
||||
segs_per_frame = sc->chain_frame_size / sgc_size;
|
||||
if (rem_segs > segs_per_frame) {
|
||||
next_chain_offset = segs_per_frame - 1;
|
||||
}
|
||||
}
|
||||
ieee_sgc = &((MPI25_SGE_IO_UNION *)cm->cm_sge)->IeeeChain;
|
||||
ieee_sgc->Length = next_chain_offset ? htole32((uint32_t)space) :
|
||||
ieee_sgc->Length = next_chain_offset ?
|
||||
htole32((uint32_t)sc->chain_frame_size) :
|
||||
htole32((uint32_t)rem_segs * (uint32_t)sgc_size);
|
||||
ieee_sgc->NextChainOffset = next_chain_offset;
|
||||
ieee_sgc->Flags = (MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
|
||||
@ -2233,10 +2255,9 @@ mpr_add_chain(struct mpr_command *cm, int segsleft)
|
||||
ieee_sgc->Address.High = htole32(chain->chain_busaddr >> 32);
|
||||
cm->cm_sge = &((MPI25_SGE_IO_UNION *)chain->chain)->IeeeSimple;
|
||||
req = (MPI2_REQUEST_HEADER *)cm->cm_req;
|
||||
req->ChainOffset = ((sc->facts->IOCRequestFrameSize * 4) -
|
||||
sgc_size) >> 4;
|
||||
req->ChainOffset = (sc->chain_frame_size - sgc_size) >> 4;
|
||||
|
||||
cm->cm_sglsize = space;
|
||||
cm->cm_sglsize = sc->chain_frame_size;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -110,6 +110,18 @@ struct mpr_ident {
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_5" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_6" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_1,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3316_1" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_2,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3316_2" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_1,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3324_1" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_2,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3324_2" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3216,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3216" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3224,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3224" },
|
||||
{ 0, 0, 0, 0, 0, NULL }
|
||||
};
|
||||
|
||||
|
@ -704,6 +704,7 @@ mprsas_register_events(struct mpr_softc *sc)
|
||||
setbit(events, MPI2_EVENT_IR_PHYSICAL_DISK);
|
||||
setbit(events, MPI2_EVENT_IR_OPERATION_STATUS);
|
||||
setbit(events, MPI2_EVENT_TEMP_THRESHOLD);
|
||||
setbit(events, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
|
||||
|
||||
mpr_register_events(sc, events, mprsas_evt_handler, NULL,
|
||||
&sc->sassc->mprsas_eh);
|
||||
@ -2048,6 +2049,9 @@ mpr_sc_failed_io_info(struct mpr_softc *sc, struct ccb_scsiio *csio,
|
||||
case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
|
||||
desc_ioc_state = "eedp app tag error";
|
||||
break;
|
||||
case MPI2_IOCSTATUS_INSUFFICIENT_POWER:
|
||||
desc_ioc_state = "insufficient power";
|
||||
break;
|
||||
default:
|
||||
desc_ioc_state = "unknown";
|
||||
break;
|
||||
|
@ -645,6 +645,23 @@ mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
|
||||
{
|
||||
pMpi26EventDataActiveCableExcept_t ace_event_data;
|
||||
ace_event_data =
|
||||
(pMpi26EventDataActiveCableExcept_t)fw_event->event_data;
|
||||
|
||||
if (ace_event_data->ReasonCode ==
|
||||
MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER) {
|
||||
mpr_printf(sc, "Currently an active cable with "
|
||||
"ReceptacleID %d cannot be powered and device "
|
||||
"connected to this active cable will not be seen. "
|
||||
"This active cable requires %d mW of power.\n",
|
||||
ace_event_data->ReceptacleID,
|
||||
ace_event_data->ActiveCablePowerRequirement);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
|
||||
case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
|
||||
default:
|
||||
|
@ -46,6 +46,8 @@
|
||||
#define MPR_SGE64_SIZE 12
|
||||
#define MPR_SGE32_SIZE 8
|
||||
#define MPR_SGC_SIZE 8
|
||||
#define MPR_DEFAULT_CHAIN_SEG_SIZE 8
|
||||
#define MPR_MAX_CHAIN_ELEMENT_SIZE 16
|
||||
|
||||
#define MPR_FUNCTRACE(sc) \
|
||||
mpr_dprint((sc), MPR_TRACE, "%s\n", __func__)
|
||||
@ -263,6 +265,8 @@ struct mpr_softc {
|
||||
int chain_free;
|
||||
int max_chains;
|
||||
int chain_free_lowwater;
|
||||
uint32_t chain_frame_size;
|
||||
uint16_t chain_seg_size;
|
||||
u_int enable_ssu;
|
||||
int spinup_wait_time;
|
||||
uint64_t chain_alloc_fail;
|
||||
|
Loading…
Reference in New Issue
Block a user