summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/mrsas/mrsas.c312
-rw-r--r--sys/dev/mrsas/mrsas.h214
-rw-r--r--sys/dev/mrsas/mrsas_cam.c150
-rw-r--r--sys/dev/mrsas/mrsas_fp.c202
-rw-r--r--sys/dev/mrsas/mrsas_ioctl.c22
-rw-r--r--sys/dev/mrsas/mrsas_ioctl.h6
-rw-r--r--sys/dev/mrsas/mrsas_linux.c5
7 files changed, 654 insertions, 257 deletions
diff --git a/sys/dev/mrsas/mrsas.c b/sys/dev/mrsas/mrsas.c
index 9c1caa0..3e6dbe8 100644
--- a/sys/dev/mrsas/mrsas.c
+++ b/sys/dev/mrsas/mrsas.c
@@ -1,6 +1,7 @@
/*
+ * Copyright (c) 2015, AVAGO Tech. All rights reserved. Author: Marian Choy
* Copyright (c) 2014, LSI Corp. All rights reserved. Author: Marian Choy
- * Support: freebsdraid@lsi.com
+ * Support: freebsdraid@avagotech.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,7 +32,7 @@
* those of the authors and should not be interpreted as representing
* official policies,either expressed or implied, of the FreeBSD Project.
*
- * Send feedback to: <megaraidfbsd@lsi.com> Mail to: LSI Corporation, 1621
+ * Send feedback to: <megaraidfbsd@avagotech.com> Mail to: AVAGO TECHNOLOGIES 1621
* Barber Lane, Milpitas, CA 95035 ATTN: MegaRaid FreeBSD
*
*/
@@ -81,16 +82,19 @@ static int mrsas_init_fw(struct mrsas_softc *sc);
static int mrsas_setup_raidmap(struct mrsas_softc *sc);
static int mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t MSIxIndex);
static int mrsas_clear_intr(struct mrsas_softc *sc);
-static int
-mrsas_get_ctrl_info(struct mrsas_softc *sc,
- struct mrsas_ctrl_info *ctrl_info);
-static int
+static int mrsas_get_ctrl_info(struct mrsas_softc *sc);
+static void mrsas_update_ext_vd_details(struct mrsas_softc *sc);
+static int
mrsas_issue_blocked_abort_cmd(struct mrsas_softc *sc,
struct mrsas_mfi_cmd *cmd_to_abort);
+static struct mrsas_softc *
+mrsas_get_softc_instance(struct cdev *dev,
+ u_long cmd, caddr_t arg);
u_int32_t mrsas_read_reg(struct mrsas_softc *sc, int offset);
-u_int8_t
+u_int8_t
mrsas_build_mptmfi_passthru(struct mrsas_softc *sc,
struct mrsas_mfi_cmd *mfi_cmd);
+void mrsas_complete_outstanding_ioctls(struct mrsas_softc *sc);
int mrsas_transition_to_ready(struct mrsas_softc *sc, int ocr);
int mrsas_init_adapter(struct mrsas_softc *sc);
int mrsas_alloc_mpt_cmds(struct mrsas_softc *sc);
@@ -102,10 +106,10 @@ int mrsas_issue_dcmd(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd);
int mrsas_issue_polled(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd);
int mrsas_reset_ctrl(struct mrsas_softc *sc);
int mrsas_wait_for_outstanding(struct mrsas_softc *sc);
-int
+int
mrsas_issue_blocked_cmd(struct mrsas_softc *sc,
struct mrsas_mfi_cmd *cmd);
-int
+int
mrsas_alloc_tmp_dcmd(struct mrsas_softc *sc, struct mrsas_tmp_dcmd *tcmd,
int size);
void mrsas_release_mfi_cmd(struct mrsas_mfi_cmd *cmd);
@@ -122,17 +126,17 @@ void mrsas_teardown_intr(struct mrsas_softc *sc);
void mrsas_addr_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error);
void mrsas_kill_hba(struct mrsas_softc *sc);
void mrsas_aen_handler(struct mrsas_softc *sc);
-void
+void
mrsas_write_reg(struct mrsas_softc *sc, int offset,
u_int32_t value);
-void
+void
mrsas_fire_cmd(struct mrsas_softc *sc, u_int32_t req_desc_lo,
u_int32_t req_desc_hi);
void mrsas_free_ctlr_info_cmd(struct mrsas_softc *sc);
-void
+void
mrsas_complete_mptmfi_passthru(struct mrsas_softc *sc,
struct mrsas_mfi_cmd *cmd, u_int8_t status);
-void
+void
mrsas_map_mpt_cmd_status(struct mrsas_mpt_cmd *cmd, u_int8_t status,
u_int8_t extStatus);
struct mrsas_mfi_cmd *mrsas_get_mfi_cmd(struct mrsas_softc *sc);
@@ -175,9 +179,9 @@ typedef struct mrsas_ident {
} MRSAS_CTLR_ID;
MRSAS_CTLR_ID device_table[] = {
- {0x1000, MRSAS_TBOLT, 0xffff, 0xffff, "LSI Thunderbolt SAS Controller"},
- {0x1000, MRSAS_INVADER, 0xffff, 0xffff, "LSI Invader SAS Controller"},
- {0x1000, MRSAS_FURY, 0xffff, 0xffff, "LSI Fury SAS Controller"},
+ {0x1000, MRSAS_TBOLT, 0xffff, 0xffff, "AVAGO Thunderbolt SAS Controller"},
+ {0x1000, MRSAS_INVADER, 0xffff, 0xffff, "AVAGO Invader SAS Controller"},
+ {0x1000, MRSAS_FURY, 0xffff, 0xffff, "AVAGO Fury SAS Controller"},
{0, 0, 0, 0, NULL}
};
@@ -272,6 +276,7 @@ mrsas_disable_intr(struct mrsas_softc *sc)
u_int32_t mask = 0xFFFFFFFF;
u_int32_t status;
+ sc->mask_interrupts = 1;
mrsas_write_reg(sc, offsetof(mrsas_reg_set, outbound_intr_mask), mask);
/* Dummy read to force pci flush */
status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_intr_mask));
@@ -283,6 +288,7 @@ mrsas_enable_intr(struct mrsas_softc *sc)
u_int32_t mask = MFI_FUSION_ENABLE_INTERRUPT_MASK;
u_int32_t status;
+ sc->mask_interrupts = 0;
mrsas_write_reg(sc, offsetof(mrsas_reg_set, outbound_intr_status), ~0);
status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_intr_status));
@@ -352,7 +358,7 @@ mrsas_probe(device_t dev)
if ((id = mrsas_find_ident(dev)) != NULL) {
if (first_ctrl) {
- printf("LSI MegaRAID SAS FreeBSD mrsas driver version: %s\n",
+ printf("AVAGO MegaRAID SAS FreeBSD mrsas driver version: %s\n",
MRSAS_VERSION);
first_ctrl = 0;
}
@@ -460,6 +466,11 @@ mrsas_get_tunables(struct mrsas_softc *sc)
*/
TUNABLE_INT_FETCH("hw.mrsas.debug_level", &sc->mrsas_debug);
+ /*
+ * Grab the global variables.
+ */
+ TUNABLE_INT_FETCH("hw.mrsas.lb_pending_cmds", &sc->lb_pending_cmds);
+
/* Grab the unit-instance variables */
snprintf(tmpstr, sizeof(tmpstr), "dev.mrsas.%d.debug_level",
device_get_unit(sc->mrsas_dev));
@@ -1163,6 +1174,12 @@ mrsas_free_mem(struct mrsas_softc *sc)
*/
if (sc->mrsas_parent_tag != NULL)
bus_dma_tag_destroy(sc->mrsas_parent_tag);
+
+ /*
+ * Free ctrl_info memory
+ */
+ if (sc->ctrl_info != NULL)
+ free(sc->ctrl_info, M_MRSAS);
}
/*
@@ -1231,6 +1248,43 @@ mrsas_resume(device_t dev)
return (0);
}
+/**
+ * mrsas_get_softc_instance: Find softc instance based on cmd type
+ *
+ * This function will return softc instance based on cmd type.
+ * In some case, application fire ioctl on required management instance and
+ * do not provide host_no. Use cdev->si_drv1 to get softc instance for those
+ * case, else get the softc instance from host_no provided by application in
+ * user data.
+ */
+
+static struct mrsas_softc *
+mrsas_get_softc_instance(struct cdev *dev, u_long cmd, caddr_t arg)
+{
+ struct mrsas_softc *sc = NULL;
+ struct mrsas_iocpacket *user_ioc = (struct mrsas_iocpacket *)arg;
+
+ if (cmd == MRSAS_IOC_GET_PCI_INFO) {
+ sc = dev->si_drv1;
+ } else {
+ /*
+ * get the Host number & the softc from data sent by the
+ * Application
+ */
+ sc = mrsas_mgmt_info.sc_ptr[user_ioc->host_no];
+ if ((user_ioc->host_no >= mrsas_mgmt_info.max_index) || (sc == NULL)) {
+ if (sc == NULL)
+ mrsas_dprint(sc, MRSAS_FAULT,
+ "There is no Controller number %d .\n", user_ioc->host_no);
+ else
+ mrsas_dprint(sc, MRSAS_FAULT,
+ "Invalid Controller number %d .\n", user_ioc->host_no);
+ }
+ }
+
+ return sc;
+}
+
/*
* mrsas_ioctl: IOCtl commands entry point.
*
@@ -1242,19 +1296,12 @@ mrsas_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td)
{
struct mrsas_softc *sc;
int ret = 0, i = 0;
+ MRSAS_DRV_PCI_INFORMATION *pciDrvInfo;
- struct mrsas_iocpacket *user_ioc = (struct mrsas_iocpacket *)arg;
-
- /* get the Host number & the softc from data sent by the Application */
- sc = mrsas_mgmt_info.sc_ptr[user_ioc->host_no];
-
- if ((mrsas_mgmt_info.max_index == user_ioc->host_no) || (sc == NULL)) {
- printf("Please check the controller number\n");
- if (sc == NULL)
- printf("There is NO such Host no. %d\n", user_ioc->host_no);
-
+ sc = mrsas_get_softc_instance(dev, cmd, arg);
+ if (!sc)
return ENOENT;
- }
+
if (sc->remove_in_progress) {
mrsas_dprint(sc, MRSAS_INFO,
"Driver remove or shutdown called.\n");
@@ -1298,6 +1345,22 @@ do_ioctl:
case MRSAS_IOC_SCAN_BUS:
ret = mrsas_bus_scan(sc);
break;
+
+ case MRSAS_IOC_GET_PCI_INFO:
+ pciDrvInfo = (MRSAS_DRV_PCI_INFORMATION *) arg;
+ memset(pciDrvInfo, 0, sizeof(MRSAS_DRV_PCI_INFORMATION));
+ pciDrvInfo->busNumber = pci_get_bus(sc->mrsas_dev);
+ pciDrvInfo->deviceNumber = pci_get_slot(sc->mrsas_dev);
+ pciDrvInfo->functionNumber = pci_get_function(sc->mrsas_dev);
+ pciDrvInfo->domainID = pci_get_domain(sc->mrsas_dev);
+ mrsas_dprint(sc, MRSAS_INFO, "pci bus no: %d,"
+ "pci device no: %d, pci function no: %d,"
+ "pci domain ID: %d\n",
+ pciDrvInfo->busNumber, pciDrvInfo->deviceNumber,
+ pciDrvInfo->functionNumber, pciDrvInfo->domainID);
+ ret = 0;
+ break;
+
default:
mrsas_dprint(sc, MRSAS_TRACE, "IOCTL command 0x%lx is not handled\n", cmd);
ret = ENOENT;
@@ -1327,8 +1390,10 @@ mrsas_poll(struct cdev *dev, int poll_events, struct thread *td)
}
if (revents == 0) {
if (poll_events & (POLLIN | POLLRDNORM)) {
+ mtx_lock(&sc->aen_lock);
sc->mrsas_poll_waiting = 1;
selrecord(td, &sc->mrsas_select);
+ mtx_unlock(&sc->aen_lock);
}
}
return revents;
@@ -1386,6 +1451,9 @@ mrsas_isr(void *arg)
struct mrsas_softc *sc = irq_context->sc;
int status = 0;
+ if (sc->mask_interrupts)
+ return;
+
if (!sc->msix_vectors) {
status = mrsas_clear_intr(sc);
if (!status)
@@ -1423,7 +1491,7 @@ mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t MSIxIndex)
MRSAS_RAID_SCSI_IO_REQUEST *scsi_io_req;
struct mrsas_mpt_cmd *cmd_mpt;
struct mrsas_mfi_cmd *cmd_mfi;
- u_int8_t arm, reply_descript_type;
+ u_int8_t reply_descript_type;
u_int16_t smid, num_completed;
u_int8_t status, extStatus;
union desc_value desc_val;
@@ -1461,8 +1529,7 @@ mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t MSIxIndex)
device_id = cmd_mpt->ccb_ptr->ccb_h.target_id;
lbinfo = &sc->load_balance_info[device_id];
if (cmd_mpt->load_balance == MRSAS_LOAD_BALANCE_FLAG) {
- arm = lbinfo->raid1DevHandle[0] == scsi_io_req->DevHandle ? 0 : 1;
- mrsas_atomic_dec(&lbinfo->scsi_pending_cmds[arm]);
+ mrsas_atomic_dec(&lbinfo->scsi_pending_cmds[cmd_mpt->pd_r1_lb]);
cmd_mpt->load_balance &= ~MRSAS_LOAD_BALANCE_FLAG;
}
/* Fall thru and complete IO */
@@ -1607,8 +1674,8 @@ mrsas_map_mpt_cmd_status(struct mrsas_mpt_cmd *cmd, u_int8_t status, u_int8_t ex
static int
mrsas_alloc_mem(struct mrsas_softc *sc)
{
- u_int32_t verbuf_size, io_req_size, reply_desc_size, sense_size, chain_frame_size,
- evt_detail_size, count;
+ u_int32_t verbuf_size, io_req_size, reply_desc_size, sense_size,
+ chain_frame_size, evt_detail_size, count;
/*
* Allocate parent DMA tag
@@ -1860,34 +1927,6 @@ mrsas_setup_raidmap(struct mrsas_softc *sc)
{
int i;
- sc->drv_supported_vd_count =
- MRSAS_MAX_LD_CHANNELS * MRSAS_MAX_DEV_PER_CHANNEL;
- sc->drv_supported_pd_count =
- MRSAS_MAX_PD_CHANNELS * MRSAS_MAX_DEV_PER_CHANNEL;
-
- if (sc->max256vdSupport) {
- sc->fw_supported_vd_count = MAX_LOGICAL_DRIVES_EXT;
- sc->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
- } else {
- sc->fw_supported_vd_count = MAX_LOGICAL_DRIVES;
- sc->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
- }
-
-#if VD_EXT_DEBUG
- device_printf(sc->mrsas_dev, "FW supports: max256vdSupport = %s\n",
- sc->max256vdSupport ? "YES" : "NO");
- device_printf(sc->mrsas_dev, "FW supports %dVDs %dPDs\n"
- "DRIVER supports %dVDs %dPDs \n",
- sc->fw_supported_vd_count, sc->fw_supported_pd_count,
- sc->drv_supported_vd_count, sc->drv_supported_pd_count);
-#endif
-
- sc->old_map_sz = sizeof(MR_FW_RAID_MAP) +
- (sizeof(MR_LD_SPAN_MAP) * (sc->fw_supported_vd_count - 1));
- sc->new_map_sz = sizeof(MR_FW_RAID_MAP_EXT);
- sc->drv_map_sz = sizeof(MR_DRV_RAID_MAP) +
- (sizeof(MR_LD_SPAN_MAP) * (sc->drv_supported_vd_count - 1));
-
for (i = 0; i < 2; i++) {
sc->ld_drv_map[i] =
(void *)malloc(sc->drv_map_sz, M_MRSAS, M_NOWAIT);
@@ -1902,14 +1941,6 @@ mrsas_setup_raidmap(struct mrsas_softc *sc)
}
}
- sc->max_map_sz = max(sc->old_map_sz, sc->new_map_sz);
-
- if (sc->max256vdSupport)
- sc->current_map_sz = sc->new_map_sz;
- else
- sc->current_map_sz = sc->old_map_sz;
-
-
for (int i = 0; i < 2; i++) {
if (bus_dma_tag_create(sc->mrsas_parent_tag,
4, 0,
@@ -1969,7 +2000,7 @@ ABORT:
* get_pdlist, get_ld_list and max_sectors are currently not being used, it
* is left here as placeholder.
*/
-static int
+static int
mrsas_init_fw(struct mrsas_softc *sc)
{
@@ -1977,7 +2008,6 @@ mrsas_init_fw(struct mrsas_softc *sc)
u_int32_t max_sectors_1;
u_int32_t max_sectors_2;
u_int32_t tmp_sectors;
- struct mrsas_ctrl_info *ctrl_info;
u_int32_t scratch_pad_2;
int msix_enable = 0;
int fw_msix_count = 0;
@@ -2039,23 +2069,25 @@ mrsas_init_fw(struct mrsas_softc *sc)
device_printf(sc->mrsas_dev, "Allocate MFI cmd failed.\n");
return (1);
}
+ sc->ctrl_info = malloc(sizeof(struct mrsas_ctrl_info), M_MRSAS, M_NOWAIT);
+ if (!sc->ctrl_info) {
+ device_printf(sc->mrsas_dev, "Malloc for ctrl_info failed.\n");
+ return (1);
+ }
/*
* Get the controller info from FW, so that the MAX VD support
* availability can be decided.
*/
- ctrl_info = malloc(sizeof(struct mrsas_ctrl_info), M_MRSAS, M_NOWAIT);
- if (!ctrl_info)
- device_printf(sc->mrsas_dev, "Malloc for ctrl_info failed.\n");
-
- if (mrsas_get_ctrl_info(sc, ctrl_info)) {
+ if (mrsas_get_ctrl_info(sc)) {
device_printf(sc->mrsas_dev, "Unable to get FW ctrl_info.\n");
+ return (1);
}
- sc->max256vdSupport =
- (u_int8_t)ctrl_info->adapterOperations3.supportMaxExtLDs;
+ sc->secure_jbod_support =
+ (u_int8_t)sc->ctrl_info->adapterOperations3.supportSecurityonJBOD;
+
+ if (sc->secure_jbod_support)
+ device_printf(sc->mrsas_dev, "FW supports SED \n");
- if (ctrl_info->max_lds > 64) {
- sc->max256vdSupport = 1;
- }
if (mrsas_setup_raidmap(sc) != SUCCESS) {
device_printf(sc->mrsas_dev, "Set up RAID map failed.\n");
return (1);
@@ -2079,9 +2111,9 @@ mrsas_init_fw(struct mrsas_softc *sc)
* calculate max_sectors_1. So the number ended up as zero always.
*/
tmp_sectors = 0;
- max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) *
- ctrl_info->max_strips_per_io;
- max_sectors_2 = ctrl_info->max_request_size;
+ max_sectors_1 = (1 << sc->ctrl_info->stripe_sz_ops.min) *
+ sc->ctrl_info->max_strips_per_io;
+ max_sectors_2 = sc->ctrl_info->max_request_size;
tmp_sectors = min(max_sectors_1, max_sectors_2);
sc->max_sectors_per_req = sc->max_num_sge * MRSAS_PAGE_SIZE / 512;
@@ -2089,9 +2121,9 @@ mrsas_init_fw(struct mrsas_softc *sc)
sc->max_sectors_per_req = tmp_sectors;
sc->disableOnlineCtrlReset =
- ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
+ sc->ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
sc->UnevenSpanSupport =
- ctrl_info->adapterOperations2.supportUnevenSpans;
+ sc->ctrl_info->adapterOperations2.supportUnevenSpans;
if (sc->UnevenSpanSupport) {
device_printf(sc->mrsas_dev, "FW supports: UnevenSpanSupport=%x\n\n",
sc->UnevenSpanSupport);
@@ -2101,9 +2133,6 @@ mrsas_init_fw(struct mrsas_softc *sc)
else
sc->fast_path_io = 0;
}
- if (ctrl_info)
- free(ctrl_info, M_MRSAS);
-
return (0);
}
@@ -2135,7 +2164,7 @@ mrsas_init_adapter(struct mrsas_softc *sc)
max_cmd = sc->max_fw_cmds;
/* Determine allocation size of command frames */
- sc->reply_q_depth = ((max_cmd + 1 + 15) / 16 * 16);
+ sc->reply_q_depth = ((max_cmd + 1 + 15) / 16 * 16) * 2;
sc->request_alloc_sz = sizeof(MRSAS_REQUEST_DESCRIPTOR_UNION) * max_cmd;
sc->reply_alloc_sz = sizeof(MPI2_REPLY_DESCRIPTORS_UNION) * (sc->reply_q_depth);
sc->io_frames_alloc_sz = MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE + (MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE * (max_cmd + 1));
@@ -2280,7 +2309,9 @@ mrsas_ioc_init(struct mrsas_softc *sc)
init_frame->driver_ver_lo = (bus_addr_t)sc->verbuf_phys_addr;
init_frame->driver_ver_hi = 0;
}
+ init_frame->driver_operations.mfi_capabilities.support_ndrive_r1_lb = 1;
init_frame->driver_operations.mfi_capabilities.support_max_255lds = 1;
+ init_frame->driver_operations.mfi_capabilities.security_protocol_cmds_fw = 1;
phys_addr = (bus_addr_t)sc->ioc_init_phys_mem + 1024;
init_frame->queue_info_new_phys_addr_lo = phys_addr;
init_frame->data_xfer_len = sizeof(Mpi2IOCInitRequest_t);
@@ -2422,7 +2453,7 @@ mrsas_alloc_mpt_cmds(struct mrsas_softc *sc)
* This functions fires the command to Firmware by writing to the
* inbound_low_queue_port and inbound_high_queue_port.
*/
-void
+void
mrsas_fire_cmd(struct mrsas_softc *sc, u_int32_t req_desc_lo,
u_int32_t req_desc_hi)
{
@@ -2702,7 +2733,6 @@ mrsas_reset_ctrl(struct mrsas_softc *sc)
/* Reset not supported, kill adapter */
mrsas_dprint(sc, MRSAS_OCR, "Reset not supported, killing adapter.\n");
mrsas_kill_hba(sc);
- sc->adprecovery = MRSAS_HW_CRITICAL_ERROR;
retval = FAIL;
goto out;
}
@@ -2787,10 +2817,6 @@ mrsas_reset_ctrl(struct mrsas_softc *sc)
mrsas_dprint(sc, MRSAS_OCR, "mrsas_ioc_init() failed!\n");
continue;
}
- mrsas_clear_bit(MRSAS_FUSION_IN_RESET, &sc->reset_flags);
- mrsas_enable_intr(sc);
- sc->adprecovery = MRSAS_HBA_OPERATIONAL;
-
/* Re-fire management commands */
for (j = 0; j < sc->max_fw_cmds; j++) {
mpt_cmd = sc->mpt_cmd_list[j];
@@ -2820,9 +2846,18 @@ mrsas_reset_ctrl(struct mrsas_softc *sc)
memset(sc->load_balance_info, 0,
sizeof(LD_LOAD_BALANCE_INFO) * MAX_LOGICAL_DRIVES_EXT);
+ if (mrsas_get_ctrl_info(sc)) {
+ mrsas_kill_hba(sc);
+ retval = FAIL;
+ goto out;
+ }
if (!mrsas_get_map_info(sc))
mrsas_sync_map_info(sc);
+ mrsas_clear_bit(MRSAS_FUSION_IN_RESET, &sc->reset_flags);
+ mrsas_enable_intr(sc);
+ sc->adprecovery = MRSAS_HBA_OPERATIONAL;
+
/* Adapter reset completed successfully */
device_printf(sc->mrsas_dev, "Reset successful\n");
retval = SUCCESS;
@@ -2853,11 +2888,43 @@ out:
void
mrsas_kill_hba(struct mrsas_softc *sc)
{
+ sc->adprecovery = MRSAS_HW_CRITICAL_ERROR;
+ pause("mrsas_kill_hba", 1000);
mrsas_dprint(sc, MRSAS_OCR, "%s\n", __func__);
mrsas_write_reg(sc, offsetof(mrsas_reg_set, doorbell),
MFI_STOP_ADP);
/* Flush */
mrsas_read_reg(sc, offsetof(mrsas_reg_set, doorbell));
+ mrsas_complete_outstanding_ioctls(sc);
+}
+
+/**
+ * mrsas_complete_outstanding_ioctls Complete pending IOCTLS after kill_hba
+ * input: Controller softc
+ *
+ * Returns void
+ */
+void
+mrsas_complete_outstanding_ioctls(struct mrsas_softc *sc)
+{
+ int i;
+ struct mrsas_mpt_cmd *cmd_mpt;
+ struct mrsas_mfi_cmd *cmd_mfi;
+ u_int32_t count, MSIxIndex;
+
+ count = sc->msix_vectors > 0 ? sc->msix_vectors : 1;
+ for (i = 0; i < sc->max_fw_cmds; i++) {
+ cmd_mpt = sc->mpt_cmd_list[i];
+
+ if (cmd_mpt->sync_cmd_idx != (u_int32_t)MRSAS_ULONG_MAX) {
+ cmd_mfi = sc->mfi_cmd_list[cmd_mpt->sync_cmd_idx];
+ if (cmd_mfi->sync_cmd && cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT) {
+ for (MSIxIndex = 0; MSIxIndex < count; MSIxIndex++)
+ mrsas_complete_mptmfi_passthru(sc, cmd_mfi,
+ cmd_mpt->io_request->RaidContext.status);
+ }
+ }
+ }
}
/*
@@ -2944,8 +3011,7 @@ mrsas_release_mfi_cmd(struct mrsas_mfi_cmd *cmd)
* supported by the FW.
*/
static int
-mrsas_get_ctrl_info(struct mrsas_softc *sc,
- struct mrsas_ctrl_info *ctrl_info)
+mrsas_get_ctrl_info(struct mrsas_softc *sc)
{
int retcode = 0;
struct mrsas_mfi_cmd *cmd;
@@ -2978,16 +3044,60 @@ mrsas_get_ctrl_info(struct mrsas_softc *sc,
dcmd->sgl.sge32[0].length = sizeof(struct mrsas_ctrl_info);
if (!mrsas_issue_polled(sc, cmd))
- memcpy(ctrl_info, sc->ctlr_info_mem, sizeof(struct mrsas_ctrl_info));
+ memcpy(sc->ctrl_info, sc->ctlr_info_mem, sizeof(struct mrsas_ctrl_info));
else
retcode = 1;
+ mrsas_update_ext_vd_details(sc);
+
mrsas_free_ctlr_info_cmd(sc);
mrsas_release_mfi_cmd(cmd);
return (retcode);
}
/*
+ * mrsas_update_ext_vd_details : Update details w.r.t Extended VD
+ * input:
+ * sc - Controller's softc
+*/
+static void
+mrsas_update_ext_vd_details(struct mrsas_softc *sc)
+{
+ sc->max256vdSupport =
+ sc->ctrl_info->adapterOperations3.supportMaxExtLDs;
+ /* Below is additional check to address future FW enhancement */
+ if (sc->ctrl_info->max_lds > 64)
+ sc->max256vdSupport = 1;
+
+ sc->drv_supported_vd_count = MRSAS_MAX_LD_CHANNELS
+ * MRSAS_MAX_DEV_PER_CHANNEL;
+ sc->drv_supported_pd_count = MRSAS_MAX_PD_CHANNELS
+ * MRSAS_MAX_DEV_PER_CHANNEL;
+ if (sc->max256vdSupport) {
+ sc->fw_supported_vd_count = MAX_LOGICAL_DRIVES_EXT;
+ sc->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
+ } else {
+ sc->fw_supported_vd_count = MAX_LOGICAL_DRIVES;
+ sc->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
+ }
+
+ sc->old_map_sz = sizeof(MR_FW_RAID_MAP) +
+ (sizeof(MR_LD_SPAN_MAP) *
+ (sc->fw_supported_vd_count - 1));
+ sc->new_map_sz = sizeof(MR_FW_RAID_MAP_EXT);
+ sc->drv_map_sz = sizeof(MR_DRV_RAID_MAP) +
+ (sizeof(MR_LD_SPAN_MAP) *
+ (sc->drv_supported_vd_count - 1));
+
+ sc->max_map_sz = max(sc->old_map_sz, sc->new_map_sz);
+
+ if (sc->max256vdSupport)
+ sc->current_map_sz = sc->new_map_sz;
+ else
+ sc->current_map_sz = sc->old_map_sz;
+}
+
+/*
* mrsas_alloc_ctlr_info_cmd: Allocates memory for controller info command
* input: Adapter soft state
*
@@ -3762,7 +3872,7 @@ mrsas_get_ld_list(struct mrsas_softc *sc)
* memory is initialized to all zeros upon successful loading of the dma
* mapped memory.
*/
-int
+int
mrsas_alloc_tmp_dcmd(struct mrsas_softc *sc,
struct mrsas_tmp_dcmd *tcmd, int size)
{
@@ -3995,10 +4105,12 @@ mrsas_complete_aen(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd)
*/
if ((!cmd->abort_aen) && (sc->remove_in_progress == 0)) {
sc->mrsas_aen_triggered = 1;
+ mtx_lock(&sc->aen_lock);
if (sc->mrsas_poll_waiting) {
sc->mrsas_poll_waiting = 0;
selwakeup(&sc->mrsas_select);
}
+ mtx_unlock(&sc->aen_lock);
} else
cmd->abort_aen = 0;
diff --git a/sys/dev/mrsas/mrsas.h b/sys/dev/mrsas/mrsas.h
index 37b6e95..1cfe89e 100644
--- a/sys/dev/mrsas/mrsas.h
+++ b/sys/dev/mrsas/mrsas.h
@@ -1,6 +1,7 @@
/*
+ * Copyright (c) 2015, AVAGO Tech. All rights reserved. Authors: Marian Choy
* Copyright (c) 2014, LSI Corp. All rights reserved. Authors: Marian Choy
- * Support: freebsdraid@lsi.com
+ * Support: freebsdraid@avagotech.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,7 +32,7 @@
* those of the authors and should not be interpreted as representing
* official policies,either expressed or implied, of the FreeBSD Project.
*
- * Send feedback to: <megaraidfbsd@lsi.com> Mail to: LSI Corporation, 1621
+ * Send feedback to: <megaraidfbsd@avagotech.com> Mail to: AVAGO TECHNOLOGIES, 1621
* Barber Lane, Milpitas, CA 95035 ATTN: MegaRaid FreeBSD
*
*/
@@ -101,7 +102,7 @@ __FBSDID("$FreeBSD$");
*/
#define BYTE_ALIGNMENT 1
#define MRSAS_MAX_NAME_LENGTH 32
-#define MRSAS_VERSION "06.705.10.02-fbsd"
+#define MRSAS_VERSION "06.707.04.03-fbsd"
#define MRSAS_ULONG_MAX 0xFFFFFFFFFFFFFFFF
#define MRSAS_DEFAULT_TIMEOUT 0x14 /* Temporarily set */
#define DONE 0
@@ -813,9 +814,8 @@ typedef struct _MR_DRV_RAID_MAP_ALL {
typedef struct _LD_LOAD_BALANCE_INFO {
u_int8_t loadBalanceFlag;
u_int8_t reserved1;
- u_int16_t raid1DevHandle[2];
- mrsas_atomic_t scsi_pending_cmds[2];
- u_int64_t last_accessed_block[2];
+ mrsas_atomic_t scsi_pending_cmds[MAX_PHYSICAL_DEVICES];
+ u_int64_t last_accessed_block[MAX_PHYSICAL_DEVICES];
} LD_LOAD_BALANCE_INFO, *PLD_LOAD_BALANCE_INFO;
/* SPAN_SET is info caclulated from span info from Raid map per ld */
@@ -858,6 +858,9 @@ struct IO_REQUEST_INFO {
u_int8_t start_span;
u_int8_t reserved;
u_int64_t start_row;
+ /* span[7:5], arm[4:0] */
+ u_int8_t span_arm;
+ u_int8_t pd_after_lb;
};
typedef struct _MR_LD_TARGET_SYNC {
@@ -1315,6 +1318,13 @@ typedef enum _REGION_TYPE {
#define MRSAS_REQ_STATE_TRAN 2
#define MRSAS_REQ_STATE_COMPLETE 3
+typedef enum _MR_SCSI_CMD_TYPE {
+ READ_WRITE_LDIO = 0,
+ NON_READ_WRITE_LDIO = 1,
+ READ_WRITE_SYSPDIO = 2,
+ NON_READ_WRITE_SYSPDIO = 3,
+} MR_SCSI_CMD_TYPE;
+
enum mrsas_req_flags {
MRSAS_DIR_UNKNOWN = 0x1,
MRSAS_DIR_IN = 0x2,
@@ -1350,6 +1360,7 @@ struct mrsas_mpt_cmd {
u_int32_t sync_cmd_idx;
u_int32_t index;
u_int8_t flags;
+ u_int8_t pd_r1_lb;
u_int8_t load_balance;
bus_size_t length;
u_int32_t error_code;
@@ -1897,9 +1908,26 @@ struct mrsas_ctrl_info {
char reserved6[4]; /* 0x7E4 RESERVED FOR IOV */
struct { /* 0x7E8 */
- u_int32_t resrved:5;
+ u_int32_t supportPersonalityChange:2;
+ u_int32_t supportThermalPollInterval:1;
+ u_int32_t supportDisableImmediateIO:1;
+ u_int32_t supportT10RebuildAssist:1;
u_int32_t supportMaxExtLDs:1;
- u_int32_t reserved1:26;
+ u_int32_t supportCrashDump:1;
+ u_int32_t supportSwZone:1;
+ u_int32_t supportDebugQueue:1;
+ u_int32_t supportNVCacheErase:1;
+ u_int32_t supportForceTo512e:1;
+ u_int32_t supportHOQRebuild:1;
+ u_int32_t supportAllowedOpsforDrvRemoval:1;
+ u_int32_t supportDrvActivityLEDSetting:1;
+ u_int32_t supportNVDRAM:1;
+ u_int32_t supportForceFlash:1;
+ u_int32_t supportDisableSESMonitoring:1;
+ u_int32_t supportCacheBypassModes:1;
+ u_int32_t supportSecurityonJBOD:1;
+ u_int32_t discardCacheDuringLDDelete:1;
+ u_int32_t reserved:12;
} adapterOperations3;
u_int8_t pad[0x800 - 0x7EC]; /* 0x7EC */
@@ -1970,7 +1998,10 @@ typedef union _MFI_CAPABILITIES {
u_int32_t support_additional_msix:1;
u_int32_t support_fastpath_wb:1;
u_int32_t support_max_255lds:1;
- u_int32_t reserved:28;
+ u_int32_t support_ndrive_r1_lb:1;
+ u_int32_t support_core_affinity:1;
+ u_int32_t security_protocol_cmds_fw:1;
+ u_int32_t reserved:25;
} mfi_capabilities;
u_int32_t reg;
} MFI_CAPABILITIES;
@@ -2413,6 +2444,167 @@ struct mrsas_mgmt_info {
int max_index;
};
+#define PCI_TYPE0_ADDRESSES 6
+#define PCI_TYPE1_ADDRESSES 2
+#define PCI_TYPE2_ADDRESSES 5
+
+typedef struct _MRSAS_DRV_PCI_COMMON_HEADER {
+ u_int16_t vendorID;
+ //(ro)
+ u_int16_t deviceID;
+ //(ro)
+ u_int16_t command;
+ //Device control
+ u_int16_t status;
+ u_int8_t revisionID;
+ //(ro)
+ u_int8_t progIf;
+ //(ro)
+ u_int8_t subClass;
+ //(ro)
+ u_int8_t baseClass;
+ //(ro)
+ u_int8_t cacheLineSize;
+ //(ro +)
+ u_int8_t latencyTimer;
+ //(ro +)
+ u_int8_t headerType;
+ //(ro)
+ u_int8_t bist;
+ //Built in self test
+
+ union {
+ struct _MRSAS_DRV_PCI_HEADER_TYPE_0 {
+ u_int32_t baseAddresses[PCI_TYPE0_ADDRESSES];
+ u_int32_t cis;
+ u_int16_t subVendorID;
+ u_int16_t subSystemID;
+ u_int32_t romBaseAddress;
+ u_int8_t capabilitiesPtr;
+ u_int8_t reserved1[3];
+ u_int32_t reserved2;
+ u_int8_t interruptLine;
+ u_int8_t interruptPin;
+ //(ro)
+ u_int8_t minimumGrant;
+ //(ro)
+ u_int8_t maximumLatency;
+ //(ro)
+ } type0;
+
+ /*
+ * PCI to PCI Bridge
+ */
+
+ struct _MRSAS_DRV_PCI_HEADER_TYPE_1 {
+ u_int32_t baseAddresses[PCI_TYPE1_ADDRESSES];
+ u_int8_t primaryBus;
+ u_int8_t secondaryBus;
+ u_int8_t subordinateBus;
+ u_int8_t secondaryLatency;
+ u_int8_t ioBase;
+ u_int8_t ioLimit;
+ u_int16_t secondaryStatus;
+ u_int16_t memoryBase;
+ u_int16_t memoryLimit;
+ u_int16_t prefetchBase;
+ u_int16_t prefetchLimit;
+ u_int32_t prefetchBaseUpper32;
+ u_int32_t prefetchLimitUpper32;
+ u_int16_t ioBaseUpper16;
+ u_int16_t ioLimitUpper16;
+ u_int8_t capabilitiesPtr;
+ u_int8_t reserved1[3];
+ u_int32_t romBaseAddress;
+ u_int8_t interruptLine;
+ u_int8_t interruptPin;
+ u_int16_t bridgeControl;
+ } type1;
+
+ /*
+ * PCI to CARDBUS Bridge
+ */
+
+ struct _MRSAS_DRV_PCI_HEADER_TYPE_2 {
+ u_int32_t socketRegistersBaseAddress;
+ u_int8_t capabilitiesPtr;
+ u_int8_t reserved;
+ u_int16_t secondaryStatus;
+ u_int8_t primaryBus;
+ u_int8_t secondaryBus;
+ u_int8_t subordinateBus;
+ u_int8_t secondaryLatency;
+ struct {
+ u_int32_t base;
+ u_int32_t limit;
+ } range [PCI_TYPE2_ADDRESSES - 1];
+ u_int8_t interruptLine;
+ u_int8_t interruptPin;
+ u_int16_t bridgeControl;
+ } type2;
+ } u;
+
+} MRSAS_DRV_PCI_COMMON_HEADER, *PMRSAS_DRV_PCI_COMMON_HEADER;
+
+#define MRSAS_DRV_PCI_COMMON_HEADER_SIZE sizeof(MRSAS_DRV_PCI_COMMON_HEADER) //64 bytes
+
+typedef struct _MRSAS_DRV_PCI_LINK_CAPABILITY {
+ union {
+ struct {
+ u_int32_t linkSpeed:4;
+ u_int32_t linkWidth:6;
+ u_int32_t aspmSupport:2;
+ u_int32_t losExitLatency:3;
+ u_int32_t l1ExitLatency:3;
+ u_int32_t rsvdp:6;
+ u_int32_t portNumber:8;
+ } bits;
+
+ u_int32_t asUlong;
+ } u;
+} MRSAS_DRV_PCI_LINK_CAPABILITY, *PMRSAS_DRV_PCI_LINK_CAPABILITY;
+
+#define MRSAS_DRV_PCI_LINK_CAPABILITY_SIZE sizeof(MRSAS_DRV_PCI_LINK_CAPABILITY)
+
+typedef struct _MRSAS_DRV_PCI_LINK_STATUS_CAPABILITY {
+ union {
+ struct {
+ u_int16_t linkSpeed:4;
+ u_int16_t negotiatedLinkWidth:6;
+ u_int16_t linkTrainingError:1;
+ u_int16_t linkTraning:1;
+ u_int16_t slotClockConfig:1;
+ u_int16_t rsvdZ:3;
+ } bits;
+
+ u_int16_t asUshort;
+ } u;
+ u_int16_t reserved;
+} MRSAS_DRV_PCI_LINK_STATUS_CAPABILITY, *PMRSAS_DRV_PCI_LINK_STATUS_CAPABILITY;
+
+#define MRSAS_DRV_PCI_LINK_STATUS_CAPABILITY_SIZE sizeof(MRSAS_DRV_PCI_LINK_STATUS_CAPABILITY)
+
+
+typedef struct _MRSAS_DRV_PCI_CAPABILITIES {
+ MRSAS_DRV_PCI_LINK_CAPABILITY linkCapability;
+ MRSAS_DRV_PCI_LINK_STATUS_CAPABILITY linkStatusCapability;
+} MRSAS_DRV_PCI_CAPABILITIES, *PMRSAS_DRV_PCI_CAPABILITIES;
+
+#define MRSAS_DRV_PCI_CAPABILITIES_SIZE sizeof(MRSAS_DRV_PCI_CAPABILITIES)
+
+/* PCI information */
+typedef struct _MRSAS_DRV_PCI_INFORMATION {
+ u_int32_t busNumber;
+ u_int8_t deviceNumber;
+ u_int8_t functionNumber;
+ u_int8_t interruptVector;
+ u_int8_t reserved1;
+ MRSAS_DRV_PCI_COMMON_HEADER pciHeaderInfo;
+ MRSAS_DRV_PCI_CAPABILITIES capability;
+ u_int32_t domainID;
+ u_int8_t reserved2[28];
+} MRSAS_DRV_PCI_INFORMATION, *PMRSAS_DRV_PCI_INFORMATION;
+
/*******************************************************************
* per-instance data
********************************************************************/
@@ -2476,6 +2668,7 @@ struct mrsas_softc {
int msix_vectors;
int msix_enable;
uint32_t msix_reg_offset[16];
+ uint8_t mask_interrupts;
struct mrsas_mpt_cmd **mpt_cmd_list;
struct mrsas_mfi_cmd **mfi_cmd_list;
TAILQ_HEAD(, mrsas_mpt_cmd) mrsas_mpt_cmd_list_head;
@@ -2519,6 +2712,7 @@ struct mrsas_softc {
bus_dmamap_t evt_detail_dmamap;
struct mrsas_evt_detail *evt_detail_mem;
bus_addr_t evt_detail_phys_addr;
+ struct mrsas_ctrl_info *ctrl_info;
bus_dma_tag_t ctlr_info_tag;
bus_dmamap_t ctlr_info_dmamap;
void *ctlr_info_mem;
@@ -2546,9 +2740,11 @@ struct mrsas_softc {
struct task ev_task;
u_int32_t CurLdCount;
u_int64_t reset_flags;
+ int lb_pending_cmds;
LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES_EXT];
LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES_EXT];
+ u_int8_t secure_jbod_support;
u_int8_t max256vdSupport;
u_int16_t fw_supported_vd_count;
u_int16_t fw_supported_pd_count;
diff --git a/sys/dev/mrsas/mrsas_cam.c b/sys/dev/mrsas/mrsas_cam.c
index 80ddc39..08f9002 100644
--- a/sys/dev/mrsas/mrsas_cam.c
+++ b/sys/dev/mrsas/mrsas_cam.c
@@ -1,6 +1,7 @@
/*
+ * Copyright (c) 2015, AVAGO Tech. All rights reserved. Author: Marian Choy
* Copyright (c) 2014, LSI Corp. All rights reserved. Author: Marian Choy
- * Support: freebsdraid@lsi.com
+ * Support: freebsdraid@avagotech.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -57,17 +58,19 @@ __FBSDID("$FreeBSD$");
* Function prototypes
*/
int mrsas_cam_attach(struct mrsas_softc *sc);
-int mrsas_ldio_inq(struct cam_sim *sim, union ccb *ccb);
+int mrsas_find_io_type(struct cam_sim *sim, union ccb *ccb);
int mrsas_bus_scan(struct mrsas_softc *sc);
int mrsas_bus_scan_sim(struct mrsas_softc *sc, struct cam_sim *sim);
-int mrsas_map_request(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd);
int
+mrsas_map_request(struct mrsas_softc *sc,
+ struct mrsas_mpt_cmd *cmd, union ccb *ccb);
+int
mrsas_build_ldio(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
union ccb *ccb);
-int
+int
mrsas_build_dcdb(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
union ccb *ccb, struct cam_sim *sim);
-int
+int
mrsas_setup_io(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
union ccb *ccb, u_int32_t device_id,
MRSAS_RAID_SCSI_IO_REQUEST * io_request);
@@ -77,10 +80,10 @@ void mrsas_cam_detach(struct mrsas_softc *sc);
void mrsas_release_mpt_cmd(struct mrsas_mpt_cmd *cmd);
void mrsas_unmap_request(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd);
void mrsas_cmd_done(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd);
-void
+void
mrsas_fire_cmd(struct mrsas_softc *sc, u_int32_t req_desc_lo,
u_int32_t req_desc_hi);
-void
+void
mrsas_set_pd_lba(MRSAS_RAID_SCSI_IO_REQUEST * io_request,
u_int8_t cdb_len, struct IO_REQUEST_INFO *io_info, union ccb *ccb,
MR_DRV_RAID_MAP_ALL * local_map_ptr, u_int32_t ref_tag,
@@ -89,10 +92,10 @@ static void mrsas_freeze_simq(struct mrsas_mpt_cmd *cmd, struct cam_sim *sim);
static void mrsas_cam_poll(struct cam_sim *sim);
static void mrsas_action(struct cam_sim *sim, union ccb *ccb);
static void mrsas_scsiio_timeout(void *data);
-static void
+static void
mrsas_data_load_cb(void *arg, bus_dma_segment_t *segs,
int nseg, int error);
-static int32_t
+static int32_t
mrsas_startio(struct mrsas_softc *sc, struct cam_sim *sim,
union ccb *ccb);
struct mrsas_mpt_cmd *mrsas_get_mpt_cmd(struct mrsas_softc *sc);
@@ -112,9 +115,9 @@ MR_BuildRaidContext(struct mrsas_softc *sc,
extern u_int16_t
MR_LdSpanArrayGet(u_int32_t ld, u_int32_t span,
MR_DRV_RAID_MAP_ALL * map);
-extern u_int16_t
-mrsas_get_updated_dev_handle(PLD_LOAD_BALANCE_INFO lbInfo,
- struct IO_REQUEST_INFO *io_info);
+extern u_int16_t
+mrsas_get_updated_dev_handle(struct mrsas_softc *sc,
+ PLD_LOAD_BALANCE_INFO lbInfo, struct IO_REQUEST_INFO *io_info);
extern u_int8_t
megasas_get_best_arm(PLD_LOAD_BALANCE_INFO lbInfo, u_int8_t arm,
u_int64_t block, u_int32_t count);
@@ -315,7 +318,11 @@ mrsas_action(struct cam_sim *sim, union ccb *ccb)
ccb->cpi.version_num = 1;
ccb->cpi.hba_inquiry = 0;
ccb->cpi.target_sprt = 0;
+#if (__FreeBSD_version >= 902001)
+ ccb->cpi.hba_misc = PIM_UNMAPPED;
+#else
ccb->cpi.hba_misc = 0;
+#endif
ccb->cpi.hba_eng_cnt = 0;
ccb->cpi.max_lun = MRSAS_SCSI_MAX_LUNS;
ccb->cpi.unit_number = cam_sim_unit(sim);
@@ -323,7 +330,7 @@ mrsas_action(struct cam_sim *sim, union ccb *ccb)
ccb->cpi.initiator_id = MRSAS_SCSI_INITIATOR_ID;
ccb->cpi.base_transfer_speed = 150000;
strncpy(ccb->cpi.sim_vid, "FreeBSD", SIM_IDLEN);
- strncpy(ccb->cpi.hba_vid, "LSI", HBA_IDLEN);
+ strncpy(ccb->cpi.hba_vid, "AVAGO", HBA_IDLEN);
strncpy(ccb->cpi.dev_name, cam_sim_name(sim), DEV_IDLEN);
ccb->cpi.transport = XPORT_SPI;
ccb->cpi.transport_version = 2;
@@ -378,8 +385,13 @@ mrsas_scsiio_timeout(void *data)
* on OCR enable/disable property of Controller from ocr_thread
* context.
*/
+#if (__FreeBSD_version >= 1000510)
callout_reset_sbt(&cmd->cm_callout, SBT_1S * 600, 0,
- mrsas_scsiio_timeout, cmd, 0);
+ mrsas_scsiio_timeout, cmd, 0);
+#else
+ callout_reset(&cmd->cm_callout, (600000 * hz) / 1000,
+ mrsas_scsiio_timeout, cmd);
+#endif
sc->do_timedout_reset = 1;
if (sc->ocr_thread_active)
wakeup(&sc->ocr_chan);
@@ -425,8 +437,8 @@ mrsas_startio(struct mrsas_softc *sc, struct cam_sim *sim,
} else
cmd->flags = MRSAS_DIR_NONE; /* no data */
- /* For FreeBSD 10.0 and higher */
-#if (__FreeBSD_version >= 1000000)
+/* For FreeBSD 9.2 and higher */
+#if (__FreeBSD_version >= 902001)
/*
* XXX We don't yet support physical addresses here.
*/
@@ -455,6 +467,11 @@ mrsas_startio(struct mrsas_softc *sc, struct cam_sim *sim,
if (cmd->length)
cmd->data = csio->data_ptr;
break;
+ case CAM_DATA_BIO:
+ cmd->length = csio->dxfer_len;
+ if (cmd->length)
+ cmd->data = csio->data_ptr;
+ break;
default:
ccb->ccb_h.status = CAM_REQ_INVALID;
goto done;
@@ -499,7 +516,9 @@ mrsas_startio(struct mrsas_softc *sc, struct cam_sim *sim,
bcopy(csio->cdb_io.cdb_bytes, cmd->io_request->CDB.CDB32, csio->cdb_len);
mtx_lock(&sc->raidmap_lock);
- if (mrsas_ldio_inq(sim, ccb)) {
+ /* Check for IO type READ-WRITE targeted for Logical Volume */
+ if (mrsas_find_io_type(sim, ccb) == READ_WRITE_LDIO) {
+ /* Build READ-WRITE IO for Logical Volume */
if (mrsas_build_ldio(sc, cmd, ccb)) {
device_printf(sc->mrsas_dev, "Build LDIO failed.\n");
mtx_unlock(&sc->raidmap_lock);
@@ -530,8 +549,13 @@ mrsas_startio(struct mrsas_softc *sc, struct cam_sim *sim,
/*
* Start timer for IO timeout. Default timeout value is 90 second.
*/
- callout_reset_sbt(&cmd->cm_callout, SBT_1MS * sc->mrsas_io_timeout, 0,
+#if (__FreeBSD_version >= 1000510)
+ callout_reset_sbt(&cmd->cm_callout, SBT_1S * 600, 0,
mrsas_scsiio_timeout, cmd, 0);
+#else
+ callout_reset(&cmd->cm_callout, (600000 * hz) / 1000,
+ mrsas_scsiio_timeout, cmd);
+#endif
mrsas_atomic_inc(&sc->fw_outstanding);
if (mrsas_atomic_read(&sc->fw_outstanding) > sc->io_cmds_highwater)
@@ -546,20 +570,17 @@ done:
}
/*
- * mrsas_ldio_inq: Determines if IO is read/write or inquiry
+ * mrsas_find_io_type: Determines if IO is read/write or inquiry
* input: pointer to CAM Control Block
*
* This function determines if the IO is read/write or inquiry. It returns a 1
* if the IO is read/write and 0 if it is inquiry.
*/
-int
-mrsas_ldio_inq(struct cam_sim *sim, union ccb *ccb)
+int
+mrsas_find_io_type(struct cam_sim *sim, union ccb *ccb)
{
struct ccb_scsiio *csio = &(ccb->csio);
- if (cam_sim_bus(sim) == 1)
- return (0);
-
switch (csio->cdb_io.cdb_bytes[0]) {
case READ_10:
case WRITE_10:
@@ -569,9 +590,11 @@ mrsas_ldio_inq(struct cam_sim *sim, union ccb *ccb)
case WRITE_6:
case READ_16:
case WRITE_16:
- return 1;
+ return (cam_sim_bus(sim) ?
+ READ_WRITE_SYSPDIO : READ_WRITE_LDIO);
default:
- return 0;
+ return (cam_sim_bus(sim) ?
+ NON_READ_WRITE_SYSPDIO : NON_READ_WRITE_LDIO);
}
}
@@ -677,7 +700,7 @@ mrsas_build_ldio(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
io_request->DataLength = cmd->length;
- if (mrsas_map_request(sc, cmd) == SUCCESS) {
+ if (mrsas_map_request(sc, cmd, ccb) == SUCCESS) {
if (cmd->sge_count > MRSAS_MAX_SGL) {
device_printf(sc->mrsas_dev, "Error: sge_count (0x%x) exceeds"
"max (0x%x) allowed\n", cmd->sge_count, sc->max_num_sge);
@@ -824,9 +847,10 @@ mrsas_setup_io(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
if ((sc->load_balance_info[device_id].loadBalanceFlag) &&
(io_info.isRead)) {
io_info.devHandle =
- mrsas_get_updated_dev_handle(&sc->load_balance_info[device_id],
- &io_info);
+ mrsas_get_updated_dev_handle(sc,
+ &sc->load_balance_info[device_id], &io_info);
cmd->load_balance = MRSAS_LOAD_BALANCE_FLAG;
+ cmd->pd_r1_lb = io_info.pd_after_lb;
} else
cmd->load_balance = 0;
cmd->request_desc->SCSIIO.DevHandle = io_info.devHandle;
@@ -876,30 +900,49 @@ mrsas_build_dcdb(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
device_id = ccb_h->target_id;
map_ptr = sc->ld_drv_map[(sc->map_id & 1)];
- /* Check if this is for system PD */
+ /*
+ * 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->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 =
+ 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 =
@@ -911,7 +954,7 @@ mrsas_build_dcdb(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
io_request->LUN[1] = ccb_h->target_lun & 0xF;
io_request->DataLength = cmd->length;
- if (mrsas_map_request(sc, cmd) == SUCCESS) {
+ 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);
@@ -934,20 +977,25 @@ mrsas_build_dcdb(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
* is built in the callback. If the bus dmamap load is not successful,
* cmd->error_code will contain the error code and a 1 is returned.
*/
-int
-mrsas_map_request(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd)
+int
+mrsas_map_request(struct mrsas_softc *sc,
+ struct mrsas_mpt_cmd *cmd, union ccb *ccb)
{
u_int32_t retcode = 0;
struct cam_sim *sim;
- int flag = BUS_DMA_NOWAIT;
sim = xpt_path_sim(cmd->ccb_ptr->ccb_h.path);
if (cmd->data != NULL) {
- mtx_lock(&sc->io_lock);
/* Map data buffer into bus space */
+ mtx_lock(&sc->io_lock);
+#if (__FreeBSD_version >= 902001)
+ retcode = bus_dmamap_load_ccb(sc->data_tag, cmd->data_dmamap, ccb,
+ mrsas_data_load_cb, cmd, 0);
+#else
retcode = bus_dmamap_load(sc->data_tag, cmd->data_dmamap, cmd->data,
- cmd->length, mrsas_data_load_cb, cmd, flag);
+ cmd->length, mrsas_data_load_cb, cmd, BUS_DMA_NOWAIT);
+#endif
mtx_unlock(&sc->io_lock);
if (retcode)
device_printf(sc->mrsas_dev, "bus_dmamap_load(): retcode = %d\n", retcode);
diff --git a/sys/dev/mrsas/mrsas_fp.c b/sys/dev/mrsas/mrsas_fp.c
index cd0d57f..7ae5662 100644
--- a/sys/dev/mrsas/mrsas_fp.c
+++ b/sys/dev/mrsas/mrsas_fp.c
@@ -1,6 +1,7 @@
/*
+ * Copyright (c) 2015, AVAGO Tech. All rights reserved. Author: Marian Choy
* Copyright (c) 2014, LSI Corp. All rights reserved. Author: Marian Choy
- * Support: freebsdraid@lsi.com
+ * Support: freebsdraid@avagotech.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,7 +32,7 @@
* those of the authors and should not be interpreted as representing
* official policies,either expressed or implied, of the FreeBSD Project.
*
- * Send feedback to: <megaraidfbsd@lsi.com> Mail to: LSI Corporation, 1621
+ * Send feedback to: <megaraidfbsd@avagotech.com> Mail to: AVAGO TECHNOLOGIES, 1621
* Barber Lane, Milpitas, CA 95035 ATTN: MegaRaid FreeBSD
*
*/
@@ -55,13 +56,13 @@ __FBSDID("$FreeBSD$");
*/
u_int8_t MR_ValidateMapInfo(struct mrsas_softc *sc);
u_int8_t
-mrsas_get_best_arm(PLD_LOAD_BALANCE_INFO lbInfo, u_int8_t arm,
- u_int64_t block, u_int32_t count);
-u_int8_t
+mrsas_get_best_arm_pd(struct mrsas_softc *sc,
+ PLD_LOAD_BALANCE_INFO lbInfo, struct IO_REQUEST_INFO *io_info);
+u_int8_t
MR_BuildRaidContext(struct mrsas_softc *sc,
struct IO_REQUEST_INFO *io_info,
RAID_CONTEXT * pRAID_Context, MR_DRV_RAID_MAP_ALL * map);
-u_int8_t
+u_int8_t
MR_GetPhyParams(struct mrsas_softc *sc, u_int32_t ld,
u_int64_t stripRow, u_int16_t stripRef, struct IO_REQUEST_INFO *io_info,
RAID_CONTEXT * pRAID_Context,
@@ -70,32 +71,32 @@ u_int16_t MR_TargetIdToLdGet(u_int32_t ldTgtId, MR_DRV_RAID_MAP_ALL * map);
u_int32_t MR_LdBlockSizeGet(u_int32_t ldTgtId, MR_DRV_RAID_MAP_ALL * map);
u_int16_t MR_GetLDTgtId(u_int32_t ld, MR_DRV_RAID_MAP_ALL * map);
u_int16_t
-mrsas_get_updated_dev_handle(PLD_LOAD_BALANCE_INFO lbInfo,
- struct IO_REQUEST_INFO *io_info);
+mrsas_get_updated_dev_handle(struct mrsas_softc *sc,
+ PLD_LOAD_BALANCE_INFO lbInfo, struct IO_REQUEST_INFO *io_info);
u_int32_t mega_mod64(u_int64_t dividend, u_int32_t divisor);
-u_int32_t
+u_int32_t
MR_GetSpanBlock(u_int32_t ld, u_int64_t row, u_int64_t *span_blk,
MR_DRV_RAID_MAP_ALL * map, int *div_error);
u_int64_t mega_div64_32(u_int64_t dividend, u_int32_t divisor);
void
-mrsas_update_load_balance_params(MR_DRV_RAID_MAP_ALL * map,
- PLD_LOAD_BALANCE_INFO lbInfo);
-void
+mrsas_update_load_balance_params(struct mrsas_softc *sc,
+ MR_DRV_RAID_MAP_ALL * map, PLD_LOAD_BALANCE_INFO lbInfo);
+void
mrsas_set_pd_lba(MRSAS_RAID_SCSI_IO_REQUEST * io_request,
u_int8_t cdb_len, struct IO_REQUEST_INFO *io_info, union ccb *ccb,
MR_DRV_RAID_MAP_ALL * local_map_ptr, u_int32_t ref_tag,
u_int32_t ld_block_size);
-static u_int16_t
+static u_int16_t
MR_LdSpanArrayGet(u_int32_t ld, u_int32_t span,
MR_DRV_RAID_MAP_ALL * map);
static u_int16_t MR_PdDevHandleGet(u_int32_t pd, MR_DRV_RAID_MAP_ALL * map);
-static u_int16_t
+static u_int16_t
MR_ArPdGet(u_int32_t ar, u_int32_t arm,
MR_DRV_RAID_MAP_ALL * map);
static MR_LD_SPAN *
MR_LdSpanPtrGet(u_int32_t ld, u_int32_t span,
MR_DRV_RAID_MAP_ALL * map);
-static u_int8_t
+static u_int8_t
MR_LdDataArmGet(u_int32_t ld, u_int32_t armIdx,
MR_DRV_RAID_MAP_ALL * map);
static MR_SPAN_BLOCK_INFO *
@@ -146,6 +147,8 @@ typedef u_int32_t REGION_LEN;
#define FALSE 0
#define TRUE 1
+#define LB_PENDING_CMDS_DEFAULT 4
+
/*
* Related Macros
@@ -376,10 +379,9 @@ MR_ValidateMapInfo(struct mrsas_softc *sc)
return 1;
}
if (sc->UnevenSpanSupport) {
- printf("Updating span set\n\n");
mr_update_span_set(drv_map, ldSpanInfo);
}
- mrsas_update_load_balance_params(drv_map, sc->load_balance_info);
+ mrsas_update_load_balance_params(sc, drv_map, sc->load_balance_info);
return 0;
}
@@ -566,12 +568,12 @@ get_row_from_strip(struct mrsas_softc *sc,
else
break;
}
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug : Strip 0x%llx, span_set_Strip 0x%llx, span_set_Row 0x%llx "
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug : Strip 0x%llx, span_set_Strip 0x%llx, span_set_Row 0x%llx "
"data width 0x%llx span offset 0x%llx\n", (unsigned long long)strip,
(unsigned long long)span_set_Strip,
(unsigned long long)span_set_Row,
(unsigned long long)span_set->span_row_data_width, (unsigned long long)span_offset);
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug : For strip 0x%llx row is 0x%llx\n", (unsigned long long)strip,
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug : For strip 0x%llx row is 0x%llx\n", (unsigned long long)strip,
(unsigned long long)span_set->data_row_start +
(unsigned long long)span_set_Row + (span_offset - 1));
return (span_set->data_row_start + span_set_Row + (span_offset - 1));
@@ -631,7 +633,7 @@ get_strip_from_row(struct mrsas_softc *sc,
}
}
}
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug - get_strip_from_row: returns invalid "
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug - get_strip_from_row: returns invalid "
"strip for ld=%x, row=%lx\n", ld, (long unsigned int)row);
return -1;
}
@@ -679,13 +681,13 @@ get_arm_from_strip(struct mrsas_softc *sc,
else
break;
}
- mrsas_dprint(sc, MRSAS_PRL11, "LSI PRL11: get_arm_from_strip: "
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO PRL11: get_arm_from_strip: "
"for ld=0x%x strip=0x%lx arm is 0x%x\n", ld,
(long unsigned int)strip, (strip_offset - span_offset));
return (strip_offset - span_offset);
}
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: - get_arm_from_strip: returns invalid arm"
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug: - get_arm_from_strip: returns invalid arm"
" for ld=%x strip=%lx\n", ld, (long unsigned int)strip);
return -1;
@@ -723,9 +725,11 @@ get_arm(struct mrsas_softc *sc, u_int32_t ld, u_int8_t span, u_int64_t stripe,
* This routine calculates the arm, span and block for the specified stripe and
* reference in stripe using spanset
*
- * Inputs : Logical drive number
- * stripRow: Stripe number
- * stripRef: Reference in stripe
+ * Inputs :
+ * sc - HBA instance
+ * ld - Logical drive number
+ * stripRow: Stripe number
+ * stripRef: Reference in stripe
*
* Outputs : span - Span number block - Absolute Block
* number in the physical disk
@@ -785,6 +789,7 @@ mr_spanset_get_phy_params(struct mrsas_softc *sc, u_int32_t ld, u_int64_t stripR
*pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk;
pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
+ io_info->span_arm = pRAID_Context->spanArm;
return retval;
}
@@ -831,7 +836,7 @@ MR_BuildRaidContext(struct mrsas_softc *sc, struct IO_REQUEST_INFO *io_info,
else if (sc->UnevenSpanSupport) {
io_info->IoforUnevenSpan = 1;
} else {
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: raid->rowDataSize is 0, but has SPAN[0] rowDataSize = 0x%0x,"
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug: raid->rowDataSize is 0, but has SPAN[0] rowDataSize = 0x%0x,"
" but there is _NO_ UnevenSpanSupport\n",
MR_LdSpanPtrGet(ld, 0, map)->spanRowDataSize);
return FALSE;
@@ -858,13 +863,13 @@ MR_BuildRaidContext(struct mrsas_softc *sc, struct IO_REQUEST_INFO *io_info,
startlba_span = (u_int8_t)mr_spanset_get_span_block(sc, ld, start_row,
pdBlock, map, &error_code);
if (error_code == 1) {
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: return from %s %d. Send IO w/o region lock.\n",
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug: return from %s %d. Send IO w/o region lock.\n",
__func__, __LINE__);
return FALSE;
}
}
if (startlba_span == SPAN_INVALID) {
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: return from %s %d for row 0x%llx,"
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug: return from %s %d for row 0x%llx,"
"start strip %llx endSrip %llx\n", __func__,
__LINE__, (unsigned long long)start_row,
(unsigned long long)start_strip,
@@ -873,12 +878,12 @@ MR_BuildRaidContext(struct mrsas_softc *sc, struct IO_REQUEST_INFO *io_info,
}
io_info->start_span = startlba_span;
io_info->start_row = start_row;
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: Check Span number from %s %d for row 0x%llx, "
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug: Check Span number from %s %d for row 0x%llx, "
" start strip 0x%llx endSrip 0x%llx span 0x%x\n",
__func__, __LINE__, (unsigned long long)start_row,
(unsigned long long)start_strip,
(unsigned long long)endStrip, startlba_span);
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug : 1. start_row 0x%llx endRow 0x%llx Start span 0x%x\n",
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug : 1. start_row 0x%llx endRow 0x%llx Start span 0x%x\n",
(unsigned long long)start_row, (unsigned long long)endRow, startlba_span);
} else {
start_row = mega_div64_32(start_strip, raid->rowDataSize);
@@ -1042,7 +1047,7 @@ mr_update_span_set(MR_DRV_RAID_MAP_ALL * map, PLD_SPAN_INFO ldSpanInfo)
span_row_width +=
MR_LdSpanPtrGet(ld, count, map)->spanRowDataSize;
#if SPAN_DEBUG
- printf("LSI Debug span %x rowDataSize %x\n", count,
+ printf("AVAGO Debug span %x rowDataSize %x\n", count,
MR_LdSpanPtrGet(ld, count, map)->spanRowDataSize);
#endif
}
@@ -1097,46 +1102,38 @@ mr_update_span_set(MR_DRV_RAID_MAP_ALL * map, PLD_SPAN_INFO ldSpanInfo)
/*
* mrsas_update_load_balance_params: Update load balance parmas
- * Inputs: map pointer
- * Load balance info
+ * Inputs:
+ * sc - driver softc instance
+ * drv_map - driver RAID map
+ * lbInfo - Load balance info
*
* This function updates the load balance parameters for the LD config of a two
* drive optimal RAID-1.
*/
-void
-mrsas_update_load_balance_params(MR_DRV_RAID_MAP_ALL * map,
- PLD_LOAD_BALANCE_INFO lbInfo)
+void
+mrsas_update_load_balance_params(struct mrsas_softc *sc,
+ MR_DRV_RAID_MAP_ALL * drv_map, PLD_LOAD_BALANCE_INFO lbInfo)
{
int ldCount;
u_int16_t ld;
- u_int32_t pd, arRef;
MR_LD_RAID *raid;
- for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) {
- ld = MR_TargetIdToLdGet(ldCount, map);
- if (ld >= MAX_LOGICAL_DRIVES) {
+ if (sc->lb_pending_cmds > 128 || sc->lb_pending_cmds < 1)
+ sc->lb_pending_cmds = LB_PENDING_CMDS_DEFAULT;
+
+ for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES_EXT; ldCount++) {
+ ld = MR_TargetIdToLdGet(ldCount, drv_map);
+ if (ld >= MAX_LOGICAL_DRIVES_EXT) {
lbInfo[ldCount].loadBalanceFlag = 0;
continue;
}
- raid = MR_LdRaidGet(ld, map);
-
- /* Two drive Optimal RAID 1 */
- if ((raid->level == 1) && (raid->rowSize == 2) &&
- (raid->spanDepth == 1)
- && raid->ldState == MR_LD_STATE_OPTIMAL) {
- lbInfo[ldCount].loadBalanceFlag = 1;
-
- /* Get the array on which this span is present */
- arRef = MR_LdSpanArrayGet(ld, 0, map);
-
- /* Get the PD */
- pd = MR_ArPdGet(arRef, 0, map);
- /* Get dev handle from PD */
- lbInfo[ldCount].raid1DevHandle[0] = MR_PdDevHandleGet(pd, map);
- pd = MR_ArPdGet(arRef, 1, map);
- lbInfo[ldCount].raid1DevHandle[1] = MR_PdDevHandleGet(pd, map);
- } else
+ raid = MR_LdRaidGet(ld, drv_map);
+ if ((raid->level != 1) ||
+ (raid->ldState != MR_LD_STATE_OPTIMAL)) {
lbInfo[ldCount].loadBalanceFlag = 0;
+ continue;
+ }
+ lbInfo[ldCount].loadBalanceFlag = 1;
}
}
@@ -1152,7 +1149,7 @@ mrsas_update_load_balance_params(MR_DRV_RAID_MAP_ALL * map,
*
* Used to set the PD logical block address in CDB for FP IOs.
*/
-void
+void
mrsas_set_pd_lba(MRSAS_RAID_SCSI_IO_REQUEST * io_request, u_int8_t cdb_len,
struct IO_REQUEST_INFO *io_info, union ccb *ccb,
MR_DRV_RAID_MAP_ALL * local_map_ptr, u_int32_t ref_tag,
@@ -1299,6 +1296,7 @@ mrsas_set_pd_lba(MRSAS_RAID_SCSI_IO_REQUEST * io_request, u_int8_t cdb_len,
}
/* Fall through normal case, just load LBA here */
u_int8_t val = cdb[1] & 0xE0;
+
switch (cdb_len) {
case 6:
cdb[3] = (u_int8_t)(start_blk & 0xff);
@@ -1332,57 +1330,94 @@ mrsas_set_pd_lba(MRSAS_RAID_SCSI_IO_REQUEST * io_request, u_int8_t cdb_len,
}
/*
- * mrsas_get_best_arm: Determine the best spindle arm
- * Inputs: Load balance info
+ * mrsas_get_best_arm_pd: Determine the best spindle arm
+ * Inputs:
+ * sc - HBA instance
+ * lbInfo - Load balance info
+ * io_info - IO request info
*
* This function determines and returns the best arm by looking at the
* parameters of the last PD access.
*/
-u_int8_t
-mrsas_get_best_arm(PLD_LOAD_BALANCE_INFO lbInfo, u_int8_t arm,
- u_int64_t block, u_int32_t count)
+u_int8_t
+mrsas_get_best_arm_pd(struct mrsas_softc *sc,
+ PLD_LOAD_BALANCE_INFO lbInfo, struct IO_REQUEST_INFO *io_info)
{
- u_int16_t pend0, pend1;
+ MR_LD_RAID *raid;
+ MR_DRV_RAID_MAP_ALL *drv_map;
+ u_int16_t pend0, pend1, ld;
u_int64_t diff0, diff1;
- u_int8_t bestArm;
+ u_int8_t bestArm, pd0, pd1, span, arm;
+ u_int32_t arRef, span_row_size;
+
+ u_int64_t block = io_info->ldStartBlock;
+ u_int32_t count = io_info->numBlocks;
+
+ span = ((io_info->span_arm & RAID_CTX_SPANARM_SPAN_MASK)
+ >> RAID_CTX_SPANARM_SPAN_SHIFT);
+ arm = (io_info->span_arm & RAID_CTX_SPANARM_ARM_MASK);
+
+ drv_map = sc->ld_drv_map[(sc->map_id & 1)];
+ ld = MR_TargetIdToLdGet(io_info->ldTgtId, drv_map);
+ raid = MR_LdRaidGet(ld, drv_map);
+ span_row_size = sc->UnevenSpanSupport ?
+ SPAN_ROW_SIZE(drv_map, ld, span) : raid->rowSize;
+
+ arRef = MR_LdSpanArrayGet(ld, span, drv_map);
+ pd0 = MR_ArPdGet(arRef, arm, drv_map);
+ pd1 = MR_ArPdGet(arRef, (arm + 1) >= span_row_size ?
+ (arm + 1 - span_row_size) : arm + 1, drv_map);
/* get the pending cmds for the data and mirror arms */
- pend0 = mrsas_atomic_read(&lbInfo->scsi_pending_cmds[0]);
- pend1 = mrsas_atomic_read(&lbInfo->scsi_pending_cmds[1]);
+ pend0 = mrsas_atomic_read(&lbInfo->scsi_pending_cmds[pd0]);
+ pend1 = mrsas_atomic_read(&lbInfo->scsi_pending_cmds[pd1]);
/* Determine the disk whose head is nearer to the req. block */
- diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[0]);
- diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[1]);
- bestArm = (diff0 <= diff1 ? 0 : 1);
+ diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[pd0]);
+ diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[pd1]);
+ bestArm = (diff0 <= diff1 ? arm : arm ^ 1);
- if ((bestArm == arm && pend0 > pend1 + 16) || (bestArm != arm && pend1 > pend0 + 16))
+ if ((bestArm == arm && pend0 > pend1 + sc->lb_pending_cmds) ||
+ (bestArm != arm && pend1 > pend0 + sc->lb_pending_cmds))
bestArm ^= 1;
/* Update the last accessed block on the correct pd */
- lbInfo->last_accessed_block[bestArm] = block + count - 1;
+ lbInfo->last_accessed_block[bestArm == arm ? pd0 : pd1] = block + count - 1;
+ io_info->span_arm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | bestArm;
+ io_info->pd_after_lb = (bestArm == arm) ? pd0 : pd1;
+#if SPAN_DEBUG
+ if (arm != bestArm)
+ printf("AVAGO Debug R1 Load balance occur - span 0x%x arm 0x%x bestArm 0x%x "
+ "io_info->span_arm 0x%x\n",
+ span, arm, bestArm, io_info->span_arm);
+#endif
- return bestArm;
+ return io_info->pd_after_lb;
}
/*
* mrsas_get_updated_dev_handle: Get the update dev handle
- * Inputs: Load balance info io_info pointer
+ * Inputs:
+ * sc - Adapter instance soft state
+ * lbInfo - Load balance info
+ * io_info - io_info pointer
*
* This function determines and returns the updated dev handle.
*/
-u_int16_t
-mrsas_get_updated_dev_handle(PLD_LOAD_BALANCE_INFO lbInfo,
- struct IO_REQUEST_INFO *io_info)
+u_int16_t
+mrsas_get_updated_dev_handle(struct mrsas_softc *sc,
+ PLD_LOAD_BALANCE_INFO lbInfo, struct IO_REQUEST_INFO *io_info)
{
- u_int8_t arm, old_arm;
+ u_int8_t arm_pd;
u_int16_t devHandle;
+ MR_DRV_RAID_MAP_ALL *drv_map;
- old_arm = lbInfo->raid1DevHandle[0] == io_info->devHandle ? 0 : 1;
+ drv_map = sc->ld_drv_map[(sc->map_id & 1)];
/* get best new arm */
- arm = mrsas_get_best_arm(lbInfo, old_arm, io_info->ldStartBlock, io_info->numBlocks);
- devHandle = lbInfo->raid1DevHandle[arm];
- mrsas_atomic_inc(&lbInfo->scsi_pending_cmds[arm]);
+ arm_pd = mrsas_get_best_arm_pd(sc, lbInfo, io_info);
+ devHandle = MR_PdDevHandleGet(arm_pd, drv_map);
+ mrsas_atomic_inc(&lbInfo->scsi_pending_cmds[arm_pd]);
return devHandle;
}
@@ -1471,6 +1506,7 @@ MR_GetPhyParams(struct mrsas_softc *sc, u_int32_t ld,
*pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk;
pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
+ io_info->span_arm = pRAID_Context->spanArm;
return retval;
}
diff --git a/sys/dev/mrsas/mrsas_ioctl.c b/sys/dev/mrsas/mrsas_ioctl.c
index 8e2aead..3c4dbf9 100644
--- a/sys/dev/mrsas/mrsas_ioctl.c
+++ b/sys/dev/mrsas/mrsas_ioctl.c
@@ -1,6 +1,7 @@
/*
+ * Copyright (c) 2015, AVAGO Tech. All rights reserved. Author: Marian Choy
* Copyright (c) 2014, LSI Corp. All rights reserved. Author: Marian Choy
- * Support: freebsdraid@lsi.com
+ * Support: freebsdraid@avagotech.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,7 +32,7 @@
* those of the authors and should not be interpreted as representing
* official policies,either expressed or implied, of the FreeBSD Project.
*
- * Send feedback to: <megaraidfbsd@lsi.com> Mail to: LSI Corporation, 1621
+ * Send feedback to: <megaraidfbsd@avagotech.com> Mail to: AVAGO TECHNOLOGIES, 1621
* Barber Lane, Milpitas, CA 95035 ATTN: MegaRaid FreeBSD
*
*/
@@ -238,7 +239,7 @@ mrsas_passthru(struct mrsas_softc *sc, void *arg, u_long ioctlCmd)
}
sense_ptr =
(unsigned long *)((unsigned long)cmd->frame + user_ioc->sense_off);
- sense_ptr = ioctl_sense_mem;
+ *sense_ptr = ioctl_sense_phys_addr;
}
/*
* Set the sync_cmd flag so that the ISR knows not to complete this
@@ -296,13 +297,14 @@ out:
/*
* Release sense buffer
*/
- if (ioctl_sense_phys_addr)
- bus_dmamap_unload(ioctl_sense_tag, ioctl_sense_dmamap);
- if (ioctl_sense_mem != NULL)
- bus_dmamem_free(ioctl_sense_tag, ioctl_sense_mem, ioctl_sense_dmamap);
- if (ioctl_sense_tag != NULL)
- bus_dma_tag_destroy(ioctl_sense_tag);
-
+ if (user_ioc->sense_len) {
+ if (ioctl_sense_phys_addr)
+ bus_dmamap_unload(ioctl_sense_tag, ioctl_sense_dmamap);
+ if (ioctl_sense_mem != NULL)
+ bus_dmamem_free(ioctl_sense_tag, ioctl_sense_mem, ioctl_sense_dmamap);
+ if (ioctl_sense_tag != NULL)
+ bus_dma_tag_destroy(ioctl_sense_tag);
+ }
/*
* Release data buffers
*/
diff --git a/sys/dev/mrsas/mrsas_ioctl.h b/sys/dev/mrsas/mrsas_ioctl.h
index bf05a7d..c43fc6d 100644
--- a/sys/dev/mrsas/mrsas_ioctl.h
+++ b/sys/dev/mrsas/mrsas_ioctl.h
@@ -1,6 +1,7 @@
/*
+ * Copyright (c) 2015, AVAGO Tech. All rights reserved. Author: Marian Choy
* Copyright (c) 2014, LSI Corp. All rights reserved. Author: Marian Choy
- * Support: freebsdraid@lsi.com
+ * Support: freebsdraid@avagotech.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,7 +32,7 @@
* those of the authors and should not be interpreted as representing
* official policies,either expressed or implied, of the FreeBSD Project.
*
- * Send feedback to: <megaraidfbsd@lsi.com> Mail to: LSI Corporation, 1621
+ * Send feedback to: <megaraidfbsd@avagotech.com> Mail to: AVAGO TECHNOLOGIES, 1621
* Barber Lane, Milpitas, CA 95035 ATTN: MegaRaid FreeBSD
*
*/
@@ -64,6 +65,7 @@ __FBSDID("$FreeBSD$");
* into a somewhat unique, 32-bit value.
*/
+#define MRSAS_IOC_GET_PCI_INFO _IOR('M', 7, MRSAS_DRV_PCI_INFORMATION)
#define MRSAS_IOC_FIRMWARE_PASS_THROUGH64 _IOWR('M', 1, struct mrsas_iocpacket)
#ifdef COMPAT_FREEBSD32
#define MRSAS_IOC_FIRMWARE_PASS_THROUGH32 _IOWR('M', 1, struct mrsas_iocpacket32)
diff --git a/sys/dev/mrsas/mrsas_linux.c b/sys/dev/mrsas/mrsas_linux.c
index 8a3db0b..15f38c5 100644
--- a/sys/dev/mrsas/mrsas_linux.c
+++ b/sys/dev/mrsas/mrsas_linux.c
@@ -1,6 +1,7 @@
/*
+ * Copyright (c) 2015, AVAGO Tech. All rights reserved. Author: Kashyap Desai,
* Copyright (c) 2014, LSI Corp. All rights reserved. Author: Kashyap Desai,
- * Sibananda Sahu Support: freebsdraid@lsi.com
+ * Sibananda Sahu Support: freebsdraid@avagotech.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,7 +32,7 @@
* those of the authors and should not be interpreted as representing
* official policies,either expressed or implied, of the FreeBSD Project.
*
- * Send feedback to: <megaraidfbsd@lsi.com> Mail to: LSI Corporation, 1621
+ * Send feedback to: <megaraidfbsd@avagotech.com> Mail to: AVAGO TECHNOLOGIES, 1621
* Barber Lane, Milpitas, CA 95035 ATTN: MegaRaid FreeBSD
*
*/
OpenPOWER on IntegriCloud