summaryrefslogtreecommitdiffstats
path: root/sys/dev/mps/mps_user.c
diff options
context:
space:
mode:
authormdf <mdf@FreeBSD.org>2010-10-14 16:44:44 +0000
committermdf <mdf@FreeBSD.org>2010-10-14 16:44:44 +0000
commit212f93db801894a21eb12a1857f17d2824021b47 (patch)
tree9434a615ab6881756410b5d969677a8d61ef6856 /sys/dev/mps/mps_user.c
parentc3e059acee4dcdaa1d1d01608e2ffe3b56c8a3e5 (diff)
downloadFreeBSD-src-212f93db801894a21eb12a1857f17d2824021b47.zip
FreeBSD-src-212f93db801894a21eb12a1857f17d2824021b47.tar.gz
Support firmware download.
Diffstat (limited to 'sys/dev/mps/mps_user.c')
-rw-r--r--sys/dev/mps/mps_user.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/sys/dev/mps/mps_user.c b/sys/dev/mps/mps_user.c
index b6621e3..9d9cf9e 100644
--- a/sys/dev/mps/mps_user.c
+++ b/sys/dev/mps/mps_user.c
@@ -383,14 +383,50 @@ mpi_pre_fw_download(struct mps_command *cm, struct mps_usr_command *cmd)
{
MPI2_FW_DOWNLOAD_REQUEST *req = (void *)cm->cm_req;
MPI2_FW_DOWNLOAD_REPLY *rpl;
+ MPI2_FW_DOWNLOAD_TCSGE tc;
+ int error;
+
+ /*
+ * This code assumes there is room in the request's SGL for
+ * the TransactionContext plus at least a SGL chain element.
+ */
+ CTASSERT(sizeof req->SGL >= sizeof tc + MPS_SGC_SIZE);
if (cmd->req_len != sizeof *req)
return (EINVAL);
if (cmd->rpl_len != sizeof *rpl)
return (EINVAL);
+ if (cmd->len == 0)
+ return (EINVAL);
+
+ error = copyin(cmd->buf, cm->cm_data, cmd->len);
+ if (error != 0)
+ return (error);
+
mpi_init_sge(cm, req, &req->SGL);
- return (0);
+ bzero(&tc, sizeof tc);
+
+ /*
+ * For now, the F/W image must be provided in a single request.
+ */
+ if ((req->MsgFlags & MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT) == 0)
+ return (EINVAL);
+ if (req->TotalImageSize != cmd->len)
+ return (EINVAL);
+
+ /*
+ * The value of the first two elements is specified in the
+ * Fusion-MPT Message Passing Interface document.
+ */
+ tc.ContextSize = 0;
+ tc.DetailsLength = 12;
+ tc.ImageOffset = 0;
+ tc.ImageSize = cmd->len;
+
+ cm->cm_flags |= MPS_CM_FLAGS_DATAOUT;
+
+ return (mps_push_sge(cm, &tc, sizeof tc, 0));
}
/*
OpenPOWER on IntegriCloud