Index: usr.sbin/mpsutil/Makefile =================================================================== --- usr.sbin/mpsutil/Makefile +++ usr.sbin/mpsutil/Makefile @@ -1,7 +1,7 @@ # $FreeBSD$ PROG= mpsutil -SRCS= mpsutil.c mps_cmd.c mps_show.c +SRCS= mpsutil.c mps_cmd.c mps_show.c mps_flash.c MAN= mpsutil.8 WARNS?= 3 @@ -10,7 +10,7 @@ LINKS= ${BINDIR}/mpsutil ${BINDIR}/mprutil MLINKS= mpsutil.8 mprutil.8 -CFLAGS+= -I${.CURDIR}/../../sys -I. -DUSE_MPT_IOCTLS +CFLAGS+= -I${.CURDIR}/../../sys -I. -DUSE_MPT_IOCTLS -g # Here be dragons Index: usr.sbin/mpsutil/mps_cmd.c =================================================================== --- usr.sbin/mpsutil/mps_cmd.c +++ usr.sbin/mpsutil/mps_cmd.c @@ -1,4 +1,6 @@ /*- + * Copyright (c) 2015 Baptiste Daroussin + * * Copyright (c) 2015 Netflix, Inc. * All rights reserved. * Written by: Scott Long @@ -442,6 +444,62 @@ return (buf); } +int +mps_firmware_send(int fd, unsigned char *fw, uint32_t len, bool bios) +{ + MPI2_FW_DOWNLOAD_REQUEST req; + MPI2_FW_DOWNLOAD_REPLY reply; + + bzero(&req, sizeof(req)); + bzero(&reply, sizeof(reply)); + req.Function = MPI2_FUNCTION_FW_DOWNLOAD; + req.ImageType = bios ? MPI2_FW_DOWNLOAD_ITYPE_BIOS : MPI2_FW_DOWNLOAD_ITYPE_FW; + req.TotalImageSize = len; + req.MsgFlags = MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT; + + if (mps_user_command(fd, &req, sizeof(req), &reply, sizeof(reply), + fw, len, 0)) { + return (-1); + } + return (0); +} + +int +mps_firmware_get(int fd, unsigned char **firmware, bool bios) +{ + MPI2_FW_UPLOAD_REQUEST req; + MPI2_FW_UPLOAD_REPLY reply; + int size; + + *firmware = NULL; + bzero(&req, sizeof(req)); + bzero(&reply, sizeof(reply)); + req.Function = MPI2_FUNCTION_FW_UPLOAD; + req.ImageType = bios ? MPI2_FW_DOWNLOAD_ITYPE_BIOS : MPI2_FW_DOWNLOAD_ITYPE_FW; + + if (mps_user_command(fd, &req, sizeof(req), &reply, sizeof(reply), + NULL, 0, 0)) { + return (-1); + } + if (reply.ActualImageSize == 0) { + return (-1); + } + + size = reply.ActualImageSize; + *firmware = calloc(1, sizeof(char) * size); + if (*firmware == NULL) { + warn("calloc"); + return (-1); + } + if (mps_user_command(fd, &req, sizeof(req), &reply, sizeof(reply), + *firmware, size, 0)) { + free(*firmware); + return (-1); + } + + return (size); +} + #else int Index: usr.sbin/mpsutil/mpsutil.h =================================================================== --- usr.sbin/mpsutil/mpsutil.h +++ usr.sbin/mpsutil/mpsutil.h @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -122,6 +123,8 @@ int mps_map_btdh(int fd, uint16_t *devhandle, uint16_t *bus, uint16_t *target); const char *mps_ioc_status(U16 IOCStatus); +int mps_firmware_send(int fd, unsigned char *buf, uint32_t len, bool bios); +int mps_firmware_get(int fd, unsigned char **buf, bool bios); static __inline void * mps_read_man_page(int fd, U8 PageNumber, U16 *IOCStatus) Index: usr.sbin/mpsutil/mpsutil.8 =================================================================== --- usr.sbin/mpsutil/mpsutil.8 +++ usr.sbin/mpsutil/mpsutil.8 @@ -60,6 +60,16 @@ .Nm .Op Fl u Ar unit .Cm show iocfacts +.Nm +.Op Fl u Ar unit +.Cm flash upload +.Op Ar firmware Ns | Ns Ar bios +.Op Ar file +.Nm +.Op Fl u Ar unit +.Cm flash download +.Op Ar firmware Ns | Ns Ar bios +.Ar file .Sh DESCRIPTION The .Nm @@ -94,7 +104,9 @@ .Pp The .Nm -utility currently only supports informational commands. +utility supports several different groups of commands. The first group of +commands provide information about the controller. The second group of commands +are used to manager controller-wide operations. .Pp The informational commands include: .Bl -tag -width indent @@ -119,8 +131,14 @@ .It Cm show cfgpage page Oo Ar num Oc Op Ar addr Show IOC Facts Message .El +.Pp +The controller management commands include: +.Bl -tag -width indent +.It Cm flash upload Oo Ar firmware Ns | Ns Ar bios Oc Op Ar file +.It Cm flash download Oo Ar firmware Ns | Ns Ar bios Oc Ar file +.El .Sh SEE ALSO -.Xr mpr 4 +.Xr mpr 4 , .Xr mps 4 .Sh HISTORY The