summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkadesai <kadesai@FreeBSD.org>2015-06-11 14:11:41 +0000
committerkadesai <kadesai@FreeBSD.org>2015-06-11 14:11:41 +0000
commit3a6c5b791fafa79766a5c99c288a7d1ef495157a (patch)
treeb1a5b3a9866fde368eba735a52ba93960b31ad97
parentc82317e7846170acdccc6de1a8faf53d209cede8 (diff)
downloadFreeBSD-src-3a6c5b791fafa79766a5c99c288a7d1ef495157a.zip
FreeBSD-src-3a6c5b791fafa79766a5c99c288a7d1ef495157a.tar.gz
MFC r282525-282533
r282533 : Corrected indentation on conflicted source files. r282532 : Configured the mrsas(4) driver to support UNMAPPED I/O and updated driver version. r282531 : 1. All LSI namings are converted to AVAGO Tech. 2. Fix in AEN path(suggested by John Baldwin). 3. Fix IOCTL path w.r.t Sense key handling r282530 : Bug fixes found internally as detailed below: 1. While disabling interrupt the FW disables interrupts for only 16 vectors. In case of Invader which supports 96 MSI-x vectors, some spurious interrupts may come on other vectors even after interrupt disable. So, driver uses a flag and ignores the spurious interrupts. 2. Reply queue depth is made double the number of commands supported by FW. 3. Misplaced interrupt enable code is now moved down in the OCR path. 4. Updated error handling code in OCR path. 5. Removed un-necessary print. r282529 : Driver calls mrsas_complete_cmd() to call mrsas_wakeup() for each MFI frame that was issued through the ioctl() interface prior to the kill adapter. This ensures userspace ioctl() system calls issued just before a kill adapter don't get stuck in wait state and IOCTLs are returned to application. r282528 : In OCR(Online Controller Reset) path, driver sets adapter state to MEGASAS_HBA_OPERATIONAL before getting new RAID map. There will be a small window where IO will come from OS with old RAID map. This patch will update adapter state to MEGASAS_HBA_OPERATIONAL, only after driver has new RAID map to avoid any IOs getting build using old RAID map. r282527 : Current driver does fast path read load balancing between arm and mirror disk for two Drive Raid-1 configuration only. Now, Driver support fast path read load balancing for all (any number of disk) Raid-1 configuration. r282526 : Now Driver expose Secure Jbod Support via driver_operations in MFI INIT Frame. FW expose Secure Jbod support via Controller properity. Firmware expect IOs to be received from different IO path than conventional fast path queue, in case of SED drives. To have Secure jbod support user need driver and firmware support. r282525 : This patch adds the feature to provide PCI information via IOCTL query.
-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