Home | History | Annotate | Line # | Download | only in mlxctl
dklist.c revision 1.2
      1  1.2  ad /*	$NetBSD: dklist.c,v 1.2 2001/04/17 13:32:39 ad Exp $	*/
      2  1.1  ad 
      3  1.1  ad /*-
      4  1.1  ad  * Copyright (c) 2001 The NetBSD Foundation, Inc.
      5  1.1  ad  * All rights reserved.
      6  1.1  ad  *
      7  1.1  ad  * This code is derived from software contributed to The NetBSD Foundation
      8  1.1  ad  * by Andrew Doran.
      9  1.1  ad  *
     10  1.1  ad  * Redistribution and use in source and binary forms, with or without
     11  1.1  ad  * modification, are permitted provided that the following conditions
     12  1.1  ad  * are met:
     13  1.1  ad  * 1. Redistributions of source code must retain the above copyright
     14  1.1  ad  *    notice, this list of conditions and the following disclaimer.
     15  1.1  ad  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1  ad  *    notice, this list of conditions and the following disclaimer in the
     17  1.1  ad  *    documentation and/or other materials provided with the distribution.
     18  1.1  ad  * 3. All advertising materials mentioning features or use of this software
     19  1.1  ad  *    must display the following acknowledgement:
     20  1.1  ad  *        This product includes software developed by the NetBSD
     21  1.1  ad  *        Foundation, Inc. and its contributors.
     22  1.1  ad  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  1.1  ad  *    contributors may be used to endorse or promote products derived
     24  1.1  ad  *    from this software without specific prior written permission.
     25  1.1  ad  *
     26  1.1  ad  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  1.1  ad  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  1.1  ad  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  1.1  ad  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  1.1  ad  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  1.1  ad  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  1.1  ad  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  1.1  ad  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  1.1  ad  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  1.1  ad  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  1.1  ad  * POSSIBILITY OF SUCH DAMAGE.
     37  1.1  ad  */
     38  1.1  ad 
     39  1.1  ad /*
     40  1.1  ad  * Copyright (c) 1996 John M. Vinopal
     41  1.1  ad  * All rights reserved.
     42  1.1  ad  *
     43  1.1  ad  * Redistribution and use in source and binary forms, with or without
     44  1.1  ad  * modification, are permitted provided that the following conditions
     45  1.1  ad  * are met:
     46  1.1  ad  * 1. Redistributions of source code must retain the above copyright
     47  1.1  ad  *    notice, this list of conditions and the following disclaimer.
     48  1.1  ad  * 2. Redistributions in binary form must reproduce the above copyright
     49  1.1  ad  *    notice, this list of conditions and the following disclaimer in the
     50  1.1  ad  *    documentation and/or other materials provided with the distribution.
     51  1.1  ad  * 3. All advertising materials mentioning features or use of this software
     52  1.1  ad  *    must display the following acknowledgement:
     53  1.1  ad  *      This product includes software developed for the NetBSD Project
     54  1.1  ad  *      by John M. Vinopal.
     55  1.1  ad  * 4. The name of the author may not be used to endorse or promote products
     56  1.1  ad  *    derived from this software without specific prior written permission.
     57  1.1  ad  *
     58  1.1  ad  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     59  1.1  ad  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     60  1.1  ad  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     61  1.1  ad  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     62  1.1  ad  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     63  1.1  ad  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     64  1.1  ad  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     65  1.1  ad  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     66  1.1  ad  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     67  1.1  ad  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     68  1.1  ad  * SUCH DAMAGE.
     69  1.1  ad  */
     70  1.1  ad 
     71  1.1  ad #ifndef lint
     72  1.1  ad #include <sys/cdefs.h>
     73  1.2  ad __RCSID("$NetBSD: dklist.c,v 1.2 2001/04/17 13:32:39 ad Exp $");
     74  1.1  ad #endif /* not lint */
     75  1.1  ad 
     76  1.1  ad #include <sys/types.h>
     77  1.1  ad #include <sys/disk.h>
     78  1.1  ad #include <sys/ioctl.h>
     79  1.1  ad 
     80  1.1  ad #include <dev/ic/mlxreg.h>
     81  1.1  ad #include <dev/ic/mlxio.h>
     82  1.1  ad 
     83  1.1  ad #include <err.h>
     84  1.1  ad #include <fcntl.h>
     85  1.1  ad #include <kvm.h>
     86  1.1  ad #include <limits.h>
     87  1.1  ad #include <nlist.h>
     88  1.1  ad #include <stdio.h>
     89  1.1  ad #include <stdlib.h>
     90  1.1  ad #include <string.h>
     91  1.1  ad #include <ctype.h>
     92  1.1  ad #include <unistd.h>
     93  1.1  ad 
     94  1.1  ad #include "extern.h"
     95  1.1  ad 
     96  1.1  ad static SIMPLEQ_HEAD(, mlx_disk) mlx_disks;
     97  1.1  ad 
     98  1.1  ad static struct nlist namelist[] = {
     99  1.2  ad #define X_DISK_COUNT	0
    100  1.1  ad 	{ "_disk_count" },	/* number of disks */
    101  1.2  ad #define X_DISKLIST	1
    102  1.1  ad 	{ "_disklist" },	/* TAILQ of disks */
    103  1.1  ad 	{ NULL },
    104  1.1  ad };
    105  1.1  ad 
    106  1.1  ad #define	KVM_ERROR(_string) {						\
    107  1.1  ad 	warnx("%s", (_string));						\
    108  1.1  ad 	errx(1, "%s", kvm_geterr(kd));					\
    109  1.1  ad }
    110  1.1  ad 
    111  1.1  ad /*
    112  1.1  ad  * Dereference the namelist pointer `v' and fill in the local copy
    113  1.1  ad  * 'p' which is of size 's'.
    114  1.1  ad  */
    115  1.1  ad #define deref_nl(kd, v, p, s)	\
    116  1.1  ad     deref_kptr(kd, (void *)namelist[(v)].n_value, (p), (s));
    117  1.1  ad 
    118  1.1  ad static void	deref_kptr(kvm_t *, void *, void *, size_t);
    119  1.1  ad 
    120  1.1  ad void
    121  1.1  ad mlx_disk_init(void)
    122  1.1  ad {
    123  1.1  ad 
    124  1.1  ad 	SIMPLEQ_INIT(&mlx_disks);
    125  1.1  ad }
    126  1.1  ad 
    127  1.1  ad int
    128  1.1  ad mlx_disk_empty(void)
    129  1.1  ad {
    130  1.1  ad 
    131  1.1  ad 	return (SIMPLEQ_FIRST(&mlx_disks) == NULL);
    132  1.1  ad }
    133  1.1  ad 
    134  1.1  ad void
    135  1.1  ad mlx_disk_iterate(void (*func)(struct mlx_disk *))
    136  1.1  ad {
    137  1.1  ad 	struct mlx_disk *md;
    138  1.1  ad 
    139  1.1  ad 	SIMPLEQ_FOREACH(md, &mlx_disks, chain)
    140  1.1  ad 		(*func)(md);
    141  1.1  ad }
    142  1.1  ad 
    143  1.1  ad static int
    144  1.1  ad mlx_disk_add0(const char *name)
    145  1.1  ad {
    146  1.1  ad 	struct mlx_disk *md;
    147  1.1  ad 	int unit;
    148  1.1  ad 
    149  1.1  ad 	if (name[0] != 'l' || name[1] != 'd' || !isdigit(name[2]))
    150  1.1  ad 		return (-1);
    151  1.1  ad 
    152  1.1  ad 	SIMPLEQ_FOREACH(md, &mlx_disks, chain)
    153  1.1  ad 		if (strcmp(md->name, name) == 0)
    154  1.1  ad 			return (0);
    155  1.1  ad 
    156  1.1  ad 	unit = atoi(name + 2);
    157  1.1  ad 	if (ioctl(mlxfd, MLX_GET_SYSDRIVE, &unit) < 0)
    158  1.1  ad 		return (-1);
    159  1.1  ad 
    160  1.1  ad 	if ((md = malloc(sizeof(*md))) == NULL)
    161  1.1  ad 		err(EXIT_FAILURE, "mlx_disk_add()");
    162  1.1  ad 
    163  1.1  ad 	strlcpy(md->name, name, sizeof(md->name));
    164  1.1  ad 	md->hwunit = unit;
    165  1.1  ad 	SIMPLEQ_INSERT_TAIL(&mlx_disks, md, chain);
    166  1.1  ad 	return (0);
    167  1.1  ad }
    168  1.1  ad 
    169  1.1  ad void
    170  1.1  ad mlx_disk_add(const char *name)
    171  1.1  ad {
    172  1.1  ad 
    173  1.1  ad 	if (mlx_disk_add0(name) != 0)
    174  1.1  ad 		errx(EXIT_FAILURE, "%s is not attached to %s", name, mlxname);
    175  1.1  ad }
    176  1.1  ad 
    177  1.1  ad void
    178  1.1  ad mlx_disk_add_all(void)
    179  1.1  ad {
    180  1.1  ad 	struct disklist_head disk_head;
    181  1.1  ad 	struct disk cur_disk, *dk;
    182  1.1  ad         char errbuf[_POSIX2_LINE_MAX];
    183  1.1  ad 	char buf[12];
    184  1.1  ad 	int i, ndrives;
    185  1.1  ad 	kvm_t *kd;
    186  1.1  ad 
    187  1.1  ad 	/* Open the kernel. */
    188  1.1  ad         if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf)) == NULL)
    189  1.1  ad 		errx(1, "kvm_openfiles: %s", errbuf);
    190  1.1  ad 
    191  1.1  ad 	/* Obtain the namelist symbols from the kernel. */
    192  1.1  ad 	if (kvm_nlist(kd, namelist))
    193  1.1  ad 		KVM_ERROR("kvm_nlist failed to read symbols.");
    194  1.1  ad 
    195  1.1  ad 	/* Get the number of attached drives. */
    196  1.1  ad 	deref_nl(kd, X_DISK_COUNT, &ndrives, sizeof(ndrives));
    197  1.1  ad 
    198  1.1  ad 	if (ndrives < 0)
    199  1.1  ad 		errx(EXIT_FAILURE, "invalid _disk_count %d.", ndrives);
    200  1.1  ad 	if (ndrives == 0)
    201  1.1  ad 		errx(EXIT_FAILURE, "no drives attached.");
    202  1.1  ad 
    203  1.1  ad 	/* Get a pointer to the first disk. */
    204  1.1  ad 	deref_nl(kd, X_DISKLIST, &disk_head, sizeof(disk_head));
    205  1.1  ad 	dk = TAILQ_FIRST(&disk_head);
    206  1.1  ad 
    207  1.1  ad 	/* Try to add each disk to the list. */
    208  1.1  ad 	for (i = 0; i < ndrives; i++) {
    209  1.1  ad 		deref_kptr(kd, dk, &cur_disk, sizeof(cur_disk));
    210  1.1  ad 		deref_kptr(kd, cur_disk.dk_name, buf, sizeof(buf));
    211  1.1  ad 		mlx_disk_add0(buf);
    212  1.1  ad 		dk = TAILQ_NEXT(dk, dk_link);
    213  1.1  ad 	}
    214  1.1  ad 
    215  1.1  ad 	kvm_close(kd);
    216  1.1  ad }
    217  1.1  ad 
    218  1.1  ad /*
    219  1.1  ad  * Dereference the kernel pointer `kptr' and fill in the local copy pointed
    220  1.1  ad  * to by `ptr'.  The storage space must be pre-allocated, and the size of
    221  1.1  ad  * the copy passed in `len'.
    222  1.1  ad  */
    223  1.1  ad static void
    224  1.1  ad deref_kptr(kvm_t *kd, void *kptr, void *ptr, size_t len)
    225  1.1  ad {
    226  1.1  ad 	char buf[128];
    227  1.1  ad 
    228  1.1  ad 	if (kvm_read(kd, (u_long)kptr, (char *)ptr, len) != len) {
    229  1.1  ad 		memset(buf, 0, sizeof(buf));
    230  1.1  ad 		snprintf(buf, sizeof buf, "can't dereference kptr 0x%lx",
    231  1.1  ad 		    (u_long)kptr);
    232  1.1  ad 		KVM_ERROR(buf);
    233  1.1  ad 	}
    234  1.1  ad }
    235