freebsd-src/sys/dev/mpi3mr/mpi3mr_cam.h
Chandrakanth patil 3f3a15543a mpi3mr: Divert large WriteSame IOs to firmware if unmap and ndob bits are set
Firmware advertises the transfer lenght for writesame commands to driver during init.
So for any writesame IOs with ndob and unmap bit set and transfer lengh is greater
than the max write same length specified by the firmware, then direct those commands
to firmware instead of hardware otherwise hardware will break.

Reviewed by:            imp
Approved by:            imp
Differential revision:  https://reviews.freebsd.org/D44452
2024-06-06 10:39:15 +00:00

201 lines
5.8 KiB
C

/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020-2024, Broadcom Inc. All rights reserved.
* Support: <fbsd-storage-driver.pdl@broadcom.com>
*
* Authors: Sumit Saxena <sumit.saxena@broadcom.com>
* Chandrakanth Patil <chandrakanth.patil@broadcom.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
* 3. Neither the name of the Broadcom Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing
* official policies,either expressed or implied, of the FreeBSD Project.
*
* Mail to: Broadcom Inc 1320 Ridder Park Dr, San Jose, CA 95131
*
* Broadcom Inc. (Broadcom) MPI3MR Adapter FreeBSD
*/
#include "mpi3mr.h"
struct mpi3mr_fw_event_work;
struct mpi3mr_throttle_group_info {
U8 io_divert;
U16 fw_qd;
U16 modified_qd;
U16 id;
U32 high;
U32 low;
mpi3mr_atomic_t pend_large_data_sz;
};
struct mpi3mr_tgt_dev_sassata {
U64 sas_address;
U16 dev_info;
};
struct mpi3mr_tgt_dev_pcie {
U32 mdts;
U16 capb;
U8 pgsz;
U8 abort_to;
U8 reset_to;
U16 dev_info;
};
struct mpi3mr_tgt_dev_volume {
U8 state;
U16 tg_id;
U32 tg_high;
U32 tg_low;
struct mpi3mr_throttle_group_info *tg;
};
typedef union _mpi3mr_form_spec_inf {
struct mpi3mr_tgt_dev_sassata sassata_inf;
struct mpi3mr_tgt_dev_pcie pcie_inf;
struct mpi3mr_tgt_dev_volume vol_inf;
} mpi3mr_form_spec_inf;
struct mpi3mr_target {
uint16_t dev_handle;
uint16_t slot;
uint16_t per_id;
uint8_t dev_type;
volatile uint8_t is_hidden;
volatile uint8_t dev_removed;
U8 dev_removedelay;
mpi3mr_atomic_t block_io;
uint8_t exposed_to_os;
uint16_t qdepth;
uint64_t wwid;
mpi3mr_form_spec_inf dev_spec;
uint16_t tid;
uint16_t exp_dev_handle;
uint16_t phy_num;
uint64_t sasaddr;
uint16_t parent_handle;
uint64_t parent_sasaddr;
uint32_t parent_devinfo;
mpi3mr_atomic_t outstanding;
uint8_t scsi_req_desc_type;
TAILQ_ENTRY(mpi3mr_target) tgt_next;
uint16_t handle;
uint8_t link_rate;
uint8_t encl_level_valid;
uint8_t encl_level;
char connector_name[4];
uint64_t devname;
uint32_t devinfo;
uint16_t encl_handle;
uint16_t encl_slot;
uint8_t flags;
#define MPI3MRSAS_TARGET_INREMOVAL (1 << 3)
uint8_t io_throttle_enabled;
uint8_t io_divert;
struct mpi3mr_throttle_group_info *throttle_group;
uint64_t q_depth;
enum mpi3mr_target_state state;
uint16_t ws_len;
};
struct mpi3mr_cam_softc {
struct mpi3mr_softc *sc;
u_int flags;
#define MPI3MRSAS_IN_DISCOVERY (1 << 0)
#define MPI3MRSAS_IN_STARTUP (1 << 1)
#define MPI3MRSAS_DISCOVERY_TIMEOUT_PENDING (1 << 2)
#define MPI3MRSAS_QUEUE_FROZEN (1 << 3)
#define MPI3MRSAS_SHUTDOWN (1 << 4)
u_int maxtargets;
struct cam_devq *devq;
struct cam_sim *sim;
struct cam_path *path;
struct intr_config_hook sas_ich;
struct callout discovery_callout;
struct mpi3mr_event_handle *mpi3mr_eh;
u_int startup_refcount;
struct proc *sysctl_proc;
struct taskqueue *ev_tq;
struct task ev_task;
TAILQ_HEAD(, mpi3mr_fw_event_work) ev_queue;
TAILQ_HEAD(, mpi3mr_target) tgt_list;
};
MALLOC_DECLARE(M_MPI3MRSAS);
static __inline void
mpi3mr_set_ccbstatus(union ccb *ccb, int status)
{
ccb->ccb_h.status &= ~CAM_STATUS_MASK;
ccb->ccb_h.status |= status;
}
static __inline int
mpi3mr_get_ccbstatus(union ccb *ccb)
{
return (ccb->ccb_h.status & CAM_STATUS_MASK);
}
static __inline void mpi3mr_print_cdb(union ccb *ccb)
{
struct ccb_scsiio *csio;
struct mpi3mr_cam_softc *cam_sc;
struct cam_sim *sim;
int i;
sim = xpt_path_sim(ccb->ccb_h.path);
cam_sc = cam_sim_softc(sim);
csio = &ccb->csio;
mpi3mr_dprint(cam_sc->sc, MPI3MR_INFO, "tgtID: %d CDB: ", csio->ccb_h.target_id);
for (i = 0; i < csio->cdb_len; i++)
printf("%x ", csio->cdb_io.cdb_bytes[i]);
printf("\n");
}
void mpi3mr_rescan_target(struct mpi3mr_softc *sc, struct mpi3mr_target *targ);
void mpi3mr_discovery_end(struct mpi3mr_cam_softc *sassc);
void mpi3mr_prepare_for_tm(struct mpi3mr_softc *sc, struct mpi3mr_cmd *tm,
struct mpi3mr_target *target, lun_id_t lun_id);
void mpi3mr_startup_increment(struct mpi3mr_cam_softc *sassc);
void mpi3mr_startup_decrement(struct mpi3mr_cam_softc *sassc);
void mpi3mr_firmware_event_work(void *arg, int pending);
int mpi3mr_check_id(struct mpi3mr_cam_softc *sassc, int id);
int
mpi3mr_cam_attach(struct mpi3mr_softc *sc);
int
mpi3mr_cam_detach(struct mpi3mr_softc *sc);
void
mpi3mr_evt_handler(struct mpi3mr_softc *sc, uintptr_t data,
MPI3_EVENT_NOTIFICATION_REPLY *event);