#ident "$Header: dev.c 1.3 89/08/07 $"

/*
 * $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 */

/*
 * $Log:	dev.c,v $
 */

/*
 * dev.c
 *	Support for displaying dev data structures
 */

#include "crash.h"
#include <sys/types.h>
#include <sys/devsw.h>
#include <sys/sysmacros.h>

struct	dev	*readdev();
caddr_t		calloc();

union	devsw	*devsw;
int		size_devsw;

dev_init()
{
	readv(search("devsw_hsz"), &size_devsw, sizeof size_devsw);
#ifdef CROSS
	devsw = (union devsw *)malloc(size_devsw * sizeof(union devsw));
#else
	devsw = (union devsw *)valloc(size_devsw * sizeof(union devsw));
#endif
	readv(search("devsw"), devsw, size_devsw * sizeof(union devsw));
}

Dev()
{
	char *arg;
	int i;
	union devsw *d;
	struct dev *next;
	caddr_t dd;
	unsigned int addr_devsw;

	printf("\
 MAJOR    MINOR    REFCNT    PARENT    FLAGS    DEVOPS    PRIVATE-DATA\n");
	if ((arg = token()) == NULL) {
		addr_devsw = search("devsw");
		if (live)
			(void) readv(addr_devsw, devsw,
					size_devsw * sizeof(union devsw));
		d = devsw;
		for (i = 0; i < size_devsw - 1; i++, d++) {
			next = d->ds_chain[0];
			if (readv(next, &dd, sizeof dd) != sizeof dd) {
				printf("read error on hash bucket at %#x\n",
									next);
				return;
			}
			while (next != (struct dev *)(addr_devsw +
					((caddr_t)d - (caddr_t)devsw))) {
				printdev(next);
				next = (struct dev *)dd;
				if (readv(next, &dd, sizeof dd) != sizeof dd) {
					printf("read error on dev at %#x\n",
									next);
					return;
				}
			}
		}
	} else if (memcmp("0x", arg, 2) == 0) {	/* address supplied */
		printdev((struct dev *)atox(arg + 2));
	} else {
		printdev((struct dev *)atoi(arg));
	}
}

printdev(dd)
register struct dev *dd;
{
	struct dev *d;
	if ((d = readdev(dd)) == NULL)
		return;

	printf(" %-6u   %-6u   %-6u    %#6x   %#6x    %#6x         %#6x\n",
		major(d->d_dev), minor(d->d_dev), d->d_refcnt,
		d->d_parent, d->d_flags, d->d_ops, d->d_private);
}

struct dev *
readdev(dd)
struct dev *dd;
{
	static struct dev devbuf;

	if (readv(dd, &devbuf, sizeof devbuf) != sizeof devbuf) {
		printf("read error on dev\n");
		return NULL;
	}
	return &devbuf;
}
