mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	powerpc/selftests: Add test for papr-vpd
Add selftests for /dev/papr-vpd, exercising the common expected use cases: * Retrieve all VPD by passing an empty location code. * Retrieve the "system VPD" by passing a location code derived from DT root node properties, as done by the vpdupdate command. The tests also verify that certain intended properties of the driver hold: * Passing an unterminated location code to PAPR_VPD_CREATE_HANDLE gets EINVAL. * Passing a NULL location code pointer to PAPR_VPD_CREATE_HANDLE gets EFAULT. * Closing the device node without first issuing a PAPR_VPD_CREATE_HANDLE command to it succeeds. * Releasing a handle without first consuming any data from it succeeds. * Re-reading the contents of a handle returns the same data as the first time. Some minimal validation of the returned data is performed. The tests are skipped on systems where the papr-vpd driver does not initialize, making this useful only on PowerVM LPARs at this point. Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://msgid.link/20231212-papr-sys_rtas-vs-lockdown-v6-12-e9eafd0c8c6c@linux.ibm.com
This commit is contained in:
		
							parent
							
								
									905b9e4878
								
							
						
					
					
						commit
						9118c5d32b
					
				
					 4 changed files with 366 additions and 0 deletions
				
			
		| 
						 | 
					@ -32,6 +32,7 @@ SUB_DIRS = alignment		\
 | 
				
			||||||
	   vphn         \
 | 
						   vphn         \
 | 
				
			||||||
	   math		\
 | 
						   math		\
 | 
				
			||||||
	   papr_attributes	\
 | 
						   papr_attributes	\
 | 
				
			||||||
 | 
						   papr_vpd		\
 | 
				
			||||||
	   ptrace	\
 | 
						   ptrace	\
 | 
				
			||||||
	   security	\
 | 
						   security	\
 | 
				
			||||||
	   mce
 | 
						   mce
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								tools/testing/selftests/powerpc/papr_vpd/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tools/testing/selftests/powerpc/papr_vpd/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					/papr_vpd
 | 
				
			||||||
							
								
								
									
										12
									
								
								tools/testing/selftests/powerpc/papr_vpd/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								tools/testing/selftests/powerpc/papr_vpd/Makefile
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					# SPDX-License-Identifier: GPL-2.0
 | 
				
			||||||
 | 
					noarg:
 | 
				
			||||||
 | 
						$(MAKE) -C ../
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST_GEN_PROGS := papr_vpd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					top_srcdir = ../../../../..
 | 
				
			||||||
 | 
					include ../../lib.mk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$(TEST_GEN_PROGS): ../harness.c ../utils.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$(OUTPUT)/papr_vpd: CFLAGS += $(KHDR_INCLUDES)
 | 
				
			||||||
							
								
								
									
										352
									
								
								tools/testing/selftests/powerpc/papr_vpd/papr_vpd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										352
									
								
								tools/testing/selftests/powerpc/papr_vpd/papr_vpd.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,352 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-2.0-only
 | 
				
			||||||
 | 
					#define _GNU_SOURCE
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <sys/ioctl.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <asm/papr-vpd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEVPATH "/dev/papr-vpd"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dev_papr_vpd_open_close(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const int devfd = open(DEVPATH, O_RDONLY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
 | 
				
			||||||
 | 
							    DEVPATH " not present");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(devfd < 0);
 | 
				
			||||||
 | 
						FAIL_IF(close(devfd) != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dev_papr_vpd_get_handle_all(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const int devfd = open(DEVPATH, O_RDONLY);
 | 
				
			||||||
 | 
						struct papr_location_code lc = { .str = "", };
 | 
				
			||||||
 | 
						off_t size;
 | 
				
			||||||
 | 
						int fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
 | 
				
			||||||
 | 
							    DEVPATH " not present");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(devfd < 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						errno = 0;
 | 
				
			||||||
 | 
						fd = ioctl(devfd, PAPR_VPD_IOC_CREATE_HANDLE, &lc);
 | 
				
			||||||
 | 
						FAIL_IF(errno != 0);
 | 
				
			||||||
 | 
						FAIL_IF(fd < 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(close(devfd) != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size = lseek(fd, 0, SEEK_END);
 | 
				
			||||||
 | 
						FAIL_IF(size <= 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void *buf = malloc((size_t)size);
 | 
				
			||||||
 | 
						FAIL_IF(!buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ssize_t consumed = pread(fd, buf, size, 0);
 | 
				
			||||||
 | 
						FAIL_IF(consumed != size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Ensure EOF */
 | 
				
			||||||
 | 
						FAIL_IF(read(fd, buf, size) != 0);
 | 
				
			||||||
 | 
						FAIL_IF(close(fd));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Verify that the buffer looks like VPD */
 | 
				
			||||||
 | 
						static const char needle[] = "System VPD";
 | 
				
			||||||
 | 
						FAIL_IF(!memmem(buf, size, needle, strlen(needle)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dev_papr_vpd_get_handle_byte_at_a_time(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const int devfd = open(DEVPATH, O_RDONLY);
 | 
				
			||||||
 | 
						struct papr_location_code lc = { .str = "", };
 | 
				
			||||||
 | 
						int fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
 | 
				
			||||||
 | 
							    DEVPATH " not present");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(devfd < 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						errno = 0;
 | 
				
			||||||
 | 
						fd = ioctl(devfd, PAPR_VPD_IOC_CREATE_HANDLE, &lc);
 | 
				
			||||||
 | 
						FAIL_IF(errno != 0);
 | 
				
			||||||
 | 
						FAIL_IF(fd < 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(close(devfd) != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size_t consumed = 0;
 | 
				
			||||||
 | 
						while (1) {
 | 
				
			||||||
 | 
							ssize_t res;
 | 
				
			||||||
 | 
							char c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							errno = 0;
 | 
				
			||||||
 | 
							res = read(fd, &c, sizeof(c));
 | 
				
			||||||
 | 
							FAIL_IF(res > sizeof(c));
 | 
				
			||||||
 | 
							FAIL_IF(res < 0);
 | 
				
			||||||
 | 
							FAIL_IF(errno != 0);
 | 
				
			||||||
 | 
							consumed += res;
 | 
				
			||||||
 | 
							if (res == 0)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(consumed != lseek(fd, 0, SEEK_END));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(close(fd));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dev_papr_vpd_unterm_loc_code(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const int devfd = open(DEVPATH, O_RDONLY);
 | 
				
			||||||
 | 
						struct papr_location_code lc = {};
 | 
				
			||||||
 | 
						int fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
 | 
				
			||||||
 | 
							    DEVPATH " not present");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(devfd < 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Place a non-null byte in every element of loc_code; the
 | 
				
			||||||
 | 
						 * driver should reject this input.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						memset(lc.str, 'x', ARRAY_SIZE(lc.str));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						errno = 0;
 | 
				
			||||||
 | 
						fd = ioctl(devfd, PAPR_VPD_IOC_CREATE_HANDLE, &lc);
 | 
				
			||||||
 | 
						FAIL_IF(fd != -1);
 | 
				
			||||||
 | 
						FAIL_IF(errno != EINVAL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(close(devfd) != 0);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dev_papr_vpd_null_handle(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const int devfd = open(DEVPATH, O_RDONLY);
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
 | 
				
			||||||
 | 
							    DEVPATH " not present");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(devfd < 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						errno = 0;
 | 
				
			||||||
 | 
						rc = ioctl(devfd, PAPR_VPD_IOC_CREATE_HANDLE, NULL);
 | 
				
			||||||
 | 
						FAIL_IF(rc != -1);
 | 
				
			||||||
 | 
						FAIL_IF(errno != EFAULT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(close(devfd) != 0);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int papr_vpd_close_handle_without_reading(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const int devfd = open(DEVPATH, O_RDONLY);
 | 
				
			||||||
 | 
						struct papr_location_code lc;
 | 
				
			||||||
 | 
						int fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
 | 
				
			||||||
 | 
							    DEVPATH " not present");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(devfd < 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						errno = 0;
 | 
				
			||||||
 | 
						fd = ioctl(devfd, PAPR_VPD_IOC_CREATE_HANDLE, &lc);
 | 
				
			||||||
 | 
						FAIL_IF(errno != 0);
 | 
				
			||||||
 | 
						FAIL_IF(fd < 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* close the handle without reading it */
 | 
				
			||||||
 | 
						FAIL_IF(close(fd) != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(close(devfd) != 0);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int papr_vpd_reread(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const int devfd = open(DEVPATH, O_RDONLY);
 | 
				
			||||||
 | 
						struct papr_location_code lc = { .str = "", };
 | 
				
			||||||
 | 
						int fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
 | 
				
			||||||
 | 
							    DEVPATH " not present");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(devfd < 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						errno = 0;
 | 
				
			||||||
 | 
						fd = ioctl(devfd, PAPR_VPD_IOC_CREATE_HANDLE, &lc);
 | 
				
			||||||
 | 
						FAIL_IF(errno != 0);
 | 
				
			||||||
 | 
						FAIL_IF(fd < 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(close(devfd) != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const off_t size = lseek(fd, 0, SEEK_END);
 | 
				
			||||||
 | 
						FAIL_IF(size <= 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char *bufs[2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (size_t i = 0; i < ARRAY_SIZE(bufs); ++i) {
 | 
				
			||||||
 | 
							bufs[i] = malloc(size);
 | 
				
			||||||
 | 
							FAIL_IF(!bufs[i]);
 | 
				
			||||||
 | 
							ssize_t consumed = pread(fd, bufs[i], size, 0);
 | 
				
			||||||
 | 
							FAIL_IF(consumed != size);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(memcmp(bufs[0], bufs[1], size));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(close(fd) != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int get_system_loc_code(struct papr_location_code *lc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static const char system_id_path[] = "/sys/firmware/devicetree/base/system-id";
 | 
				
			||||||
 | 
						static const char model_path[] = "/sys/firmware/devicetree/base/model";
 | 
				
			||||||
 | 
						char *system_id;
 | 
				
			||||||
 | 
						char *model;
 | 
				
			||||||
 | 
						int err = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (read_file_alloc(model_path, &model, NULL))
 | 
				
			||||||
 | 
							return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (read_file_alloc(system_id_path, &system_id, NULL))
 | 
				
			||||||
 | 
							goto free_model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char *mtm;
 | 
				
			||||||
 | 
						int sscanf_ret = sscanf(model, "IBM,%ms", &mtm);
 | 
				
			||||||
 | 
						if (sscanf_ret != 1)
 | 
				
			||||||
 | 
							goto free_system_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char *plant_and_seq;
 | 
				
			||||||
 | 
						if (sscanf(system_id, "IBM,%*c%*c%ms", &plant_and_seq) != 1)
 | 
				
			||||||
 | 
							goto free_mtm;
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Replace - with . to build location code.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						char *sep = strchr(mtm, '-');
 | 
				
			||||||
 | 
						if (!sep)
 | 
				
			||||||
 | 
							goto free_mtm;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							*sep = '.';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						snprintf(lc->str, sizeof(lc->str),
 | 
				
			||||||
 | 
							 "U%s.%s", mtm, plant_and_seq);
 | 
				
			||||||
 | 
						err = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						free(plant_and_seq);
 | 
				
			||||||
 | 
					free_mtm:
 | 
				
			||||||
 | 
						free(mtm);
 | 
				
			||||||
 | 
					free_system_id:
 | 
				
			||||||
 | 
						free(system_id);
 | 
				
			||||||
 | 
					free_model:
 | 
				
			||||||
 | 
						free(model);
 | 
				
			||||||
 | 
						return err;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int papr_vpd_system_loc_code(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct papr_location_code lc;
 | 
				
			||||||
 | 
						const int devfd = open(DEVPATH, O_RDONLY);
 | 
				
			||||||
 | 
						off_t size;
 | 
				
			||||||
 | 
						int fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SKIP_IF_MSG(get_system_loc_code(&lc),
 | 
				
			||||||
 | 
							    "Cannot determine system location code");
 | 
				
			||||||
 | 
						SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
 | 
				
			||||||
 | 
							    DEVPATH " not present");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(devfd < 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						errno = 0;
 | 
				
			||||||
 | 
						fd = ioctl(devfd, PAPR_VPD_IOC_CREATE_HANDLE, &lc);
 | 
				
			||||||
 | 
						FAIL_IF(errno != 0);
 | 
				
			||||||
 | 
						FAIL_IF(fd < 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FAIL_IF(close(devfd) != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size = lseek(fd, 0, SEEK_END);
 | 
				
			||||||
 | 
						FAIL_IF(size <= 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void *buf = malloc((size_t)size);
 | 
				
			||||||
 | 
						FAIL_IF(!buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ssize_t consumed = pread(fd, buf, size, 0);
 | 
				
			||||||
 | 
						FAIL_IF(consumed != size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Ensure EOF */
 | 
				
			||||||
 | 
						FAIL_IF(read(fd, buf, size) != 0);
 | 
				
			||||||
 | 
						FAIL_IF(close(fd));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Verify that the buffer looks like VPD */
 | 
				
			||||||
 | 
						static const char needle[] = "System VPD";
 | 
				
			||||||
 | 
						FAIL_IF(!memmem(buf, size, needle, strlen(needle)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct vpd_test {
 | 
				
			||||||
 | 
						int (*function)(void);
 | 
				
			||||||
 | 
						const char *description;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct vpd_test vpd_tests[] = {
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.function = dev_papr_vpd_open_close,
 | 
				
			||||||
 | 
							.description = "open/close " DEVPATH,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.function = dev_papr_vpd_unterm_loc_code,
 | 
				
			||||||
 | 
							.description = "ensure EINVAL on unterminated location code",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.function = dev_papr_vpd_null_handle,
 | 
				
			||||||
 | 
							.description = "ensure EFAULT on bad handle addr",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.function = dev_papr_vpd_get_handle_all,
 | 
				
			||||||
 | 
							.description = "get handle for all VPD"
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.function = papr_vpd_close_handle_without_reading,
 | 
				
			||||||
 | 
							.description = "close handle without consuming VPD"
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.function = dev_papr_vpd_get_handle_byte_at_a_time,
 | 
				
			||||||
 | 
							.description = "read all VPD one byte at a time"
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.function = papr_vpd_reread,
 | 
				
			||||||
 | 
							.description = "ensure re-read yields same results"
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.function = papr_vpd_system_loc_code,
 | 
				
			||||||
 | 
							.description = "get handle for system VPD"
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						size_t fails = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (size_t i = 0; i < ARRAY_SIZE(vpd_tests); ++i) {
 | 
				
			||||||
 | 
							const struct vpd_test *t = &vpd_tests[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (test_harness(t->function, t->description))
 | 
				
			||||||
 | 
								++fails;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return fails == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in a new issue