summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith M Wesolowski <wesolows@foobazco.org>2013-04-05 23:29:13 +0000
committerKeith M Wesolowski <wesolows@foobazco.org>2013-04-05 23:29:13 +0000
commit19e0355d7a64b2c771a95292ee26a5935cb39c30 (patch)
treeb3657112b8df28623d24ee47a55783acaa696d06
parent47644c2a782d42cef6171070446352a68326cba5 (diff)
parentb1fa6326238973aeaf12c34fcda75985b6c06be1 (diff)
downloadillumos-joyent-19e0355d7a64b2c771a95292ee26a5935cb39c30.tar.gz
[illumos-gate merge]
commit b1fa6326238973aeaf12c34fcda75985b6c06be1 3675 DTrace print() should try to resolve function pointers 3676 dt_print_enum hardcodes a value of zero commit cba073b1ec508c3bc83d649fd197b7d1c483eb55 3677 /dev/ipnet can duplicate packets commit dfc0fed81813380fb526f1a003d3be17ab26ce3b 3683 pfiles shouldn't try to trace itself 3684 pfiles crashes on processes with no files 3685 getsockname should set the sa_family_t for unbound unix domain sockets 3686 pfiles shows incorrect socket information on some getsockname calls commit bd6433eb4d5b16c480f15cd77e2201c318b2556d 3682 /usr/bin/head should implement -c -q and -v commit a1c36c8ba5112b6713dabac615bf8d56a45f0764 3500 Support LSI SAS2008 (Falcon) Skinny FW for mr_sas(7D) Conflicts: usr/src/man/man1/head.1 usr/src/cmd/head/head.c Manifests adapted: usr/src/pkg/manifests/driver-storage-mr_sas.mf [driver_aliases] usr/src/pkg/manifests/system-dtrace-tests.mf [nop]
-rw-r--r--usr/src/cmd/head/head.c5
-rw-r--r--usr/src/cmd/mdb/common/modules/mr_sas/mr_sas.c53
-rw-r--r--usr/src/cmd/ptools/pfiles/pfiles.c6
-rw-r--r--usr/src/man/man1/head.14
-rw-r--r--usr/src/pkg/manifests/driver-storage-mr_sas.mf6
-rw-r--r--usr/src/pkg/manifests/system-dtrace-tests.mf2
-rw-r--r--usr/src/uts/common/io/mr_sas/mr_sas.c194
-rw-r--r--usr/src/uts/common/io/mr_sas/mr_sas.h10
-rw-r--r--usr/src/uts/common/io/mr_sas/mr_sas_tbolt.c121
9 files changed, 202 insertions, 199 deletions
diff --git a/usr/src/cmd/head/head.c b/usr/src/cmd/head/head.c
index b0687d6c22..c08f2a450e 100644
--- a/usr/src/cmd/head/head.c
+++ b/usr/src/cmd/head/head.c
@@ -106,8 +106,9 @@ main(int argc, char **argv)
case 'c':
if ((strcmp(optarg, "--") == 0) || (optind > argc)) {
(void) fprintf(stderr, gettext(
- "%s: Missing -n argument\n"), argv[0]),
- Usage();
+ "%s: Missing -%c argument\n"), argv[0],
+ optopt);
+ Usage();
}
linecnt = (off_t)strtoll(optarg, (char **)NULL, 10);
if (linecnt <= 0) {
diff --git a/usr/src/cmd/mdb/common/modules/mr_sas/mr_sas.c b/usr/src/cmd/mdb/common/modules/mr_sas/mr_sas.c
index a060f17462..15da29874d 100644
--- a/usr/src/cmd/mdb/common/modules/mr_sas/mr_sas.c
+++ b/usr/src/cmd/mdb/common/modules/mr_sas/mr_sas.c
@@ -23,6 +23,10 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ */
+
#include <limits.h>
#include <sys/mdb_modapi.h>
#include <sys/sysinfo.h>
@@ -57,15 +61,16 @@ construct_path(uintptr_t addr, char *result)
}
void
-display_targets(struct mrsas_instance m, int verbose)
+display_targets(struct mrsas_instance *m, int verbose)
{
int tgt;
- struct mrsas_ld *mr_ldp;
+ struct mrsas_ld mr_ldp[MRDRV_MAX_LD];
+ struct mrsas_tbolt_pd mr_pdp[MRSAS_TBOLT_PD_TGT_MAX];
char device_path[PATH_MAX];
if (verbose) {
*device_path = 0;
- if (construct_path((uintptr_t)m.dip, device_path) != DCMD_OK) {
+ if (construct_path((uintptr_t)m->dip, device_path) != DCMD_OK) {
strcpy(device_path, "couldn't determine device path");
}
}
@@ -73,29 +78,41 @@ display_targets(struct mrsas_instance m, int verbose)
mdb_printf("\n");
if (verbose)
mdb_printf("%s\n", device_path);
- mdb_printf("dev_type target\n");
- mdb_printf("----------");
- mdb_printf("\n");
+ mdb_printf("Physical/Logical Target\n");
+ mdb_printf("-----------------------\n");
+
+ if (mdb_vread(&mr_ldp, sizeof (mr_ldp), (uintptr_t)m->mr_ld_list)
+ == -1 ||
+ mdb_vread(&mr_pdp, sizeof (mr_pdp), (uintptr_t)m->mr_tbolt_pd_list)
+ == -1) {
+ mdb_warn("can't read list of disks");
+ return;
+ }
+
for (tgt = 0; tgt < MRDRV_MAX_LD; tgt++) {
- mr_ldp = (struct mrsas_ld *)&m.mr_ld_list[tgt];
- if ((mr_ldp != NULL) && (mr_ldp->dip != NULL) &&
- (mr_ldp->lun_type == MRSAS_LD_LUN)) {
- mdb_printf("sd %d", tgt);
- mdb_printf("\n");
+ if (mr_ldp[tgt].dip != NULL &&
+ mr_ldp[tgt].lun_type == MRSAS_LD_LUN) {
+ mdb_printf("Logical sd %d\n", tgt);
+ }
+ }
+ for (tgt = 0; tgt < MRSAS_TBOLT_PD_TGT_MAX; tgt++) {
+ if (mr_pdp[tgt].dip != NULL &&
+ mr_pdp[tgt].lun_type == MRSAS_TBOLT_PD_LUN) {
+ mdb_printf("Physical sd %d\n", tgt);
}
}
mdb_printf("\n");
}
void
-display_deviceinfo(struct mrsas_instance m)
+display_deviceinfo(struct mrsas_instance *m)
{
uint16_t vid, did, svid, sid;
- vid = m.vendor_id;
- did = m.device_id;
- svid = m.subsysvid;
- sid = m.subsysid;
+ vid = m->vendor_id;
+ did = m->device_id;
+ svid = m->subsysvid;
+ sid = m->subsysid;
mdb_printf("\n");
mdb_printf("vendor_id device_id subsysvid subsysid");
@@ -178,10 +195,10 @@ mr_sas_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
mdb_printf("\n");
if (target_info)
- display_targets(m, verbose);
+ display_targets(&m, verbose);
if (device_info)
- display_deviceinfo(m);
+ display_deviceinfo(&m);
return (rv);
}
diff --git a/usr/src/cmd/ptools/pfiles/pfiles.c b/usr/src/cmd/ptools/pfiles/pfiles.c
index be4bcdcc6f..fbe54fc0dd 100644
--- a/usr/src/cmd/ptools/pfiles/pfiles.c
+++ b/usr/src/cmd/ptools/pfiles/pfiles.c
@@ -338,11 +338,7 @@ getflock(struct ps_prochandle *Pr, int fd, struct flock *flock_native)
#ifdef _LP64
struct flock64_32 flock_target;
- /*
- * Pr may be NULL when pfiles is inspecting itself, but in that case
- * we already know the data model of the two processes must match.
- */
- if ((Pr != NULL) && (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32)) {
+ if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) {
copyflock(flock_target, *flock_native);
ret = pr_fcntl(Pr, fd, F_GETLK, &flock_target);
copyflock(*flock_native, flock_target);
diff --git a/usr/src/man/man1/head.1 b/usr/src/man/man1/head.1
index aac241d12a..ff818f891f 100644
--- a/usr/src/man/man1/head.1
+++ b/usr/src/man/man1/head.1
@@ -151,7 +151,7 @@ the \fB-n\fR \fInumber\fR option.
\fB\FB-q\fR\fR
.ad
.RS 13n
-\fBhead\fR will not print a header inbetween each specified file.
+\fBhead\fR will not print a header in between each specified file.
.RE
.sp
@@ -160,7 +160,7 @@ the \fB-n\fR \fInumber\fR option.
\fB\FB-v\fR\fR
.ad
.RS 13n
-\fBhead\fR will always print a header inbetween each specified file.
+\fBhead\fR will always print a header in between each specified file.
.RE
.sp
diff --git a/usr/src/pkg/manifests/driver-storage-mr_sas.mf b/usr/src/pkg/manifests/driver-storage-mr_sas.mf
index 0ab39410f1..ba185d0176 100644
--- a/usr/src/pkg/manifests/driver-storage-mr_sas.mf
+++ b/usr/src/pkg/manifests/driver-storage-mr_sas.mf
@@ -21,7 +21,7 @@
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
-# Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
#
#
@@ -46,11 +46,15 @@ $(sparc_ONLY)driver name=mr_sas class=scsi-self-identifying \
alias=pci1000,79 \
alias=pciex1000,5b \
alias=pciex1000,5d \
+ alias=pciex1000,71 \
+ alias=pciex1000,73 \
alias=pciex1000,78 \
alias=pciex1000,79
$(i386_ONLY)driver name=mr_sas class=scsi-self-identifying \
alias=pciex1000,5b \
alias=pciex1000,5d \
+ alias=pciex1000,71 \
+ alias=pciex1000,73 \
alias=pciex1000,78 \
alias=pciex1000,79
file path=kernel/drv/$(ARCH64)/mr_sas group=sys
diff --git a/usr/src/pkg/manifests/system-dtrace-tests.mf b/usr/src/pkg/manifests/system-dtrace-tests.mf
index 709b1f6a92..d1e0317ee6 100644
--- a/usr/src/pkg/manifests/system-dtrace-tests.mf
+++ b/usr/src/pkg/manifests/system-dtrace-tests.mf
@@ -1261,6 +1261,8 @@ file path=opt/SUNWdtrt/tst/common/print/tst.array.d.out mode=0444
file path=opt/SUNWdtrt/tst/common/print/tst.bitfield.d mode=0444
file path=opt/SUNWdtrt/tst/common/print/tst.bitfield.d.out mode=0444
file path=opt/SUNWdtrt/tst/common/print/tst.dyn.d mode=0444
+file path=opt/SUNWdtrt/tst/common/print/tst.enum.d mode=0444
+file path=opt/SUNWdtrt/tst/common/print/tst.enum.d.out mode=0444
file path=opt/SUNWdtrt/tst/common/print/tst.primitive.d mode=0444
file path=opt/SUNWdtrt/tst/common/print/tst.primitive.d.out mode=0444
file path=opt/SUNWdtrt/tst/common/print/tst.struct.d mode=0444
diff --git a/usr/src/uts/common/io/mr_sas/mr_sas.c b/usr/src/uts/common/io/mr_sas/mr_sas.c
index f33a85f4c3..e929672325 100644
--- a/usr/src/uts/common/io/mr_sas/mr_sas.c
+++ b/usr/src/uts/common/io/mr_sas/mr_sas.c
@@ -44,7 +44,7 @@
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 Bayard G. Bell. All rights reserved.
- * Copyright 2012 Nexenta System, Inc. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
@@ -80,6 +80,15 @@
#include <sys/fm/util.h>
#include <sys/fm/io/ddi.h>
+/* Macros to help Skinny and stock 2108/MFI live together. */
+#define WR_IB_PICK_QPORT(addr, instance) \
+ if ((instance)->skinny) { \
+ WR_IB_LOW_QPORT((addr), (instance)); \
+ WR_IB_HIGH_QPORT(0, (instance)); \
+ } else { \
+ WR_IB_QPORT((addr), (instance)); \
+ }
+
/*
* Local static data
*/
@@ -135,9 +144,6 @@ static int mrsas_tran_unquiesce(dev_info_t *dip);
static uint_t mrsas_isr();
static uint_t mrsas_softintr();
static void mrsas_undo_resources(dev_info_t *, struct mrsas_instance *);
-static struct mrsas_cmd *get_mfi_pkt(struct mrsas_instance *);
-static void return_mfi_pkt(struct mrsas_instance *,
- struct mrsas_cmd *);
static void free_space_for_mfi(struct mrsas_instance *);
static uint32_t read_fw_status_reg_ppc(struct mrsas_instance *);
@@ -575,6 +581,18 @@ mrsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
instance->tbolt = 1;
break;
+ case PCI_DEVICE_ID_LSI_SKINNY:
+ case PCI_DEVICE_ID_LSI_SKINNY_NEW:
+ /*
+ * FALLTHRU to PPC-style functions, but mark this
+ * instance as Skinny, because the register set is
+ * slightly different (See WR_IB_PICK_QPORT), and
+ * certain other features are available to a Skinny
+ * HBA.
+ */
+ instance->skinny = 1;
+ /* FALLTHRU */
+
case PCI_DEVICE_ID_LSI_2108VDE:
case PCI_DEVICE_ID_LSI_2108V:
con_log(CL_ANN, (CE_NOTE,
@@ -815,15 +833,11 @@ mrsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
tran->tran_tgt_init = mrsas_tran_tgt_init;
tran->tran_tgt_probe = scsi_hba_probe;
tran->tran_tgt_free = mrsas_tran_tgt_free;
- if (instance->tbolt) {
- tran->tran_init_pkt =
- mrsas_tbolt_tran_init_pkt;
- tran->tran_start =
- mrsas_tbolt_tran_start;
- } else {
- tran->tran_init_pkt = mrsas_tran_init_pkt;
- tran->tran_start = mrsas_tran_start;
- }
+ tran->tran_init_pkt = mrsas_tran_init_pkt;
+ if (instance->tbolt)
+ tran->tran_start = mrsas_tbolt_tran_start;
+ else
+ tran->tran_start = mrsas_tran_start;
tran->tran_abort = mrsas_tran_abort;
tran->tran_reset = mrsas_tran_reset;
tran->tran_getcap = mrsas_tran_getcap;
@@ -940,7 +954,7 @@ mrsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
instance->unroll.ldlist_buff = 1;
#ifdef PDSUPPORT
- if (instance->tbolt) {
+ if (instance->tbolt || instance->skinny) {
instance->mr_tbolt_pd_max = MRSAS_TBOLT_PD_TGT_MAX;
instance->mr_tbolt_pd_list =
kmem_zalloc(MRSAS_TBOLT_GET_PD_MAX(instance) *
@@ -1663,7 +1677,7 @@ mrsas_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
}
#ifdef PDSUPPORT
- else if (instance->tbolt) {
+ else if (instance->tbolt || instance->skinny) {
if (instance->mr_tbolt_pd_list[tgt].dip == NULL) {
mutex_enter(&instance->config_dev_mtx);
instance->mr_tbolt_pd_list[tgt].dip = tgt_dip;
@@ -1701,7 +1715,7 @@ mrsas_tran_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
}
#ifdef PDSUPPORT
- else if (instance->tbolt) {
+ else if (instance->tbolt || instance->skinny) {
mutex_enter(&instance->config_dev_mtx);
instance->mr_tbolt_pd_list[tgt].dip = NULL;
mutex_exit(&instance->config_dev_mtx);
@@ -1938,7 +1952,7 @@ mrsas_tran_start(struct scsi_address *ap, register struct scsi_pkt *pkt)
DTRACE_PROBE2(start_tran_err,
uint16_t, instance->fw_outstanding,
uint16_t, instance->max_fw_cmds);
- return_mfi_pkt(instance, cmd);
+ mrsas_return_mfi_pkt(instance, cmd);
return (TRAN_BUSY);
}
@@ -1987,7 +2001,7 @@ mrsas_tran_start(struct scsi_address *ap, register struct scsi_pkt *pkt)
(void) mrsas_common_check(instance, cmd);
DTRACE_PROBE2(start_nointr_done, uint8_t, hdr->cmd,
uint8_t, hdr->cmd_status);
- return_mfi_pkt(instance, cmd);
+ mrsas_return_mfi_pkt(instance, cmd);
if (pkt->pkt_comp) {
(*pkt->pkt_comp)(pkt);
@@ -2461,8 +2475,8 @@ mrsas_isr(struct mrsas_instance *instance)
* After clearing the frame buffer the context id of the
* frame buffer SHOULD be restored back.
*/
-static struct mrsas_cmd *
-get_mfi_pkt(struct mrsas_instance *instance)
+struct mrsas_cmd *
+mrsas_get_mfi_pkt(struct mrsas_instance *instance)
{
mlist_t *head = &instance->cmd_pool_list;
struct mrsas_cmd *cmd = NULL;
@@ -2509,8 +2523,8 @@ get_mfi_app_pkt(struct mrsas_instance *instance)
/*
* return_mfi_pkt : Return a cmd to free command pool
*/
-static void
-return_mfi_pkt(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
+void
+mrsas_return_mfi_pkt(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
{
mutex_enter(&instance->cmd_pool_mtx);
/* use mlist_add_tail for debug assistance */
@@ -3162,7 +3176,13 @@ mrsas_alloc_cmd_pool(struct mrsas_instance *instance)
INIT_LIST_HEAD(&instance->cmd_pend_list);
INIT_LIST_HEAD(&instance->app_cmd_pool_list);
- reserve_cmd = MRSAS_APP_RESERVED_CMDS;
+ /*
+ * When max_cmd is lower than MRSAS_APP_RESERVED_CMDS, how do I split
+ * into app_cmd and regular cmd? For now, just take
+ * max(1/8th of max, 4);
+ */
+ reserve_cmd = min(MRSAS_APP_RESERVED_CMDS,
+ max(max_cmd >> 3, MRSAS_APP_MIN_RESERVED_CMDS));
for (i = 0; i < reserve_cmd; i++) {
cmd = instance->cmd_list[i];
@@ -3276,7 +3296,7 @@ get_ctrl_info(struct mrsas_instance *instance,
if (instance->tbolt) {
cmd = get_raid_msg_mfi_pkt(instance);
} else {
- cmd = get_mfi_pkt(instance);
+ cmd = mrsas_get_mfi_pkt(instance);
}
if (!cmd) {
@@ -3299,7 +3319,7 @@ get_ctrl_info(struct mrsas_instance *instance,
if (!ci) {
cmn_err(CE_WARN,
"Failed to alloc mem for ctrl info");
- return_mfi_pkt(instance, cmd);
+ mrsas_return_mfi_pkt(instance, cmd);
return (DDI_FAILURE);
}
@@ -3358,7 +3378,7 @@ get_ctrl_info(struct mrsas_instance *instance,
if (instance->tbolt) {
return_raid_msg_mfi_pkt(instance, cmd);
} else {
- return_mfi_pkt(instance, cmd);
+ mrsas_return_mfi_pkt(instance, cmd);
}
return (ret);
@@ -3381,7 +3401,7 @@ abort_aen_cmd(struct mrsas_instance *instance,
if (instance->tbolt) {
cmd = get_raid_msg_mfi_pkt(instance);
} else {
- cmd = get_mfi_pkt(instance);
+ cmd = mrsas_get_mfi_pkt(instance);
}
if (!cmd) {
@@ -3434,7 +3454,7 @@ abort_aen_cmd(struct mrsas_instance *instance,
if (instance->tbolt) {
return_raid_msg_mfi_pkt(instance, cmd);
} else {
- return_mfi_pkt(instance, cmd);
+ mrsas_return_mfi_pkt(instance, cmd);
}
atomic_add_16(&instance->fw_outstanding, (-1));
@@ -3569,7 +3589,12 @@ mrsas_init_adapter_ppc(struct mrsas_instance *instance)
}
/* Build INIT command */
- cmd = get_mfi_pkt(instance);
+ cmd = mrsas_get_mfi_pkt(instance);
+ if (cmd == NULL) {
+ DTRACE_PROBE2(init_adapter_mfi_err, uint16_t,
+ instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
+ return (DDI_FAILURE);
+ }
if (mrsas_build_init_cmd(instance, &cmd) != DDI_SUCCESS) {
con_log(CL_ANN,
@@ -3589,7 +3614,7 @@ mrsas_init_adapter_ppc(struct mrsas_instance *instance)
if (mrsas_common_check(instance, cmd) != DDI_SUCCESS)
goto fail_fw_init;
- return_mfi_pkt(instance, cmd);
+ mrsas_return_mfi_pkt(instance, cmd);
if (ctio_enable &&
(instance->func_ptr->read_fw_status_reg(instance) & 0x04000000)) {
@@ -3599,6 +3624,8 @@ mrsas_init_adapter_ppc(struct mrsas_instance *instance)
instance->flag_ieee = 0;
}
+ ASSERT(!instance->skinny || instance->flag_ieee);
+
instance->unroll.alloc_space_mfi = 1;
instance->unroll.verBuff = 1;
@@ -3609,7 +3636,7 @@ fail_fw_init:
(void) mrsas_free_dma_obj(instance, instance->drv_ver_dma_obj);
fail_undo_alloc_mfi_space:
- return_mfi_pkt(instance, cmd);
+ mrsas_return_mfi_pkt(instance, cmd);
free_space_for_mfi(instance);
return (DDI_FAILURE);
@@ -3761,7 +3788,7 @@ mrsas_issue_init_mfi(struct mrsas_instance *instance)
}
if (mrsas_common_check(instance, cmd) != DDI_SUCCESS) {
- return_mfi_pkt(instance, cmd);
+ return_mfi_app_pkt(instance, cmd);
return (DDI_FAILURE);
}
@@ -3814,7 +3841,7 @@ mfi_state_transition_to_ready(struct mrsas_instance *instance)
* to be set
*/
/* WR_IB_MSG_0(MFI_INIT_CLEAR_HANDSHAKE, instance); */
- if (!instance->tbolt) {
+ if (!instance->tbolt && !instance->skinny) {
WR_IB_DOORBELL(MFI_INIT_CLEAR_HANDSHAKE |
MFI_INIT_HOTPLUG, instance);
} else {
@@ -3833,7 +3860,7 @@ mfi_state_transition_to_ready(struct mrsas_instance *instance)
* (MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG)
* to be set
*/
- if (!instance->tbolt) {
+ if (!instance->tbolt && !instance->skinny) {
WR_IB_DOORBELL(MFI_INIT_HOTPLUG, instance);
} else {
WR_RESERVED0_REGISTER(MFI_INIT_HOTPLUG,
@@ -3853,7 +3880,7 @@ mfi_state_transition_to_ready(struct mrsas_instance *instance)
* to be set
*/
/* WR_IB_DOORBELL(MFI_INIT_READY, instance); */
- if (!instance->tbolt) {
+ if (!instance->tbolt && !instance->skinny) {
WR_IB_DOORBELL(MFI_RESET_FLAGS, instance);
} else {
WR_RESERVED0_REGISTER(MFI_RESET_FLAGS,
@@ -3937,7 +3964,8 @@ mfi_state_transition_to_ready(struct mrsas_instance *instance)
}
};
- if (!instance->tbolt) {
+ /* This may also need to apply to Skinny, but for now, don't worry. */
+ if (!instance->tbolt && !instance->skinny) {
fw_ctrl = RD_IB_DOORBELL(instance);
con_log(CL_ANN1, (CE_CONT,
"mfi_state_transition_to_ready:FW ctrl = 0x%x", fw_ctrl));
@@ -3976,7 +4004,7 @@ get_seq_num(struct mrsas_instance *instance,
if (instance->tbolt) {
cmd = get_raid_msg_mfi_pkt(instance);
} else {
- cmd = get_mfi_pkt(instance);
+ cmd = mrsas_get_mfi_pkt(instance);
}
if (!cmd) {
@@ -4052,7 +4080,7 @@ get_seq_num(struct mrsas_instance *instance,
if (instance->tbolt) {
return_raid_msg_mfi_pkt(instance, cmd);
} else {
- return_mfi_pkt(instance, cmd);
+ mrsas_return_mfi_pkt(instance, cmd);
}
return (ret);
@@ -4105,7 +4133,7 @@ flush_cache(struct mrsas_instance *instance)
if (instance->tbolt) {
cmd = get_raid_msg_mfi_pkt(instance);
} else {
- cmd = get_mfi_pkt(instance);
+ cmd = mrsas_get_mfi_pkt(instance);
}
if (!cmd) {
@@ -4151,7 +4179,7 @@ flush_cache(struct mrsas_instance *instance)
if (instance->tbolt) {
return_raid_msg_mfi_pkt(instance, cmd);
} else {
- return_mfi_pkt(instance, cmd);
+ mrsas_return_mfi_pkt(instance, cmd);
}
}
@@ -4251,7 +4279,7 @@ service_mfi_aen(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
#ifdef PDSUPPORT
case MR_EVT_PD_REMOVED_EXT: {
- if (instance->tbolt) {
+ if (instance->tbolt || instance->skinny) {
pd_addr = &evt_detail->args.pd_addr;
dtype = pd_addr->scsi_dev_type;
con_log(CL_DLEVEL1, (CE_NOTE,
@@ -4275,7 +4303,7 @@ service_mfi_aen(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
} /* End of MR_EVT_PD_REMOVED_EXT */
case MR_EVT_PD_INSERTED_EXT: {
- if (instance->tbolt) {
+ if (instance->tbolt || instance->skinny) {
rval = mrsas_service_evt(instance,
ddi_get16(acc_handle,
&evt_detail->args.pd.device_id),
@@ -4289,7 +4317,7 @@ service_mfi_aen(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
} /* End of MR_EVT_PD_INSERTED_EXT */
case MR_EVT_PD_STATE_CHANGE: {
- if (instance->tbolt) {
+ if (instance->tbolt || instance->skinny) {
tgt = ddi_get16(acc_handle,
&evt_detail->args.pd.device_id);
if ((evt_detail->args.pd_state.prevState ==
@@ -4525,6 +4553,12 @@ mrsas_softintr(struct mrsas_instance *instance)
inq = (struct scsi_inquiry *)
acmd->cmd_buf->b_un.b_addr;
+#ifdef PDSUPPORT
+ if (hdr->cmd_status == MFI_STAT_OK) {
+ display_scsi_inquiry(
+ (caddr_t)inq);
+ }
+#else
/* don't expose physical drives to OS */
if (acmd->islogical &&
(hdr->cmd_status == MFI_STAT_OK)) {
@@ -4541,6 +4575,7 @@ mrsas_softintr(struct mrsas_instance *instance)
hdr->cmd_status =
MFI_STAT_DEVICE_NOT_FOUND;
}
+#endif /* PDSUPPORT */
}
}
@@ -4649,19 +4684,14 @@ mrsas_softintr(struct mrsas_instance *instance)
}
}
+ mrsas_return_mfi_pkt(instance, cmd);
+
/* Call the callback routine */
if (((pkt->pkt_flags & FLAG_NOINTR) == 0) &&
pkt->pkt_comp) {
-
- con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_softintr: "
- "posting to scsa cmd %p index %x pkt %p "
- "time %llx", (void *)cmd, cmd->index,
- (void *)pkt, gethrtime()));
(*pkt->pkt_comp)(pkt);
-
}
- return_mfi_pkt(instance, cmd);
break;
case MFI_CMD_OP_SMP:
@@ -5088,7 +5118,7 @@ build_cmd(struct mrsas_instance *instance, struct scsi_address *ap,
*cmd_done = 0;
/* get the command packet */
- if (!(cmd = get_mfi_pkt(instance))) {
+ if (!(cmd = mrsas_get_mfi_pkt(instance))) {
DTRACE_PROBE2(build_cmd_mfi_err, uint16_t,
instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
return (NULL);
@@ -5136,7 +5166,7 @@ build_cmd(struct mrsas_instance *instance, struct scsi_address *ap,
/*
* case SCMD_SYNCHRONIZE_CACHE:
* flush_cache(instance);
- * return_mfi_pkt(instance, cmd);
+ * mrsas_return_mfi_pkt(instance, cmd);
* *cmd_done = 1;
*
* return (NULL);
@@ -5245,7 +5275,7 @@ build_cmd(struct mrsas_instance *instance, struct scsi_address *ap,
break;
}
- /* fall through For all non-rd/wr cmds */
+ /* fall through For all non-rd/wr and physical disk cmds */
default:
switch (pkt->pkt_cdbp[0]) {
@@ -5260,7 +5290,7 @@ build_cmd(struct mrsas_instance *instance, struct scsi_address *ap,
case 0x3:
case 0x4:
(void) mrsas_mode_sense_build(pkt);
- return_mfi_pkt(instance, cmd);
+ mrsas_return_mfi_pkt(instance, cmd);
*cmd_done = 1;
return (NULL);
}
@@ -6294,7 +6324,7 @@ handle_mfi_ioctl(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl,
if (instance->tbolt) {
cmd = get_raid_msg_mfi_pkt(instance);
} else {
- cmd = get_mfi_pkt(instance);
+ cmd = mrsas_get_mfi_pkt(instance);
}
if (!cmd) {
con_log(CL_ANN, (CE_WARN, "mr_sas: "
@@ -6338,7 +6368,7 @@ handle_mfi_ioctl(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl,
if (instance->tbolt) {
return_raid_msg_mfi_pkt(instance, cmd);
} else {
- return_mfi_pkt(instance, cmd);
+ mrsas_return_mfi_pkt(instance, cmd);
}
return (rval);
@@ -6435,7 +6465,7 @@ register_mfi_aen(struct mrsas_instance *instance, uint32_t seq_num,
if (instance->tbolt) {
cmd = get_raid_msg_mfi_pkt(instance);
} else {
- cmd = get_mfi_pkt(instance);
+ cmd = mrsas_get_mfi_pkt(instance);
}
if (!cmd) {
@@ -6728,7 +6758,7 @@ issue_cmd_ppc(struct mrsas_cmd *cmd, struct mrsas_instance *instance)
mutex_enter(&instance->reg_write_mtx);
/* Issue the command to the FW */
- WR_IB_QPORT((cmd->frame_phys_addr) |
+ WR_IB_PICK_QPORT((cmd->frame_phys_addr) |
(((cmd->frame_count - 1) << 1) | 1), instance);
mutex_exit(&instance->reg_write_mtx);
@@ -6739,10 +6769,10 @@ issue_cmd_ppc(struct mrsas_cmd *cmd, struct mrsas_instance *instance)
*/
static int
issue_cmd_in_sync_mode_ppc(struct mrsas_instance *instance,
-struct mrsas_cmd *cmd)
+ struct mrsas_cmd *cmd)
{
int i;
- uint32_t msecs = MFI_POLL_TIMEOUT_SECS * (10 * MILLISEC);
+ uint32_t msecs = MFI_POLL_TIMEOUT_SECS * MILLISEC;
struct mrsas_header *hdr = &cmd->frame->hdr;
con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_sync_mode_ppc: called"));
@@ -6755,7 +6785,7 @@ struct mrsas_cmd *cmd)
con_log(CL_ANN1, (CE_NOTE, "sync_mode_ppc: "
"issue and return in reset case\n"));
- WR_IB_QPORT((cmd->frame_phys_addr) |
+ WR_IB_PICK_QPORT((cmd->frame_phys_addr) |
(((cmd->frame_count - 1) << 1) | 1), instance);
return (DDI_SUCCESS);
@@ -6768,7 +6798,7 @@ struct mrsas_cmd *cmd)
mutex_enter(&instance->reg_write_mtx);
/* Issue the command to the FW */
- WR_IB_QPORT((cmd->frame_phys_addr) |
+ WR_IB_PICK_QPORT((cmd->frame_phys_addr) |
(((cmd->frame_count - 1) << 1) | 1), instance);
mutex_exit(&instance->reg_write_mtx);
@@ -6810,7 +6840,7 @@ issue_cmd_in_poll_mode_ppc(struct mrsas_instance *instance,
ddi_put16(cmd->frame_dma_obj.acc_handle, &frame_hdr->flags, flags);
/* issue the frame using inbound queue port */
- WR_IB_QPORT((cmd->frame_phys_addr) |
+ WR_IB_PICK_QPORT((cmd->frame_phys_addr) |
(((cmd->frame_count - 1) << 1) | 1), instance);
/* wait for cmd_status to change from 0xFF */
@@ -6837,11 +6867,16 @@ enable_intr_ppc(struct mrsas_instance *instance)
con_log(CL_ANN1, (CE_NOTE, "enable_intr_ppc: called"));
- /* WR_OB_DOORBELL_CLEAR(0xFFFFFFFF, instance); */
- WR_OB_DOORBELL_CLEAR(OB_DOORBELL_CLEAR_MASK, instance);
+ if (instance->skinny) {
+ /* For SKINNY, write ~0x1, from BSD's mfi driver. */
+ WR_OB_INTR_MASK(0xfffffffe, instance);
+ } else {
+ /* WR_OB_DOORBELL_CLEAR(0xFFFFFFFF, instance); */
+ WR_OB_DOORBELL_CLEAR(OB_DOORBELL_CLEAR_MASK, instance);
- /* WR_OB_INTR_MASK(~0x80000000, instance); */
- WR_OB_INTR_MASK(~(MFI_REPLY_2108_MESSAGE_INTR_MASK), instance);
+ /* WR_OB_INTR_MASK(~0x80000000, instance); */
+ WR_OB_INTR_MASK(~(MFI_REPLY_2108_MESSAGE_INTR_MASK), instance);
+ }
/* dummy read to force PCI flush */
mask = RD_OB_INTR_MASK(instance);
@@ -6860,7 +6895,8 @@ disable_intr_ppc(struct mrsas_instance *instance)
con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: before : "
"outbound_intr_mask = 0x%x", RD_OB_INTR_MASK(instance)));
- /* WR_OB_INTR_MASK(0xFFFFFFFF, instance); */
+ /* For now, assume there are no extras needed for Skinny support. */
+
WR_OB_INTR_MASK(OB_INTR_MASK, instance);
con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: after : "
@@ -6886,6 +6922,10 @@ intr_ack_ppc(struct mrsas_instance *instance)
con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: status = 0x%x", status));
+ /*
+ * NOTE: Some drivers call out SKINNY here, but the return is the same
+ * for SKINNY and 2108.
+ */
if (!(status & MFI_REPLY_2108_MESSAGE_INTR)) {
ret = DDI_INTR_UNCLAIMED;
}
@@ -6898,8 +6938,16 @@ intr_ack_ppc(struct mrsas_instance *instance)
if (ret == DDI_INTR_UNCLAIMED) {
return (ret);
}
- /* clear the interrupt by writing back the same value */
- WR_OB_DOORBELL_CLEAR(status, instance);
+
+ /*
+ * Clear the interrupt by writing back the same value.
+ * Another case where SKINNY is slightly different.
+ */
+ if (instance->skinny) {
+ WR_OB_INTR_STATUS(status, instance);
+ } else {
+ WR_OB_DOORBELL_CLEAR(status, instance);
+ }
/* dummy READ */
status = RD_OB_INTR_STATUS(instance);
@@ -7485,7 +7533,7 @@ mrsas_tran_bus_config(dev_info_t *parent, uint_t flags,
if (lun == 0) {
rval = mrsas_config_ld(instance, tgt, lun, childp);
#ifdef PDSUPPORT
- } else if (instance->tbolt == 1 && lun != 0) {
+ } else if ((instance->tbolt || instance->skinny) && lun != 0) {
rval = mrsas_tbolt_config_pd(instance,
tgt, lun, childp);
#endif
@@ -7528,7 +7576,7 @@ mrsas_config_all_devices(struct mrsas_instance *instance)
#ifdef PDSUPPORT
/* Config PD devices connected to the card */
- if (instance->tbolt) {
+ if (instance->tbolt || instance->skinny) {
for (tgt = 0; tgt < instance->mr_tbolt_pd_max; tgt++) {
(void) mrsas_tbolt_config_pd(instance, tgt, 1, NULL);
}
@@ -7782,7 +7830,7 @@ mrsas_issue_evt_taskq(struct mrsas_eventinfo *mrevt)
(void) mrsas_config_ld(instance, mrevt->tgt,
0, NULL);
#ifdef PDSUPPORT
- } else if (instance->tbolt) {
+ } else if (instance->tbolt || instance->skinny) {
(void) mrsas_tbolt_config_pd(instance,
mrevt->tgt,
1, NULL);
diff --git a/usr/src/uts/common/io/mr_sas/mr_sas.h b/usr/src/uts/common/io/mr_sas/mr_sas.h
index f5bd2169d6..e8da1321db 100644
--- a/usr/src/uts/common/io/mr_sas/mr_sas.h
+++ b/usr/src/uts/common/io/mr_sas/mr_sas.h
@@ -43,6 +43,7 @@
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _MR_SAS_H_
@@ -90,6 +91,8 @@ extern "C" {
*/
#define PCI_DEVICE_ID_LSI_2108VDE 0x0078
#define PCI_DEVICE_ID_LSI_2108V 0x0079
+#define PCI_DEVICE_ID_LSI_SKINNY 0x0071
+#define PCI_DEVICE_ID_LSI_SKINNY_NEW 0x0073
#define PCI_DEVICE_ID_LSI_TBOLT 0x005b
#define PCI_DEVICE_ID_LSI_INVADER 0x005d
@@ -100,6 +103,7 @@ extern "C" {
#define MRSAS_MAX_SGE_CNT 0x50
#define MRSAS_APP_RESERVED_CMDS 32
+#define MRSAS_APP_MIN_RESERVED_CMDS 4
#define MRSAS_IOCTL_DRIVER 0x12341234
#define MRSAS_IOCTL_FIRMWARE 0x12345678
@@ -594,7 +598,8 @@ typedef struct mrsas_instance {
uint8_t fast_path_io;
- uint16_t tbolt;
+ uint8_t skinny;
+ uint8_t tbolt;
uint16_t reply_read_index;
uint16_t reply_size; /* Single Reply struct size */
uint16_t raid_io_msg_size; /* Single message size */
@@ -2045,6 +2050,9 @@ struct mrsas_cmd *get_raid_msg_pkt(struct mrsas_instance *);
int mfi_state_transition_to_ready(struct mrsas_instance *);
+struct mrsas_cmd *mrsas_get_mfi_pkt(struct mrsas_instance *);
+void mrsas_return_mfi_pkt(struct mrsas_instance *, struct mrsas_cmd *);
+
/* FMA functions. */
int mrsas_common_check(struct mrsas_instance *, struct mrsas_cmd *);
diff --git a/usr/src/uts/common/io/mr_sas/mr_sas_tbolt.c b/usr/src/uts/common/io/mr_sas/mr_sas_tbolt.c
index b9821b23c9..aebc70c3b8 100644
--- a/usr/src/uts/common/io/mr_sas/mr_sas_tbolt.c
+++ b/usr/src/uts/common/io/mr_sas/mr_sas_tbolt.c
@@ -15,6 +15,10 @@
* Shakeel Bukhari
*/
+/*
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ */
+
#include <sys/types.h>
#include <sys/file.h>
@@ -46,8 +50,6 @@ extern struct ddi_device_acc_attr endian_attr;
extern int debug_level_g;
extern unsigned int enable_fp;
volatile int dump_io_wait_time = 90;
-extern void
-io_timeout_checker(void *arg);
extern volatile int debug_timeout_g;
extern int mrsas_issue_pending_cmds(struct mrsas_instance *);
extern int mrsas_complete_pending_cmds(struct mrsas_instance *instance);
@@ -1882,96 +1884,6 @@ mrsas_tbolt_build_cmd(struct mrsas_instance *instance, struct scsi_address *ap,
return (cmd);
}
-/*
- * mrsas_tbolt_tran_init_pkt - allocate & initialize a scsi_pkt structure
- * @ap:
- * @pkt:
- * @bp:
- * @cmdlen:
- * @statuslen:
- * @tgtlen:
- * @flags:
- * @callback:
- *
- * The tran_init_pkt() entry point allocates and initializes a scsi_pkt
- * structure and DMA resources for a target driver request. The
- * tran_init_pkt() entry point is called when the target driver calls the
- * SCSA function scsi_init_pkt(). Each call of the tran_init_pkt() entry point
- * is a request to perform one or more of three possible services:
- * - allocation and initialization of a scsi_pkt structure
- * - allocation of DMA resources for data transfer
- * - reallocation of DMA resources for the next portion of the data transfer
- */
-struct scsi_pkt *
-mrsas_tbolt_tran_init_pkt(struct scsi_address *ap,
- register struct scsi_pkt *pkt,
- struct buf *bp, int cmdlen, int statuslen, int tgtlen,
- int flags, int (*callback)(), caddr_t arg)
-{
- struct scsa_cmd *acmd;
- struct mrsas_instance *instance;
- struct scsi_pkt *new_pkt;
-
- instance = ADDR2MR(ap);
-
- /* step #1 : pkt allocation */
- if (pkt == NULL) {
- pkt = scsi_hba_pkt_alloc(instance->dip, ap, cmdlen, statuslen,
- tgtlen, sizeof (struct scsa_cmd), callback, arg);
- if (pkt == NULL) {
- return (NULL);
- }
-
- acmd = PKT2CMD(pkt);
-
- /*
- * Initialize the new pkt - we redundantly initialize
- * all the fields for illustrative purposes.
- */
- acmd->cmd_pkt = pkt;
- acmd->cmd_flags = 0;
- acmd->cmd_scblen = statuslen;
- acmd->cmd_cdblen = cmdlen;
- acmd->cmd_dmahandle = NULL;
- acmd->cmd_ncookies = 0;
- acmd->cmd_cookie = 0;
- acmd->cmd_cookiecnt = 0;
- acmd->cmd_nwin = 0;
-
- pkt->pkt_address = *ap;
- pkt->pkt_comp = (void (*)())NULL;
- pkt->pkt_flags = 0;
- pkt->pkt_time = 0;
- pkt->pkt_resid = 0;
- pkt->pkt_state = 0;
- pkt->pkt_statistics = 0;
- pkt->pkt_reason = 0;
- new_pkt = pkt;
- } else {
- acmd = PKT2CMD(pkt);
- new_pkt = NULL;
- }
-
- /* step #2 : dma allocation/move */
- if (bp && bp->b_bcount != 0) {
- if (acmd->cmd_dmahandle == NULL) {
- if (mrsas_dma_alloc(instance, pkt, bp, flags,
- callback) == DDI_FAILURE) {
- if (new_pkt) {
- scsi_hba_pkt_free(ap, new_pkt);
- }
- return ((struct scsi_pkt *)NULL);
- }
- } else {
- if (mrsas_dma_move(instance, pkt, bp) == DDI_FAILURE) {
- return ((struct scsi_pkt *)NULL);
- }
- }
- }
- return (pkt);
-}
-
-
uint32_t
tbolt_read_fw_status_reg(struct mrsas_instance *instance)
{
@@ -3632,6 +3544,14 @@ abort_syncmap_cmd(struct mrsas_instance *instance,
#ifdef PDSUPPORT
+/*
+ * Even though these functions were originally intended for 2208 only, it
+ * turns out they're useful for "Skinny" support as well. In a perfect world,
+ * these two functions would be either in mr_sas.c, or in their own new source
+ * file. Since this driver needs some cleanup anyway, keep this portion in
+ * mind as well.
+ */
+
int
mrsas_tbolt_config_pd(struct mrsas_instance *instance, uint16_t tgt,
uint8_t lun, dev_info_t **ldip)
@@ -3694,7 +3614,6 @@ mrsas_tbolt_config_pd(struct mrsas_instance *instance, uint16_t tgt,
sd->sd_inq = (struct scsi_inquiry *)NULL;
}
kmem_free(sd, sizeof (struct scsi_device));
- rval = NDI_SUCCESS;
} else {
con_log(CL_ANN1, (CE_NOTE,
"Device not supported: tgt %d lun %d dtype %d",
@@ -3716,7 +3635,12 @@ mrsas_tbolt_get_pd_info(struct mrsas_instance *instance,
struct mrsas_dcmd_frame *dcmd;
dma_obj_t dcmd_dma_obj;
- cmd = get_raid_msg_pkt(instance);
+ ASSERT(instance->tbolt || instance->skinny);
+
+ if (instance->tbolt)
+ cmd = get_raid_msg_pkt(instance);
+ else
+ cmd = mrsas_get_mfi_pkt(instance);
if (!cmd) {
con_log(CL_ANN1,
@@ -3761,9 +3685,8 @@ mrsas_tbolt_get_pd_info(struct mrsas_instance *instance,
cmd->sync_cmd = MRSAS_TRUE;
cmd->frame_count = 1;
- if (instance->tbolt) {
+ if (instance->tbolt)
mr_sas_tbolt_build_mfi_cmd(instance, cmd);
- }
instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd);
@@ -3771,6 +3694,10 @@ mrsas_tbolt_get_pd_info(struct mrsas_instance *instance,
(uint8_t *)dcmd_dma_obj.buffer, sizeof (struct mrsas_tbolt_pd_info),
DDI_DEV_AUTOINCR);
(void) mrsas_free_dma_obj(instance, dcmd_dma_obj);
- return_raid_msg_pkt(instance, cmd);
+
+ if (instance->tbolt)
+ return_raid_msg_pkt(instance, cmd);
+ else
+ mrsas_return_mfi_pkt(instance, cmd);
}
#endif