Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/mpi3mr/mpi3mr_cam.c
Show First 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | |||||
#include <cam/scsi/smp_all.h> | #include <cam/scsi/smp_all.h> | ||||
#include <dev/nvme/nvme.h> | #include <dev/nvme/nvme.h> | ||||
#include "mpi/mpi30_api.h" | #include "mpi/mpi30_api.h" | ||||
#include "mpi3mr_cam.h" | #include "mpi3mr_cam.h" | ||||
#include "mpi3mr.h" | #include "mpi3mr.h" | ||||
#include <sys/time.h> /* XXX for pcpu.h */ | #include <sys/time.h> /* XXX for pcpu.h */ | ||||
#include <sys/pcpu.h> /* XXX for PCPU_GET */ | #include <sys/pcpu.h> /* XXX for PCPU_GET */ | ||||
#include <asm/unaligned.h> | |||||
#define smp_processor_id() PCPU_GET(cpuid) | #define smp_processor_id() PCPU_GET(cpuid) | ||||
static void | static void | ||||
mpi3mr_enqueue_request(struct mpi3mr_softc *sc, struct mpi3mr_cmd *cm); | mpi3mr_enqueue_request(struct mpi3mr_softc *sc, struct mpi3mr_cmd *cm); | ||||
static void | static void | ||||
mpi3mr_map_request(struct mpi3mr_softc *sc, struct mpi3mr_cmd *cm); | mpi3mr_map_request(struct mpi3mr_softc *sc, struct mpi3mr_cmd *cm); | ||||
void | void | ||||
mpi3mr_release_simq_reinit(struct mpi3mr_cam_softc *cam_sc); | mpi3mr_release_simq_reinit(struct mpi3mr_cam_softc *cam_sc); | ||||
static void | static void | ||||
mpi3mr_freeup_events(struct mpi3mr_softc *sc); | mpi3mr_freeup_events(struct mpi3mr_softc *sc); | ||||
extern int | extern int | ||||
mpi3mr_register_events(struct mpi3mr_softc *sc); | mpi3mr_register_events(struct mpi3mr_softc *sc); | ||||
extern void mpi3mr_add_sg_single(void *paddr, U8 flags, U32 length, | extern void mpi3mr_add_sg_single(void *paddr, U8 flags, U32 length, | ||||
bus_addr_t dma_addr); | bus_addr_t dma_addr); | ||||
static U32 event_count; | static U32 event_count; | ||||
static | |||||
inline void mpi3mr_divert_ws(Mpi3SCSIIORequest_t *req, | |||||
struct ccb_scsiio *csio, | |||||
U16 ws_len) | |||||
{ | |||||
U8 unmap = 0, ndob = 0; | |||||
U32 num_blocks = 0; | |||||
U8 opcode = scsiio_cdb_ptr(csio)[0]; | |||||
U16 service_action = ((scsiio_cdb_ptr(csio)[8] << 8) | scsiio_cdb_ptr(csio)[9]); | |||||
if (opcode == WRITE_SAME_16 || | |||||
(opcode == VARIABLE_LEN_CDB && | |||||
service_action == WRITE_SAME_32)) { | |||||
int unmap_ndob_index = (opcode == WRITE_SAME_16) ? 1 : 10; | |||||
unmap = scsiio_cdb_ptr(csio)[unmap_ndob_index] & 0x08; | |||||
ndob = scsiio_cdb_ptr(csio)[unmap_ndob_index] & 0x01; | |||||
num_blocks = get_unaligned_be32(scsiio_cdb_ptr(csio) + | |||||
((opcode == WRITE_SAME_16) ? 10 : 28)); | |||||
/* Check conditions for diversion to firmware */ | |||||
if (unmap && ndob && num_blocks > ws_len) { | |||||
req->MsgFlags |= MPI3_SCSIIO_MSGFLAGS_DIVERT_TO_FIRMWARE; | |||||
req->Flags = htole32(le32toh(req->Flags) | | |||||
MPI3_SCSIIO_FLAGS_DIVERT_REASON_WRITE_SAME_TOO_LARGE); | |||||
} | |||||
} | |||||
} | |||||
static void mpi3mr_prepare_sgls(void *arg, | static void mpi3mr_prepare_sgls(void *arg, | ||||
bus_dma_segment_t *segs, int nsegs, int error) | bus_dma_segment_t *segs, int nsegs, int error) | ||||
{ | { | ||||
struct mpi3mr_softc *sc; | struct mpi3mr_softc *sc; | ||||
struct mpi3mr_cmd *cm; | struct mpi3mr_cmd *cm; | ||||
u_int i; | u_int i; | ||||
bus_addr_t chain_dma; | bus_addr_t chain_dma; | ||||
void *chain; | void *chain; | ||||
▲ Show 20 Lines • Show All 961 Lines • ▼ Show 20 Lines | case MSG_ACA_TASK: | ||||
mpi_control |= MPI3_SCSIIO_FLAGS_TASKATTRIBUTE_ACAQ; | mpi_control |= MPI3_SCSIIO_FLAGS_TASKATTRIBUTE_ACAQ; | ||||
break; | break; | ||||
case CAM_TAG_ACTION_NONE: | case CAM_TAG_ACTION_NONE: | ||||
case MSG_SIMPLE_Q_TAG: | case MSG_SIMPLE_Q_TAG: | ||||
default: | default: | ||||
mpi_control |= MPI3_SCSIIO_FLAGS_TASKATTRIBUTE_SIMPLEQ; | mpi_control |= MPI3_SCSIIO_FLAGS_TASKATTRIBUTE_SIMPLEQ; | ||||
break; | break; | ||||
} | } | ||||
if (targ->ws_len) | |||||
mpi3mr_divert_ws(req, csio, targ->ws_len); | |||||
req->Flags = htole32(mpi_control); | req->Flags = htole32(mpi_control); | ||||
if (csio->ccb_h.flags & CAM_CDB_POINTER) | if (csio->ccb_h.flags & CAM_CDB_POINTER) | ||||
bcopy(csio->cdb_io.cdb_ptr, &req->CDB.CDB32[0], csio->cdb_len); | bcopy(csio->cdb_io.cdb_ptr, &req->CDB.CDB32[0], csio->cdb_len); | ||||
else { | else { | ||||
KASSERT(csio->cdb_len <= IOCDBLEN, | KASSERT(csio->cdb_len <= IOCDBLEN, | ||||
("cdb_len %d is greater than IOCDBLEN but CAM_CDB_POINTER " | ("cdb_len %d is greater than IOCDBLEN but CAM_CDB_POINTER " | ||||
▲ Show 20 Lines • Show All 1,136 Lines • Show Last 20 Lines |