From owner-freebsd-hackers@FreeBSD.ORG Sun Feb 17 18:06:30 2013 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id BE8BAC43 for ; Sun, 17 Feb 2013 18:06:30 +0000 (UTC) (envelope-from prvs=17602818aa=killing@multiplay.co.uk) Received: from mail1.multiplay.co.uk (mail1.multiplay.co.uk [85.236.96.23]) by mx1.freebsd.org (Postfix) with ESMTP id D5F33164 for ; Sun, 17 Feb 2013 18:06:29 +0000 (UTC) Received: from r2d2 ([188.220.16.49]) by mail1.multiplay.co.uk (mail1.multiplay.co.uk [85.236.96.23]) (MDaemon PRO v10.0.4) with ESMTP id md50002265088.msg for ; Sun, 17 Feb 2013 18:06:28 +0000 X-Spam-Processed: mail1.multiplay.co.uk, Sun, 17 Feb 2013 18:06:28 +0000 (not processed: message from valid local sender) X-MDRemoteIP: 188.220.16.49 X-Return-Path: prvs=17602818aa=killing@multiplay.co.uk X-Envelope-From: killing@multiplay.co.uk X-MDaemon-Deliver-To: freebsd-hackers@freebsd.org Message-ID: <49693195BAD841469129EE4B7523CABE@multiplay.co.uk> From: "Steven Hartland" To: Subject: Looking for reviewers for patch that adds foreign disk support mfiutil Date: Sun, 17 Feb 2013 18:06:40 -0000 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_02FD_01CE0D39.88DA2DE0" X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2900.5931 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157 X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 17 Feb 2013 18:06:30 -0000 This is a multi-part message in MIME format. ------=_NextPart_000_02FD_01CE0D39.88DA2DE0 Content-Type: text/plain; format=flowed; charset="iso-8859-1"; reply-type=original Content-Transfer-Encoding: 7bit Hi all I'm looking for someone to review the attached patch to mfiutil which adds foreign disk support to mfiutil as per: http://www.freebsd.org/cgi/query-pr.cgi?pr=172091 Any and all feedback welcome :) Regards Steve ================================================ This e.mail is private and confidential between Multiplay (UK) Ltd. and the person or entity to whom it is addressed. In the event of misdirection, the recipient is prohibited from using, copying, printing or otherwise disseminating it or any information contained in it. In the event of misdirection, illegible or incomplete transmission please telephone +44 845 868 1337 or return the E.mail to postmaster@multiplay.co.uk. ------=_NextPart_000_02FD_01CE0D39.88DA2DE0 Content-Type: application/octet-stream; name="z-mfi-foreign-timeout.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="z-mfi-foreign-timeout.patch" Add support for foreign disks / configs this implements the following new=0A= methods to mfiutil=0A= * foreign scan - lists the number of foreign configs=0A= * foreign drives - lists the drives which are flagged as foreign=0A= * foreign display - displays the specified foreign configuration=0A= * foreign preview - previews the specified foreign configuration (after = import)=0A= * foreign clear - clears the foreign configuration=0A= * foreign import - imports the foreign configuration=0A= =0A= mfiutil show drives - now identifies foreign drives=0A= =0A= It should be noted that although foreign import takes a configuration = option=0A= this currently fails with error code 0x03 (invalid argument). This also=0A= occurs with MegaCli so its currently thought this is a firmware bug.=0A= =0A= Adds hw.mfi.cmd_timeout loader / sysctl tuneable which controls the = default=0A= timeout used in the mfi driver. This is useful for long running commands=0A= such as secure erase.=0A= =0A= Additional debugging of DCMD commands has also been added which added=0A= identifying the DCMD's used by MegaCli to perform the various actions.=0A= --- usr.sbin/mfiutil/mfi_config.c.orig 2012-11-07 12:24:57.788834019 = +0000=0A= +++ usr.sbin/mfiutil/mfi_config.c 2012-11-07 14:31:31.462399216 +0000=0A= @@ -37,19 +37,13 @@=0A= #include =0A= #include =0A= #include =0A= -#ifdef DEBUG=0A= #include =0A= -#endif=0A= #include =0A= #include =0A= #include =0A= #include =0A= #include "mfiutil.h"=0A= =0A= -#ifdef DEBUG=0A= -static void dump_config(int fd, struct mfi_config_data *config);=0A= -#endif=0A= -=0A= static int add_spare(int ac, char **av);=0A= static int remove_spare(int ac, char **av);=0A= =0A= @@ -81,9 +75,17 @@=0A= }=0A= return (iv);=0A= }=0A= +=0A= int=0A= mfi_config_read(int fd, struct mfi_config_data **configp)=0A= {=0A= + return mfi_config_read_opcode(fd, MFI_DCMD_CFG_READ, configp, NULL, 0);=0A= +}=0A= +=0A= +int=0A= +mfi_config_read_opcode(int fd, uint32_t opcode, struct mfi_config_data = **configp,=0A= + uint8_t *mbox, size_t mboxlen)=0A= +{=0A= struct mfi_config_data *config;=0A= uint32_t config_size;=0A= int error;=0A= @@ -98,8 +100,8 @@=0A= config =3D reallocf(config, config_size);=0A= if (config =3D=3D NULL)=0A= return (-1);=0A= - if (mfi_dcmd_command(fd, MFI_DCMD_CFG_READ, config,=0A= - config_size, NULL, 0, NULL) < 0) {=0A= + if (mfi_dcmd_command(fd, opcode, config,=0A= + config_size, mbox, mboxlen, NULL) < 0) {=0A= error =3D errno;=0A= free(config);=0A= errno =3D error;=0A= @@ -366,6 +368,13 @@=0A= info->drives =3D NULL;=0A= return (EINVAL);=0A= }=0A= +=0A= + if (pinfo->state.ddf.v.pd_type.is_foreign) {=0A= + warnx("Drive %u is foreign", device_id);=0A= + free(info->drives);=0A= + info->drives =3D NULL;=0A= + return (EINVAL);=0A= + }=0A= }=0A= =0A= return (0);=0A= @@ -804,7 +813,7 @@=0A= =0A= #ifdef DEBUG=0A= if (dump)=0A= - dump_config(fd, config);=0A= + dump_config(fd, config, NULL);=0A= #endif=0A= =0A= /* Send the new config to the controller. */=0A= @@ -1093,10 +1102,9 @@=0A= }=0A= MFI_COMMAND(top, remove, remove_spare);=0A= =0A= -#ifdef DEBUG=0A= /* Display raw data about a config. */=0A= -static void=0A= -dump_config(int fd, struct mfi_config_data *config)=0A= +void=0A= +dump_config(int fd, struct mfi_config_data *config, const char = *msg_prefix)=0A= {=0A= struct mfi_array *ar;=0A= struct mfi_ld_config *ld;=0A= @@ -1106,9 +1114,12 @@=0A= char *p;=0A= int i, j;=0A= =0A= + if (NULL =3D=3D msg_prefix)=0A= + msg_prefix =3D "Configuration (Debug)";=0A= +=0A= printf(=0A= - "mfi%d Configuration (Debug): %d arrays, %d volumes, %d spares\n",=0A= - mfi_unit, config->array_count, config->log_drv_count,=0A= + "mfi%d %s: %d arrays, %d volumes, %d spares\n", mfi_unit,=0A= + msg_prefix, config->array_count, config->log_drv_count,=0A= config->spares_count);=0A= printf(" array size: %u\n", config->array_size);=0A= printf(" volume size: %u\n", config->log_drv_size);=0A= @@ -1186,6 +1197,7 @@=0A= }=0A= }=0A= =0A= +#ifdef DEBUG=0A= static int=0A= debug_config(int ac, char **av)=0A= {=0A= @@ -1213,7 +1225,7 @@=0A= }=0A= =0A= /* Dump out the configuration. */=0A= - dump_config(fd, config);=0A= + dump_config(fd, config, NULL);=0A= free(config);=0A= close(fd);=0A= =0A= @@ -1265,7 +1277,7 @@=0A= close(fd);=0A= return (error);=0A= }=0A= - dump_config(fd, config);=0A= + dump_config(fd, config, NULL);=0A= free(config);=0A= close(fd);=0A= =0A= --- usr.sbin/mfiutil/mfiutil.h.orig 2012-11-07 12:25:06.150119092 +0000=0A= +++ usr.sbin/mfiutil/mfiutil.h 2012-11-07 14:31:31.464398803 +0000=0A= @@ -136,6 +136,8 @@=0A= const char *mfi_volume_name(int fd, uint8_t target_id);=0A= int mfi_volume_busy(int fd, uint8_t target_id);=0A= int mfi_config_read(int fd, struct mfi_config_data **configp);=0A= +int mfi_config_read_opcode(int fd, uint32_t opcode,=0A= + struct mfi_config_data **configp, uint8_t *mbox, size_t mboxlen);=0A= int mfi_lookup_drive(int fd, char *drive, uint16_t *device_id);=0A= int mfi_lookup_volume(int fd, const char *name, uint8_t *target_id);=0A= int mfi_dcmd_command(int fd, uint32_t opcode, void *buf, size_t bufsize,=0A= @@ -152,6 +154,10 @@=0A= const char *mfi_status(u_int status_code);=0A= const char *mfi_drive_name(struct mfi_pd_info *pinfo, uint16_t = device_id,=0A= uint32_t def);=0A= +void format_stripe(char *buf, size_t buflen, uint8_t stripe);=0A= +void print_ld(struct mfi_ld_info *info, int state_len);=0A= +void print_pd(struct mfi_pd_info *info, int state_len);=0A= +void dump_config(int fd, struct mfi_config_data *config, const char* = msg_prefix);=0A= =0A= void scan_firmware(struct mfi_info_component *comp);=0A= void display_firmware(struct mfi_info_component *comp, const char *tag);=0A= --- usr.sbin/mfiutil/Makefile.orig 2012-11-07 12:24:55.880985046 +0000=0A= +++ usr.sbin/mfiutil/Makefile 2012-11-07 14:31:31.460399070 +0000=0A= @@ -2,7 +2,7 @@=0A= PROG=3D mfiutil=0A= =0A= SRCS=3D mfiutil.c mfi_cmd.c mfi_config.c mfi_drive.c mfi_evt.c = mfi_flash.c \=0A= - mfi_patrol.c mfi_show.c mfi_volume.c=0A= + mfi_patrol.c mfi_show.c mfi_volume.c mfi_foreign.c=0A= MAN8=3D mfiutil.8=0A= =0A= CFLAGS+=3D -fno-builtin-strftime=0A= --- usr.sbin/mfiutil/mfi_foreign.c.orig 2012-11-07 14:31:31.467398742 = +0000=0A= +++ usr.sbin/mfiutil/mfi_foreign.c 2012-11-07 14:31:31.470398682 +0000=0A= @@ -0,0 +1,405 @@=0A= +/*-=0A= + * Copyright (c) 2008, 2009 Yahoo!, Inc.=0A= + * All rights reserved.=0A= + *=0A= + * Redistribution and use in source and binary forms, with or without=0A= + * modification, are permitted provided that the following conditions=0A= + * are met:=0A= + * 1. Redistributions of source code must retain the above copyright=0A= + * notice, this list of conditions and the following disclaimer.=0A= + * 2. Redistributions in binary form must reproduce the above copyright=0A= + * notice, this list of conditions and the following disclaimer in = the=0A= + * documentation and/or other materials provided with the = distribution.=0A= + * 3. The names of the authors may not be used to endorse or promote=0A= + * products derived from this software without specific prior written=0A= + * permission.=0A= + *=0A= + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' = AND=0A= + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE=0A= + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR = PURPOSE=0A= + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE = LIABLE=0A= + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR = CONSEQUENTIAL=0A= + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE = GOODS=0A= + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)=0A= + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, = STRICT=0A= + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN = ANY WAY=0A= + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY = OF=0A= + * SUCH DAMAGE.=0A= + *=0A= + * $FreeBSD$=0A= + */=0A= +=0A= +#include =0A= +#include =0A= +#include =0A= +#include =0A= +#include =0A= +#include =0A= +#include =0A= +#include =0A= +#include =0A= +#include "mfiutil.h"=0A= +=0A= +MFI_TABLE(top, foreign);=0A= +=0A= +/* We currently don't know the full details of the following struct */=0A= +struct mfi_foreign_scan_cfg {=0A= + char data[24];=0A= +};=0A= +=0A= +struct mfi_foreign_scan_info {=0A= + uint32_t count; /* Number of foreign configs found */=0A= + struct mfi_foreign_scan_cfg cfgs[8];=0A= +};=0A= +=0A= +static int=0A= +foreign_drives(int ac, char **av)=0A= +{=0A= + struct mfi_pd_info info;=0A= + struct mfi_pd_list *list;=0A= + int error, fd;=0A= + u_int i;=0A= + fd =3D mfi_open(mfi_unit, O_RDONLY);=0A= + if (fd < 0) {=0A= + error =3D errno;=0A= + warn("mfi_open");=0A= + return (error);=0A= + }=0A= +=0A= + list =3D NULL;=0A= + if (mfi_pd_get_list(fd, &list, NULL) < 0) {=0A= + error =3D errno;=0A= + warn("Failed to get drive list");=0A= + goto error;=0A= + }=0A= + /* List the drives. */=0A= + printf("mfi%d Foreign disks:\n", mfi_unit);=0A= + for (i =3D 0; i < list->count; i++) {=0A= + /* Skip non-hard disks. */=0A= + if (list->addr[i].scsi_dev_type !=3D 0)=0A= + continue;=0A= + /* Fetch details for this drive. */=0A= + if (mfi_pd_get_info(fd, list->addr[i].device_id, &info,=0A= + NULL) < 0) {=0A= + error =3D errno;=0A= + warn("Failed to fetch info for drive %u",=0A= + list->addr[i].device_id);=0A= + goto error;=0A= + }=0A= +=0A= + if (!info.state.ddf.v.pd_type.is_foreign)=0A= + continue;=0A= + =0A= + printf("%s ", mfi_drive_name(&info, list->addr[i].device_id,=0A= + MFI_DNAME_DEVICE_ID));=0A= + print_pd(&info, -1);=0A= + printf(" %s\n", mfi_drive_name(&info, list->addr[i].device_id,=0A= + MFI_DNAME_ES));=0A= + }=0A= +error:=0A= + if(list)=0A= + free(list);=0A= + close(fd);=0A= + error =3D 0;=0A= + return (0);=0A= +}=0A= +MFI_COMMAND(foreign, drives, foreign_drives);=0A= +=0A= +static int=0A= +foreign_clear(int ac, char **av)=0A= +{=0A= + int ch, error, fd;=0A= +=0A= + fd =3D mfi_open(mfi_unit, O_RDWR);=0A= + if (fd < 0) {=0A= + error =3D errno;=0A= + warn("mfi_open");=0A= + return (error);=0A= + }=0A= +=0A= + printf(=0A= + "Are you sure you wish to clear ALL foreign configurations"=0A= + " on mfi%u? [y/N] ", mfi_unit);=0A= +=0A= + ch =3D getchar();=0A= + if (ch !=3D 'y' && ch !=3D 'Y') {=0A= + printf("\nAborting\n");=0A= + close(fd);=0A= + return (0);=0A= + }=0A= +=0A= + if (mfi_dcmd_command(fd, MFI_DCMD_CFG_FOREIGN_CLEAR, NULL, 0, NULL,=0A= + 0, NULL) < 0) {=0A= + error =3D errno;=0A= + warn("Failed to clear foreign configuration");=0A= + close(fd);=0A= + return (error);=0A= + }=0A= +=0A= + printf("mfi%d: Foreign configuration cleared\n", mfi_unit);=0A= + close(fd);=0A= + return (0);=0A= +}=0A= +MFI_COMMAND(foreign, clear, foreign_clear);=0A= +=0A= +static int=0A= +foreign_scan(int ac, char **av)=0A= +{=0A= + struct mfi_foreign_scan_info info;=0A= + int error, fd;=0A= +=0A= + fd =3D mfi_open(mfi_unit, O_RDONLY);=0A= + if (fd < 0) {=0A= + error =3D errno;=0A= + warn("mfi_open");=0A= + return (error);=0A= + }=0A= +=0A= + if (mfi_dcmd_command(fd, MFI_DCMD_CFG_FOREIGN_SCAN, &info,=0A= + sizeof(info), NULL, 0, NULL) < 0) {=0A= + error =3D errno;=0A= + warn("Failed to scan foreign configuration");=0A= + close(fd);=0A= + return (error);=0A= + }=0A= +=0A= + printf("mfi%d: Found %d foreign configurations\n", mfi_unit,=0A= + info.count);=0A= + close(fd);=0A= + return (0);=0A= +}=0A= +MFI_COMMAND(foreign, scan, foreign_scan);=0A= +=0A= +static int=0A= +foreign_show_cfg(int fd, uint32_t opcode, uint8_t cfgidx)=0A= +{=0A= + struct mfi_config_data *config;=0A= + char prefix[26];=0A= + int error, i;=0A= + uint8_t mbox[4];=0A= +=0A= + bzero(mbox, sizeof(mbox));=0A= + mbox[0] =3D cfgidx;=0A= + if (mfi_config_read_opcode(fd, opcode, &config, mbox, sizeof(mbox))=0A= + < 0) {=0A= + error =3D errno;=0A= + warn("Failed to get foreign config %d", i);=0A= + close(fd);=0A= + return (error);=0A= + }=0A= +=0A= + if (opcode =3D=3D MFI_DCMD_CFG_FOREIGN_PREVIEW)=0A= + sprintf(prefix, "Foreign configuration preview %d", cfgidx);=0A= + else=0A= + sprintf(prefix, "Foreign configuration %d", cfgidx);=0A= + /*=0A= + * MegaCli uses DCMD opcodes: 0x03100200 (which fails) followed by=0A= + * 0x1a721880 which returns what looks to be drive / volume info=0A= + * but we have no real information on what these are or what they do=0A= + * so we're currently relying solely on the config returned above=0A= + */=0A= + dump_config(fd, config, prefix);=0A= + free(config);=0A= +=0A= + return (0);=0A= +}=0A= +=0A= +static int=0A= +foreign_display(int ac, char **av)=0A= +{=0A= + struct mfi_foreign_scan_info info;=0A= + uint8_t i;=0A= + int error, fd;=0A= +=0A= + if (2 < ac) {=0A= + warnx("foreign display: extra arguments");=0A= + return (EINVAL);=0A= + }=0A= +=0A= + fd =3D mfi_open(mfi_unit, O_RDONLY);=0A= + if (fd < 0) {=0A= + error =3D errno;=0A= + warn("mfi_open");=0A= + return (error);=0A= + }=0A= +=0A= + if (mfi_dcmd_command(fd, MFI_DCMD_CFG_FOREIGN_SCAN, &info,=0A= + sizeof(info), NULL, 0, NULL) < 0) {=0A= + error =3D errno;=0A= + warn("Failed to scan foreign configuration");=0A= + close(fd);=0A= + return (error);=0A= + }=0A= +=0A= + if (0 =3D=3D info.count) {=0A= + warnx("foreign display: no foreign configs found");=0A= + close(fd);=0A= + return (EINVAL);=0A= + }=0A= +=0A= + if (1 =3D=3D ac) {=0A= + for (i =3D 0; i < info.count; i++) {=0A= + error =3D foreign_show_cfg(fd,=0A= + MFI_DCMD_CFG_FOREIGN_DISPLAY, i);=0A= + if(0 !=3D error) {=0A= + close(fd);=0A= + return (error);=0A= + }=0A= + if (i < info.count - 1)=0A= + printf("\n");=0A= + }=0A= + } else if (2 =3D=3D ac) {=0A= + error =3D foreign_show_cfg(fd,=0A= + MFI_DCMD_CFG_FOREIGN_DISPLAY, atoi(av[1]));=0A= + if (0 !=3D error) {=0A= + close(fd);=0A= + return (error);=0A= + }=0A= + }=0A= + =0A= + close(fd);=0A= + return (0);=0A= +}=0A= +MFI_COMMAND(foreign, display, foreign_display);=0A= +=0A= +static int=0A= +foreign_preview(int ac, char **av)=0A= +{=0A= + struct mfi_foreign_scan_info info;=0A= + uint8_t i;=0A= + int error, fd;=0A= +=0A= + if (2 < ac) {=0A= + warnx("foreign preview: extra arguments");=0A= + return (EINVAL);=0A= + }=0A= +=0A= + fd =3D mfi_open(mfi_unit, O_RDONLY);=0A= + if (fd < 0) {=0A= + error =3D errno;=0A= + warn("mfi_open");=0A= + return (error);=0A= + }=0A= +=0A= + if (mfi_dcmd_command(fd, MFI_DCMD_CFG_FOREIGN_SCAN, &info,=0A= + sizeof(info), NULL, 0, NULL) < 0) {=0A= + error =3D errno;=0A= + warn("Failed to scan foreign configuration");=0A= + close(fd);=0A= + return (error);=0A= + }=0A= +=0A= + if (0 =3D=3D info.count) {=0A= + warnx("foreign preview: no foreign configs found");=0A= + close(fd);=0A= + return (EINVAL);=0A= + }=0A= +=0A= + if (1 =3D=3D ac) {=0A= + for (i =3D 0; i < info.count; i++) {=0A= + error =3D foreign_show_cfg(fd,=0A= + MFI_DCMD_CFG_FOREIGN_PREVIEW, i);=0A= + if(0 !=3D error) {=0A= + close(fd);=0A= + return (error);=0A= + }=0A= + if (i < info.count - 1)=0A= + printf("\n");=0A= + }=0A= + } else if (2 =3D=3D ac) {=0A= + error =3D foreign_show_cfg(fd,=0A= + MFI_DCMD_CFG_FOREIGN_PREVIEW, atoi(av[1]));=0A= + if (0 !=3D error) {=0A= + close(fd);=0A= + return (error);=0A= + }=0A= + }=0A= + =0A= + close(fd);=0A= + return (0);=0A= +}=0A= +MFI_COMMAND(foreign, preview, foreign_preview);=0A= +=0A= +static int=0A= +foreign_import(int ac, char **av)=0A= +{=0A= + struct mfi_foreign_scan_info info;=0A= + int ch, error, fd;=0A= + uint8_t cfgidx;=0A= + uint8_t mbox[4];=0A= +=0A= + if (2 < ac) {=0A= + warnx("foreign preview: extra arguments");=0A= + return (EINVAL);=0A= + }=0A= +=0A= + fd =3D mfi_open(mfi_unit, O_RDWR);=0A= + if (fd < 0) {=0A= + error =3D errno;=0A= + warn("mfi_open");=0A= + return (error);=0A= + }=0A= +=0A= + if (mfi_dcmd_command(fd, MFI_DCMD_CFG_FOREIGN_SCAN, &info,=0A= + sizeof(info), NULL, 0, NULL) < 0) {=0A= + error =3D errno;=0A= + warn("Failed to scan foreign configuration");=0A= + close(fd);=0A= + return (error);=0A= + }=0A= +=0A= + if (0 =3D=3D info.count) {=0A= + warnx("foreign import: no foreign configs found");=0A= + close(fd);=0A= + return (EINVAL);=0A= + }=0A= +=0A= + if (1 =3D=3D ac) {=0A= + cfgidx =3D 0xff;=0A= + printf("Are you sure you wish to import ALL foreign "=0A= + "configurations on mfi%u? [y/N] ", mfi_unit);=0A= + } else {=0A= + /*=0A= + * While this is docmmented for MegaCli this failed with=0A= + * exit code 0x03 on the test controller which was a Supermicro=0A= + * SMC2108 with firmware 12.12.0-0095 which is a LSI 2108 based=0A= + * controller.=0A= + */=0A= + cfgidx =3D atoi(av[1]);=0A= + if (cfgidx >=3D info.count) {=0A= + warnx("Invalid foreign config %d specified max is %d",=0A= + cfgidx, info.count - 1);=0A= + close(fd);=0A= + return (EINVAL);=0A= + }=0A= + printf("Are you sure you wish to import the foreign "=0A= + "configuration %d on mfi%u? [y/N] ", cfgidx, mfi_unit);=0A= + }=0A= +=0A= + ch =3D getchar();=0A= + if (ch !=3D 'y' && ch !=3D 'Y') {=0A= + printf("\nAborting\n");=0A= + close(fd);=0A= + return (0);=0A= + }=0A= +=0A= + bzero(mbox, sizeof(mbox));=0A= + mbox[0] =3D cfgidx;=0A= + if (mfi_dcmd_command(fd, MFI_DCMD_CFG_FOREIGN_IMPORT, NULL, 0, mbox,=0A= + sizeof(mbox), NULL) < 0) {=0A= + error =3D errno;=0A= + warn("Failed to import foreign configuration");=0A= + close(fd);=0A= + return (error);=0A= + }=0A= +=0A= + if (1 =3D=3D ac)=0A= + printf("mfi%d: All foreign configurations imported\n",=0A= + mfi_unit);=0A= + else=0A= + printf("mfi%d: Foreign configuration %d imported\n", mfi_unit,=0A= + cfgidx);=0A= + close(fd);=0A= + return (0);=0A= +}=0A= +MFI_COMMAND(foreign, import, foreign_import);=0A= --- usr.sbin/mfiutil/mfiutil.c.orig 2012-11-07 12:25:04.142289096 +0000=0A= +++ usr.sbin/mfiutil/mfiutil.c 2012-11-07 14:31:31.464398803 +0000=0A= @@ -83,6 +83,12 @@=0A= fprintf(stderr, " patrol [interval = [start]]\n");=0A= fprintf(stderr, " start patrol - start a patrol = read\n");=0A= fprintf(stderr, " stop patrol - stop a patrol = read\n");=0A= + fprintf(stderr, " foreign scan - scan for foreign = configurations\n");=0A= + fprintf(stderr, " foreign drives - list foreign = drives\n");=0A= + fprintf(stderr, " foreign clear [volume] - clear foreign = configurations (default all)\n");=0A= + fprintf(stderr, " foreign display [volume] - display foreign = configurations (default all)\n");=0A= + fprintf(stderr, " foreign preview [volume] - preview foreign = configurations (default all)\n");=0A= + fprintf(stderr, " foreign import [volume] - import foreign = configurations (default all)\n");=0A= fprintf(stderr, " flash \n");=0A= #ifdef DEBUG=0A= fprintf(stderr, " debug - debug 'show = config'\n");=0A= --- usr.sbin/mfiutil/mfiutil.8.orig 2012-11-07 12:24:54.871069332 +0000=0A= +++ usr.sbin/mfiutil/mfiutil.8 2012-11-07 14:31:31.471400151 +0000=0A= @@ -140,6 +140,24 @@=0A= .Cm patrol Ar command Op Ar interval Op Ar start=0A= .Nm=0A= .Op Fl u Ar unit=0A= +.Cm foreign scan=0A= +.Nm=0A= +.Op Fl u Ar unit=0A= +.Cm foreign drives=0A= +.Nm=0A= +.Op Fl u Ar unit=0A= +.Cm foreign clear Op Ar config=0A= +.Nm=0A= +.Op Fl u Ar unit=0A= +.Cm foreign display Op Ar config=0A= +.Nm=0A= +.Op Fl u Ar unit=0A= +.Cm foreign preview Op Ar config=0A= +.Nm=0A= +.Op Fl u Ar unit=0A= +.Cm foreign import Op Ar config=0A= +.Nm=0A= +.Op Fl u Ar unit=0A= .Cm flash Ar file=0A= .Sh DESCRIPTION=0A= The=0A= @@ -561,6 +579,37 @@=0A= Start a patrol read operation.=0A= .It Cm stop patrol=0A= Stop a currently running patrol read operation.=0A= +.It Cm foreign scan=0A= +Scan for foreign configurations and display the number found. The=0A= +.Ar config=0A= +argument for the commands below takes the form of a number from 0 to = the total=0A= +configurations found.=0A= +.It Cm foreign drives=0A= +Scan for drives flagged as foreign and display them.=0A= +.It Cm foreign clear Op config=0A= +Clear the specifed foreign=0A= +.Ar config=0A= +or all if no=0A= +.Ar config=0A= +argument is provided.=0A= +.It Cm foreign display Op config=0A= +Display the specifed foreign=0A= +.Ar config=0A= +or all if no=0A= +.Ar config=0A= +argument is provided.=0A= +.It Cm foreign preview Op config=0A= +Preview the specifed foreign=0A= +.Ar config=0A= +after import or all if no=0A= +.Ar config=0A= +argument is provided.=0A= +.It Cm foreign import Op config=0A= +Import the specifed foreign=0A= +.Ar config=0A= +or all if no=0A= +.Ar config=0A= +argument is provided.=0A= .It Cm flash Ar file=0A= Updates the flash on the controller with the firmware stored in=0A= .Ar file .=0A= --- usr.sbin/mfiutil/mfi_cmd.c.orig 2012-11-07 12:24:56.758910703 +0000=0A= +++ usr.sbin/mfiutil/mfi_cmd.c 2012-11-07 14:31:31.461399143 +0000=0A= @@ -284,7 +284,7 @@=0A= if (statusp !=3D NULL)=0A= *statusp =3D dcmd->header.cmd_status;=0A= else if (dcmd->header.cmd_status !=3D MFI_STAT_OK) {=0A= - warnx("Command failed: %s",=0A= + warnx("Command 0x%08x failed: %s", opcode,=0A= mfi_status(dcmd->header.cmd_status));=0A= errno =3D EIO;=0A= return (-1);=0A= --- usr.sbin/mfiutil/mfi_show.c.orig 2012-11-07 12:25:03.255363063 +0000=0A= +++ usr.sbin/mfiutil/mfi_show.c 2012-11-07 14:31:31.463398730 +0000=0A= @@ -40,9 +40,11 @@=0A= #include =0A= #include "mfiutil.h"=0A= =0A= +const char* foreign_state =3D " (FOREIGN)";=0A= +=0A= MFI_TABLE(top, show);=0A= =0A= -static void=0A= +void=0A= format_stripe(char *buf, size_t buflen, uint8_t stripe)=0A= {=0A= =0A= @@ -264,7 +266,7 @@=0A= }=0A= MFI_COMMAND(show, battery, show_battery);=0A= =0A= -static void=0A= +void=0A= print_ld(struct mfi_ld_info *info, int state_len)=0A= {=0A= struct mfi_ld_params *params =3D &info->ld_config.params;=0A= @@ -285,19 +287,24 @@=0A= mfi_ldstate(params->state));=0A= }=0A= =0A= -static void=0A= +void=0A= print_pd(struct mfi_pd_info *info, int state_len)=0A= {=0A= const char *s;=0A= - char buf[6];=0A= + char buf[256];=0A= =0A= humanize_number(buf, sizeof(buf), info->raw_size * 512, "",=0A= HN_AUTOSCALE, HN_B | HN_NOSPACE |HN_DECIMAL);=0A= printf("(%6s) ", buf);=0A= + if (info->state.ddf.v.pd_type.is_foreign) {=0A= + sprintf(buf, "%s%s", mfi_pdstate(info->fw_state), foreign_state);=0A= + s =3D buf;=0A= + } else=0A= + s =3D mfi_pdstate(info->fw_state);=0A= if (state_len > 0)=0A= - printf("%-*s", state_len, mfi_pdstate(info->fw_state));=0A= + printf("%-*s", state_len, s);=0A= else=0A= - printf("%s", mfi_pdstate(info->fw_state));=0A= + printf(s);=0A= s =3D mfi_pd_inq_string(info);=0A= if (s !=3D NULL)=0A= printf(" %s", s);=0A= @@ -533,6 +540,8 @@=0A= goto error;=0A= }=0A= len =3D strlen(mfi_pdstate(info.fw_state));=0A= + if (info.state.ddf.v.pd_type.is_foreign)=0A= + len +=3D strlen(foreign_state);=0A= if (len > state_len)=0A= state_len =3D len;=0A= }=0A= --- sys/dev/mfi/mfireg.h.orig 2012-11-07 12:21:50.437607341 +0000=0A= +++ sys/dev/mfi/mfireg.h 2012-11-07 14:31:31.466398669 +0000=0A= @@ -184,27 +184,31 @@=0A= MFI_CMD_STP=0A= } mfi_cmd_t;=0A= =0A= -/* Direct commands */=0A= +/*=0A= + * Direct commands=0A= + *=0A= + * NOTE: Keep mfi_op_codes in mfi_debug.c up to date when adding values=0A= + */=0A= typedef enum {=0A= MFI_DCMD_CTRL_GETINFO =3D 0x01010000,=0A= - MFI_DCMD_CTRL_MFI_HOST_MEM_ALLOC =3D0x0100e100,=0A= - MFI_DCMD_CTRL_MFC_DEFAULTS_GET =3D0x010e0201,=0A= - MFI_DCMD_CTRL_MFC_DEFAULTS_SET =3D0x010e0202,=0A= - MFI_DCMD_CTRL_FLUSHCACHE =3D 0x01101000,=0A= - MFI_DCMD_CTRL_SHUTDOWN =3D 0x01050000,=0A= MFI_DCMD_CTRL_EVENT_GETINFO =3D 0x01040100,=0A= MFI_DCMD_CTRL_EVENT_GET =3D 0x01040300,=0A= MFI_DCMD_CTRL_EVENT_WAIT =3D 0x01040500,=0A= + MFI_DCMD_CTRL_SHUTDOWN =3D 0x01050000,=0A= MFI_DCMD_PR_GET_STATUS =3D 0x01070100,=0A= MFI_DCMD_PR_GET_PROPERTIES =3D 0x01070200,=0A= MFI_DCMD_PR_SET_PROPERTIES =3D 0x01070300,=0A= MFI_DCMD_PR_START =3D 0x01070400,=0A= MFI_DCMD_PR_STOP =3D 0x01070500,=0A= MFI_DCMD_TIME_SECS_GET =3D 0x01080201,=0A= + MFI_DCMD_CTRL_MFI_HOST_MEM_ALLOC =3D0x0100e100,=0A= + MFI_DCMD_CTRL_MFC_DEFAULTS_GET =3D0x010e0201,=0A= + MFI_DCMD_CTRL_MFC_DEFAULTS_SET =3D0x010e0202,=0A= MFI_DCMD_FLASH_FW_OPEN =3D 0x010f0100,=0A= MFI_DCMD_FLASH_FW_DOWNLOAD =3D 0x010f0200,=0A= MFI_DCMD_FLASH_FW_FLASH =3D 0x010f0300,=0A= MFI_DCMD_FLASH_FW_CLOSE =3D 0x010f0400,=0A= + MFI_DCMD_CTRL_FLUSHCACHE =3D 0x01101000,=0A= MFI_DCMD_PD_GET_LIST =3D 0x02010000,=0A= MFI_DCMD_PD_LIST_QUERY =3D 0x02010100,=0A= MFI_DCMD_PD_GET_INFO =3D 0x02020000,=0A= @@ -229,7 +233,11 @@=0A= MFI_DCMD_CFG_CLEAR =3D 0x04030000,=0A= MFI_DCMD_CFG_MAKE_SPARE =3D 0x04040000,=0A= MFI_DCMD_CFG_REMOVE_SPARE =3D 0x04050000,=0A= + MFI_DCMD_CFG_FOREIGN_SCAN =3D 0x04060100,=0A= + MFI_DCMD_CFG_FOREIGN_DISPLAY =3D 0x04060200,=0A= + MFI_DCMD_CFG_FOREIGN_PREVIEW =3D 0x04060300,=0A= MFI_DCMD_CFG_FOREIGN_IMPORT =3D 0x04060400,=0A= + MFI_DCMD_CFG_FOREIGN_CLEAR =3D 0x04060500,=0A= MFI_DCMD_BBU_GET_STATUS =3D 0x05010000,=0A= MFI_DCMD_BBU_GET_CAPACITY_INFO =3D0x05020000,=0A= MFI_DCMD_BBU_GET_DESIGN_INFO =3D 0x05030000,=0A= --- sys/dev/mfi/mfivar.h.orig 2012-11-07 12:44:51.712248722 +0000=0A= +++ sys/dev/mfi/mfivar.h 2012-11-07 14:31:31.467398742 +0000=0A= @@ -589,6 +589,7 @@=0A= extern void mfi_print_cmd(struct mfi_command *cm);=0A= extern void mfi_dump_cmds(struct mfi_softc *sc);=0A= extern void mfi_validate_sg(struct mfi_softc *, struct mfi_command *, = const char *, int );=0A= +extern const char * mfi_op_desc(uint32_t opcode);=0A= #define MFI_PRINT_CMD(cm) mfi_print_cmd(cm)=0A= #define MFI_DUMP_CMDS(sc) mfi_dump_cmds(sc)=0A= #define MFI_VALIDATE_CMD(sc, cm) mfi_validate_sg(sc, cm, __FUNCTION__, = __LINE__)=0A= --- sys/dev/mfi/mfi_debug.c.orig 2012-11-07 12:21:44.533103108 +0000=0A= +++ sys/dev/mfi/mfi_debug.c 2012-11-07 14:31:31.465398876 +0000=0A= @@ -54,6 +54,88 @@=0A= #include =0A= #include =0A= =0A= +struct mfi_op_table_entry {=0A= + uint32_t opcode;=0A= + const char *desc;=0A= +};=0A= +=0A= +/* Keep in sync with mfi_dcmd_t in mfireg.h */=0A= +static struct mfi_op_table_entry mfi_op_codes[] =3D {=0A= + { MFI_DCMD_CTRL_GETINFO, "MFI_DCMD_CTRL_GETINFO" },=0A= + { MFI_DCMD_CTRL_MFI_HOST_MEM_ALLOC, "MFI_DCMD_CTRL_MFI_HOST_MEM_ALLOC" = },=0A= + { MFI_DCMD_CTRL_EVENT_GETINFO, "MFI_DCMD_CTRL_EVENT_GETINFO" },=0A= + { MFI_DCMD_CTRL_EVENT_GET, "MFI_DCMD_CTRL_EVENT_GET" },=0A= + { MFI_DCMD_CTRL_EVENT_WAIT, "MFI_DCMD_CTRL_EVENT_WAIT" },=0A= + { MFI_DCMD_CTRL_SHUTDOWN, "MFI_DCMD_CTRL_SHUTDOWN" },=0A= + { MFI_DCMD_PR_GET_STATUS, "MFI_DCMD_PR_GET_STATUS" },=0A= + { MFI_DCMD_PR_GET_PROPERTIES, "MFI_DCMD_PR_GET_PROPERTIES" },=0A= + { MFI_DCMD_PR_SET_PROPERTIES, "MFI_DCMD_PR_SET_PROPERTIES" },=0A= + { MFI_DCMD_PR_START, "MFI_DCMD_PR_START" },=0A= + { MFI_DCMD_PR_STOP, "MFI_DCMD_PR_STOP" },=0A= + { MFI_DCMD_TIME_SECS_GET, "MFI_DCMD_TIME_SECS_GET" },=0A= + { MFI_DCMD_CTRL_MFC_DEFAULTS_GET, "MFI_DCMD_CTRL_MFC_DEFAULTS_GET" },=0A= + { MFI_DCMD_CTRL_MFC_DEFAULTS_SET, "MFI_DCMD_CTRL_MFC_DEFAULTS_SET" },=0A= + { MFI_DCMD_FLASH_FW_OPEN, "MFI_DCMD_FLASH_FW_OPEN" },=0A= + { MFI_DCMD_FLASH_FW_DOWNLOAD, "MFI_DCMD_FLASH_FW_DOWNLOAD" },=0A= + { MFI_DCMD_FLASH_FW_FLASH, "MFI_DCMD_FLASH_FW_FLASH" },=0A= + { MFI_DCMD_FLASH_FW_CLOSE, "MFI_DCMD_FLASH_FW_CLOSE" },=0A= + { MFI_DCMD_CTRL_FLUSHCACHE, "MFI_DCMD_CTRL_FLUSHCACHE" },=0A= + { MFI_DCMD_PD_GET_LIST, "MFI_DCMD_PD_GET_LIST" },=0A= + { MFI_DCMD_PD_LIST_QUERY, "MFI_DCMD_PD_LIST_QUERY" },=0A= + { MFI_DCMD_PD_GET_INFO, "MFI_DCMD_PD_GET_INFO" },=0A= + { MFI_DCMD_PD_STATE_SET, "MFI_DCMD_PD_STATE_SET" },=0A= + { MFI_DCMD_PD_REBUILD_START, "MFI_DCMD_PD_REBUILD_START" },=0A= + { MFI_DCMD_PD_REBUILD_ABORT, "MFI_DCMD_PD_REBUILD_ABORT" },=0A= + { MFI_DCMD_PD_CLEAR_START, "MFI_DCMD_PD_CLEAR_START" },=0A= + { MFI_DCMD_PD_CLEAR_ABORT, "MFI_DCMD_PD_CLEAR_ABORT" },=0A= + { MFI_DCMD_PD_GET_PROGRESS, "MFI_DCMD_PD_GET_PROGRESS" },=0A= + { MFI_DCMD_PD_LOCATE_START, "MFI_DCMD_PD_LOCATE_START" },=0A= + { MFI_DCMD_PD_LOCATE_STOP, "MFI_DCMD_PD_LOCATE_STOP" },=0A= + { MFI_DCMD_LD_MAP_GET_INFO, "MFI_DCMD_LD_MAP_GET_INFO" },=0A= + { MFI_DCMD_LD_SYNC, "MFI_DCMD_LD_SYNC" },=0A= + { MFI_DCMD_LD_GET_LIST, "MFI_DCMD_LD_GET_LIST" },=0A= + { MFI_DCMD_LD_GET_INFO, "MFI_DCMD_LD_GET_INFO" },=0A= + { MFI_DCMD_LD_GET_PROP, "MFI_DCMD_LD_GET_PROP" },=0A= + { MFI_DCMD_LD_SET_PROP, "MFI_DCMD_LD_SET_PROP" },=0A= + { MFI_DCMD_LD_INIT_START, "MFI_DCMD_LD_INIT_START" },=0A= + { MFI_DCMD_LD_DELETE, "MFI_DCMD_LD_DELETE" },=0A= + { MFI_DCMD_CFG_READ, "MFI_DCMD_CFG_READ" },=0A= + { MFI_DCMD_CFG_ADD, "MFI_DCMD_CFG_ADD" },=0A= + { MFI_DCMD_CFG_CLEAR, "MFI_DCMD_CFG_CLEAR" },=0A= + { MFI_DCMD_CFG_MAKE_SPARE, "MFI_DCMD_CFG_MAKE_SPARE" },=0A= + { MFI_DCMD_CFG_REMOVE_SPARE, "MFI_DCMD_CFG_REMOVE_SPARE" },=0A= + { MFI_DCMD_CFG_FOREIGN_SCAN, "MFI_DCMD_CFG_FOREIGN_SCAN" },=0A= + { MFI_DCMD_CFG_FOREIGN_DISPLAY, "MFI_DCMD_CFG_FOREIGN_DISPLAY" },=0A= + { MFI_DCMD_CFG_FOREIGN_PREVIEW, "MFI_DCMD_CFG_FOREIGN_PREVIEW" },=0A= + { MFI_DCMD_CFG_FOREIGN_IMPORT, "MFI_DCMD_CFG_FOREIGN_IMPORT" },=0A= + { MFI_DCMD_CFG_FOREIGN_CLEAR, "MFI_DCMD_CFG_FOREIGN_CLEAR" },=0A= + { MFI_DCMD_BBU_GET_STATUS, "MFI_DCMD_BBU_GET_STATUS" },=0A= + { MFI_DCMD_BBU_GET_CAPACITY_INFO, "MFI_DCMD_BBU_GET_CAPACITY_INFO" },=0A= + { MFI_DCMD_BBU_GET_DESIGN_INFO, "MFI_DCMD_BBU_GET_DESIGN_INFO" },=0A= + { MFI_DCMD_CLUSTER, "MFI_DCMD_CLUSTER" },=0A= + { MFI_DCMD_CLUSTER_RESET_ALL, "MFI_DCMD_CLUSTER_RESET_ALL" },=0A= + { MFI_DCMD_CLUSTER_RESET_LD, "MFI_DCMD_CLUSTER_RESET_LD" }=0A= +};=0A= +=0A= +static void=0A= +mfi_dump_bytes(const char *prefix, unsigned char *p, int len)=0A= +{=0A= + int i, c =3D 1, j =3D 0;=0A= +=0A= + if (prefix)=0A= + printf("%s: ", prefix);=0A= + printf("[%d]\ndata[%d] ", len, j);=0A= + for (i =3D 0; i < len; ++i) {=0A= + printf(" %02x", p[i]);=0A= + c++;=0A= + if ( 32 =3D=3D c ) {=0A= + printf("\ndata[%d] ", j++);=0A= + c =3D 1;=0A= + }=0A= + }=0A= + printf("\n");=0A= +}=0A= +=0A= static void=0A= mfi_print_frame_flags(device_t dev, uint32_t flags)=0A= {=0A= @@ -127,64 +209,16 @@=0A= {=0A= struct mfi_dcmd_frame *dcmd;=0A= struct mfi_frame_header *hdr;=0A= - const char *opcode;=0A= =0A= dcmd =3D &cm->cm_frame->dcmd;=0A= hdr =3D &dcmd->header;=0A= =0A= - switch (dcmd->opcode) {=0A= - case MFI_DCMD_CTRL_GETINFO:=0A= - opcode =3D "CTRL_GETINFO";=0A= - break;=0A= - case MFI_DCMD_CTRL_FLUSHCACHE:=0A= - opcode =3D "CTRL_FLUSHCACHE";=0A= - break;=0A= - case MFI_DCMD_CTRL_SHUTDOWN:=0A= - opcode =3D "CTRL_SHUTDOWN";=0A= - break;=0A= - case MFI_DCMD_CTRL_EVENT_GETINFO:=0A= - opcode =3D "EVENT_GETINFO";=0A= - break;=0A= - case MFI_DCMD_CTRL_EVENT_GET:=0A= - opcode =3D "EVENT_GET";=0A= - break;=0A= - case MFI_DCMD_CTRL_EVENT_WAIT:=0A= - opcode =3D "EVENT_WAIT";=0A= - break;=0A= - case MFI_DCMD_LD_GET_LIST:=0A= - opcode =3D "LD_GET_LIST";=0A= - break;=0A= - case MFI_DCMD_LD_GET_INFO:=0A= - opcode =3D "LD_GET_INFO";=0A= - break;=0A= - case MFI_DCMD_LD_GET_PROP:=0A= - opcode =3D "LD_GET_PROP";=0A= - break;=0A= - case MFI_DCMD_LD_SET_PROP:=0A= - opcode =3D "LD_SET_PROP";=0A= - break;=0A= - case MFI_DCMD_CLUSTER:=0A= - opcode =3D "CLUSTER";=0A= - break;=0A= - case MFI_DCMD_CLUSTER_RESET_ALL:=0A= - opcode =3D "CLUSTER_RESET_ALL";=0A= - break;=0A= - case MFI_DCMD_CLUSTER_RESET_LD:=0A= - opcode =3D "CLUSTER_RESET_LD";=0A= - break;=0A= - case MFI_DCMD_LD_MAP_GET_INFO:=0A= - opcode =3D "LD_MAP_GET_INFO";=0A= - break;=0A= - default:=0A= - opcode =3D "UNKNOWN";=0A= - break;=0A= - }=0A= -=0A= - device_printf(dev, "cmd=3DMFI_CMD_DCMD opcode=3D%s data_len=3D%d\n",=0A= - opcode, hdr->data_len);=0A= + device_printf(dev, "cmd=3DMFI_CMD_DCMD opcode=3D%s (0x%08x) = data_len=3D%d\n",=0A= + mfi_op_desc(dcmd->opcode), dcmd->opcode, hdr->data_len);=0A= mfi_print_frame_flags(dev, hdr->flags);=0A= mfi_print_sgl(hdr, &dcmd->sgl, hdr->sg_count);=0A= -=0A= + if (NULL !=3D dcmd->mbox)=0A= + mfi_dump_bytes("dcmd->mbox", dcmd->mbox, MFI_MBOX_SIZE);=0A= }=0A= =0A= static void=0A= @@ -278,4 +312,19 @@=0A= }=0A= }=0A= =0A= +const char *=0A= +mfi_op_desc(uint32_t opcode)=0A= +{=0A= + int i;=0A= + int num_ops =3D sizeof(mfi_op_codes)/sizeof(mfi_op_codes[0]);=0A= + for (i =3D 0; i < num_ops; i++) {=0A= + if (mfi_op_codes[i].opcode =3D=3D opcode)=0A= + return(mfi_op_codes[i].desc);=0A= + else if (mfi_op_codes[i].opcode > opcode)=0A= + break;=0A= + }=0A= +=0A= + return ("UNKNOWN");=0A= +}=0A= +=0A= #endif=0A= --- sys/dev/mfi/mfi.c.orig 2012-11-07 12:49:16.123978018 +0000=0A= +++ sys/dev/mfi/mfi.c 2012-11-07 14:40:33.960774577 +0000=0A= @@ -150,6 +150,11 @@=0A= SYSCTL_INT(_hw_mfi, OID_AUTO, detect_jbod_change, CTLFLAG_RW,=0A= &mfi_detect_jbod_change, 0, "Detect a change to a JBOD");=0A= =0A= +static int mfi_cmd_timeout =3D MFI_CMD_TIMEOUT;=0A= +TUNABLE_INT("hw.mfi.cmd_timeout", &mfi_cmd_timeout);=0A= +SYSCTL_INT(_hw_mfi, OID_AUTO, cmd_timeout, CTLFLAG_RW, &mfi_cmd_timeout,=0A= + 0, "Command timeout (in seconds)");=0A= +=0A= /* Management interface */=0A= static d_open_t mfi_open;=0A= static d_close_t mfi_close;=0A= @@ -762,7 +767,7 @@=0A= =0A= /* Start the timeout watchdog */=0A= callout_init(&sc->mfi_watchdog_callout, CALLOUT_MPSAFE);=0A= - callout_reset(&sc->mfi_watchdog_callout, MFI_CMD_TIMEOUT * hz,=0A= + callout_reset(&sc->mfi_watchdog_callout, mfi_cmd_timeout * hz,=0A= mfi_timeout, sc);=0A= =0A= if (sc->mfi_flags & MFI_FLAGS_TBOLT) {=0A= @@ -899,6 +904,7 @@=0A= cm->cm_data =3D buf;=0A= cm->cm_private =3D buf;=0A= cm->cm_len =3D bufsize;=0A= + MFI_PRINT_CMD(cm);=0A= =0A= *cmp =3D cm;=0A= if ((bufp !=3D NULL) && (*bufp =3D=3D NULL) && (buf !=3D NULL))=0A= @@ -2673,6 +2679,7 @@=0A= =0A= mtx_assert(&sc->mfi_io_lock, MA_OWNED);=0A= error =3D 0;=0A= + MFI_PRINT_CMD(cm);=0A= switch (cm->cm_frame->dcmd.opcode) {=0A= case MFI_DCMD_LD_DELETE:=0A= TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) {=0A= @@ -2727,6 +2734,7 @@=0A= uint16_t syspd_id;=0A= uint16_t *mbox;=0A= =0A= + MFI_PRINT_CMD(cm);=0A= switch (cm->cm_frame->dcmd.opcode) {=0A= case MFI_DCMD_LD_DELETE:=0A= TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) {=0A= @@ -2758,9 +2766,8 @@=0A= }=0A= break;=0A= case MFI_DCMD_CFG_ADD:=0A= - mfi_ldprobe(sc);=0A= - break;=0A= case MFI_DCMD_CFG_FOREIGN_IMPORT:=0A= + if (cm->cm_frame->header.cmd_status =3D=3D MFI_STAT_OK)=0A= mfi_ldprobe(sc);=0A= break;=0A= case MFI_DCMD_PD_STATE_SET:=0A= @@ -3624,7 +3631,7 @@=0A= break;=0A= device_printf(sc->mfi_dev, "Dumping\n\n");=0A= timedout =3D 0;=0A= - deadline =3D time_uptime - MFI_CMD_TIMEOUT;=0A= + deadline =3D time_uptime - mfi_cmd_timeout;=0A= mtx_lock(&sc->mfi_io_lock);=0A= TAILQ_FOREACH(cm, &sc->mfi_busy, cm_link) {=0A= if (cm->cm_timestamp < deadline) {=0A= @@ -3655,10 +3662,11 @@=0A= time_t deadline;=0A= int timedout =3D 0;=0A= =0A= - deadline =3D time_uptime - MFI_CMD_TIMEOUT;=0A= + deadline =3D time_uptime - mfi_cmd_timeout;=0A= if (sc->adpreset =3D=3D 0) {=0A= if (!mfi_tbolt_reset(sc)) {=0A= - callout_reset(&sc->mfi_watchdog_callout, MFI_CMD_TIMEOUT * hz, = mfi_timeout, sc);=0A= + callout_reset(&sc->mfi_watchdog_callout,=0A= + mfi_cmd_timeout * hz, mfi_timeout, sc);=0A= return;=0A= }=0A= }=0A= @@ -3688,7 +3696,7 @@=0A= =0A= mtx_unlock(&sc->mfi_io_lock);=0A= =0A= - callout_reset(&sc->mfi_watchdog_callout, MFI_CMD_TIMEOUT * hz,=0A= + callout_reset(&sc->mfi_watchdog_callout, mfi_cmd_timeout * hz,=0A= mfi_timeout, sc);=0A= =0A= if (0)=0A= ------=_NextPart_000_02FD_01CE0D39.88DA2DE0--