/**
 * mrsas_build_dcdb:       Builds an DCDB command  
 * input:                  Adapter instance soft state
 *                         Pointer to command packet
 *                         Pointer to CCB 
 *
 * This function builds the DCDB inquiry command.  It returns 0 if the 
 * command is built successfully, otherwise it returns a 1. 
 */
int mrsas_build_dcdb(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
                      union ccb *ccb, struct cam_sim *sim)
{
    struct ccb_hdr *ccb_h = &(ccb->ccb_h);
    u_int32_t device_id;
    MR_FW_RAID_MAP_ALL *map_ptr;
    MRSAS_RAID_SCSI_IO_REQUEST *io_request;

    io_request = cmd->io_request;
    device_id = ccb_h->target_id;
    map_ptr = sc->raidmap_mem[(sc->map_id & 1)];

    /* Check if this is for system PD */ 
    if (cam_sim_bus(sim) == 1 && 
            sc->pd_list[device_id].driveState == MR_PD_STATE_SYSTEM) {
        io_request->Function = 0;
        io_request->DevHandle = map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
        io_request->RaidContext.timeoutValue = map_ptr->raidMap.fpPdIoTimeoutSec;
        io_request->RaidContext.regLockFlags = 0;
        io_request->RaidContext.regLockRowLBA = 0;
        io_request->RaidContext.regLockLength = 0;
        io_request->RaidContext.RAIDFlags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD << 
            MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
	    if ((sc->device_id == MRSAS_INVADER) || (sc->device_id == MRSAS_FURY))
            io_request->IoFlags |= MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH;
        cmd->request_desc->SCSIIO.RequestFlags = 
            (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY << 
            MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
        cmd->request_desc->SCSIIO.DevHandle = 
            map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
    }
    else {
        io_request->Function  = MRSAS_MPI2_FUNCTION_LD_IO_REQUEST;
        io_request->DevHandle = device_id;
        cmd->request_desc->SCSIIO.RequestFlags =
            (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO << MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
    }
	
    io_request->RaidContext.VirtualDiskTgtId = device_id;
    io_request->LUN[1] = ccb_h->target_lun & 0xF;
    io_request->DataLength = cmd->length;

    if (mrsas_map_request(sc, cmd) == SUCCESS) {
        if (cmd->sge_count > sc->max_num_sge) {
            device_printf(sc->mrsas_dev, "Error: sge_count (0x%x) exceeds" 
                "max (0x%x) allowed\n", cmd->sge_count, sc->max_num_sge);
            return (1);
        }
        io_request->RaidContext.numSGE = cmd->sge_count;
    }
    else {
        device_printf(sc->mrsas_dev, "Data map/load failed.\n");
        return(1);
    } 
    return(0);
}
Exemplo n.º 2
0
/*
 * mrsas_build_ldio_rw:	Builds an LDIO command
 * input:				Adapter instance soft state
 * 						Pointer to command packet
 * 						Pointer to CCB
 *
 * This function builds the LDIO command packet.  It returns 0 if the command is
 * built successfully, otherwise it returns a 1.
 */
int
mrsas_build_ldio_rw(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
    union ccb *ccb)
{
	struct ccb_hdr *ccb_h = &(ccb->ccb_h);
	struct ccb_scsiio *csio = &(ccb->csio);
	u_int32_t device_id;
	MRSAS_RAID_SCSI_IO_REQUEST *io_request;

	device_id = ccb_h->target_id;

	io_request = cmd->io_request;
	io_request->RaidContext.VirtualDiskTgtId = device_id;
	io_request->RaidContext.status = 0;
	io_request->RaidContext.exStatus = 0;

	/* just the cdb len, other flags zero, and ORed-in later for FP */
	io_request->IoFlags = csio->cdb_len;

	if (mrsas_setup_io(sc, cmd, ccb, device_id, io_request) != SUCCESS)
		device_printf(sc->mrsas_dev, "Build ldio or fpio error\n");

	io_request->DataLength = cmd->length;

	if (mrsas_map_request(sc, cmd, ccb) == SUCCESS) {
		if (cmd->sge_count > sc->max_num_sge) {
			device_printf(sc->mrsas_dev, "Error: sge_count (0x%x) exceeds"
			    "max (0x%x) allowed\n", cmd->sge_count, sc->max_num_sge);
			return (FAIL);
		}
		/*
		 * numSGE store lower 8 bit of sge_count. numSGEExt store
		 * higher 8 bit of sge_count
		 */
		io_request->RaidContext.numSGE = cmd->sge_count;
		io_request->RaidContext.numSGEExt = (uint8_t)(cmd->sge_count >> 8);

	} else {
Exemplo n.º 3
0
/*
 * mrsas_build_dcdb:	Builds an DCDB command
 * input:				Adapter instance soft state
 * 						Pointer to command packet
 * 						Pointer to CCB
 *
 * This function builds the DCDB inquiry command.  It returns 0 if the command
 * is built successfully, otherwise it returns a 1.
 */
int
mrsas_build_dcdb(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
    union ccb *ccb, struct cam_sim *sim)
{
	struct ccb_hdr *ccb_h = &(ccb->ccb_h);
	u_int32_t device_id;
	MR_DRV_RAID_MAP_ALL *map_ptr;
	MRSAS_RAID_SCSI_IO_REQUEST *io_request;

	io_request = cmd->io_request;
	device_id = ccb_h->target_id;
	map_ptr = sc->ld_drv_map[(sc->map_id & 1)];

	/*
         * Check if this is RW for system PD or
         * it's a NON RW for sys PD and there is NO secure jbod FW support
         */
	if (cam_sim_bus(sim) == 1 &&
	    sc->pd_list[device_id].driveState == MR_PD_STATE_SYSTEM) {

		io_request->DevHandle =
		    map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
		io_request->RaidContext.RAIDFlags =
		    MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD <<
		    MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
		cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle;
		cmd->request_desc->SCSIIO.MSIxIndex =
		    sc->msix_vectors ? smp_processor_id() % sc->msix_vectors : 0;

		if (sc->secure_jbod_support && (mrsas_find_io_type(sim, ccb) == NON_READ_WRITE_SYSPDIO)) {
			/* system pd firmware path */
			io_request->Function = MRSAS_MPI2_FUNCTION_LD_IO_REQUEST;
			cmd->request_desc->SCSIIO.RequestFlags =
			    (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO << MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
		} else {
			/* system pd fast path */
			io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
			io_request->RaidContext.timeoutValue = map_ptr->raidMap.fpPdIoTimeoutSec;
			io_request->RaidContext.regLockFlags = 0;
			io_request->RaidContext.regLockRowLBA = 0;
			io_request->RaidContext.regLockLength = 0;

			cmd->request_desc->SCSIIO.RequestFlags =
			    (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
			    MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);

			/*
			 * NOTE - For system pd RW cmds only IoFlags will be FAST_PATH
			 * Because the NON RW cmds will now go via FW Queue
			 * and not the Exception queue
			 */
			if ((sc->device_id == MRSAS_INVADER) || (sc->device_id == MRSAS_FURY))
				io_request->IoFlags |= MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH;
		}
	} else {
		/* FW path for SysPD or LD Non-RW (SCSI management commands) */
		io_request->Function = MRSAS_MPI2_FUNCTION_LD_IO_REQUEST;
		io_request->DevHandle = device_id;
		cmd->request_desc->SCSIIO.RequestFlags =
		    (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
		    MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
	}

	io_request->RaidContext.VirtualDiskTgtId = device_id;
	io_request->LUN[1] = ccb_h->target_lun & 0xF;
	io_request->DataLength = cmd->length;

	if (mrsas_map_request(sc, cmd, ccb) == SUCCESS) {
		if (cmd->sge_count > sc->max_num_sge) {
			device_printf(sc->mrsas_dev, "Error: sge_count (0x%x) exceeds"
			    "max (0x%x) allowed\n", cmd->sge_count, sc->max_num_sge);
			return (1);
		}
		io_request->RaidContext.numSGE = cmd->sge_count;
	} else {
		device_printf(sc->mrsas_dev, "Data map/load failed.\n");
		return (1);
	}
	return (0);
}