1c2a13d6fSAndriy Gapon /*-
2c2a13d6fSAndriy Gapon * SPDX-License-Identifier: BSD-2-Clause
3c2a13d6fSAndriy Gapon *
4c2a13d6fSAndriy Gapon * Copyright (c) 2019 Andriy Gapon <avg@FreeBSD.org>
5c2a13d6fSAndriy Gapon *
6c2a13d6fSAndriy Gapon * Redistribution and use in source and binary forms, with or without
7c2a13d6fSAndriy Gapon * modification, are permitted provided that the following conditions
8c2a13d6fSAndriy Gapon * are met:
9c2a13d6fSAndriy Gapon * 1. Redistributions of source code must retain the above copyright
10c2a13d6fSAndriy Gapon * notice, this list of conditions and the following disclaimer.
11c2a13d6fSAndriy Gapon * 2. Redistributions in binary form must reproduce the above copyright
12c2a13d6fSAndriy Gapon * notice, this list of conditions and the following disclaimer in the
13c2a13d6fSAndriy Gapon * documentation and/or other materials provided with the distribution.
14c2a13d6fSAndriy Gapon *
15c2a13d6fSAndriy Gapon * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16c2a13d6fSAndriy Gapon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17c2a13d6fSAndriy Gapon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18c2a13d6fSAndriy Gapon * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19c2a13d6fSAndriy Gapon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20c2a13d6fSAndriy Gapon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21c2a13d6fSAndriy Gapon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22c2a13d6fSAndriy Gapon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23c2a13d6fSAndriy Gapon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24c2a13d6fSAndriy Gapon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25c2a13d6fSAndriy Gapon * SUCH DAMAGE.
26c2a13d6fSAndriy Gapon */
27c2a13d6fSAndriy Gapon
28c2a13d6fSAndriy Gapon #include <sys/cdefs.h>
29c2a13d6fSAndriy Gapon #include <sys/stat.h>
30c2a13d6fSAndriy Gapon #include <sys/param.h>
31c2a13d6fSAndriy Gapon #include <sys/mman.h>
32fc9780fdSAlfredo Dal'Ava Junior #include <sys/endian.h>
33c2a13d6fSAndriy Gapon
34c2a13d6fSAndriy Gapon #include <errno.h>
35c2a13d6fSAndriy Gapon #include <err.h>
36c2a13d6fSAndriy Gapon #include <fcntl.h>
37c2a13d6fSAndriy Gapon #include <stdint.h>
38c2a13d6fSAndriy Gapon #include <stdio.h>
39c2a13d6fSAndriy Gapon #include <stdlib.h>
40c2a13d6fSAndriy Gapon #include <string.h>
41c2a13d6fSAndriy Gapon #include <unistd.h>
42c2a13d6fSAndriy Gapon
43c2a13d6fSAndriy Gapon #include "mpsutil.h"
44c2a13d6fSAndriy Gapon
45c2a13d6fSAndriy Gapon MPS_TABLE(top, slot);
46c2a13d6fSAndriy Gapon
47c2a13d6fSAndriy Gapon static int
slot_set(int argc,char ** argv)48c2a13d6fSAndriy Gapon slot_set(int argc, char **argv)
49c2a13d6fSAndriy Gapon {
50c2a13d6fSAndriy Gapon char *endptr;
51c2a13d6fSAndriy Gapon unsigned long ux;
52c2a13d6fSAndriy Gapon long x;
53c2a13d6fSAndriy Gapon int error;
54c2a13d6fSAndriy Gapon int fd;
55c2a13d6fSAndriy Gapon U32 status;
56c2a13d6fSAndriy Gapon U16 handle;
57c2a13d6fSAndriy Gapon U16 slot;
58c2a13d6fSAndriy Gapon
59c2a13d6fSAndriy Gapon if (argc != 5) {
60c2a13d6fSAndriy Gapon warnx("Incorrect number of arguments");
61c2a13d6fSAndriy Gapon return (EINVAL);
62c2a13d6fSAndriy Gapon }
63c2a13d6fSAndriy Gapon
64c2a13d6fSAndriy Gapon if (strcmp(argv[1], "status") != 0) {
65c2a13d6fSAndriy Gapon warnx("Invalid argument '%s', expecting 'status'",
66c2a13d6fSAndriy Gapon argv[1]);
67c2a13d6fSAndriy Gapon return (EINVAL);
68c2a13d6fSAndriy Gapon }
69c2a13d6fSAndriy Gapon
70c2a13d6fSAndriy Gapon errno = 0;
71c2a13d6fSAndriy Gapon x = strtol(argv[2], &endptr, 0);
72c2a13d6fSAndriy Gapon if (*endptr != '\0' || errno != 0 || x < 0 || x > UINT16_MAX) {
73c2a13d6fSAndriy Gapon warnx("Invalid enclosure handle argument '%s'", argv[2]);
74c2a13d6fSAndriy Gapon return (EINVAL);
75c2a13d6fSAndriy Gapon }
76c2a13d6fSAndriy Gapon handle = x;
77c2a13d6fSAndriy Gapon
78c2a13d6fSAndriy Gapon errno = 0;
79c2a13d6fSAndriy Gapon x = strtol(argv[3], &endptr, 0);
80c2a13d6fSAndriy Gapon if (*endptr != '\0' || errno != 0 || x < 0 || x > UINT16_MAX) {
81c2a13d6fSAndriy Gapon warnx("Invalid slot argument '%s'", argv[3]);
82c2a13d6fSAndriy Gapon return (EINVAL);
83c2a13d6fSAndriy Gapon }
84c2a13d6fSAndriy Gapon slot = x;
85c2a13d6fSAndriy Gapon
86c2a13d6fSAndriy Gapon errno = 0;
87c2a13d6fSAndriy Gapon ux = strtoul(argv[4], &endptr, 0);
88c2a13d6fSAndriy Gapon if (*endptr != '\0' || errno != 0 || ux > UINT32_MAX) {
89c2a13d6fSAndriy Gapon warnx("Invalid status argument '%s'", argv[4]);
90c2a13d6fSAndriy Gapon return (EINVAL);
91c2a13d6fSAndriy Gapon }
92c2a13d6fSAndriy Gapon status = ux;
93c2a13d6fSAndriy Gapon
94c2a13d6fSAndriy Gapon fd = mps_open(mps_unit);
95c2a13d6fSAndriy Gapon if (fd < 0) {
96c2a13d6fSAndriy Gapon error = errno;
97c2a13d6fSAndriy Gapon warn("mps_open");
98c2a13d6fSAndriy Gapon return (error);
99c2a13d6fSAndriy Gapon }
100c2a13d6fSAndriy Gapon
101fc9780fdSAlfredo Dal'Ava Junior if (mps_set_slot_status(fd, htole16(handle), htole16(slot),
102fc9780fdSAlfredo Dal'Ava Junior htole32(status)) != 0) {
103c2a13d6fSAndriy Gapon warnx("Failed to set status");
104c2a13d6fSAndriy Gapon close(fd);
105c2a13d6fSAndriy Gapon return (1);
106c2a13d6fSAndriy Gapon }
107c2a13d6fSAndriy Gapon
108c2a13d6fSAndriy Gapon close(fd);
109c2a13d6fSAndriy Gapon printf("Successfully set slot status\n");
110c2a13d6fSAndriy Gapon return (0);
111c2a13d6fSAndriy Gapon }
112c2a13d6fSAndriy Gapon
113c2a13d6fSAndriy Gapon MPS_COMMAND(slot, set, slot_set, "status <enclosure handle> <slot number> "
114*638e2a13SScott Long "<status>", "\n Set status of the slot in the directly attached enclosure");
115