/*
 * Copyright (C) 2000-2003 ASANO Masahiro
 */

#include <unistd.h>
#include "crash.h"

PRIVATE addr_t usb_driver(), usb_bus(), usb_device();
const commandtable_t command_usb_driver =
	{"usb_driver", usb_driver, "[address]", "print usb_driver"};
const commandtable_t command_usb_bus =
	{"usb_bus", usb_bus, "[address]", "print usb_bus"};
const commandtable_t command_usb_device =
	{"usb_device", usb_device, "[address]", "print usb_device"};

extern void prhead_usb_driver(), prhead_usb_bus(), prhead_usb_device();
extern addr_t print_usb_driver(), print_usb_bus(), print_usb_device();
addr_t usb_driver_list_addr, usb_bus_list_addr;

PRIVATE addr_t
usb_driver()
{
	addr_t addr = 0;
	int c, nflag = 0;
	struct list_head usb_driver_list;

	while ((c = getopt(argcnt, args, "n")) != EOF) {
		switch (c) {
		case 'n':
			nflag = 1;
			break;
		default:
			THROW(usage);
		}
	}

	GETADDR(usb_driver_list);

	if (optind == argcnt) {
		memread(usb_driver_list_addr, sizeof(usb_driver_list), &usb_driver_list, "usb_driver_list");
		prhead_usb_driver();
		addr = (addr_t)usb_driver_list.next;
		while (addr && usb_driver_list_addr != addr)
			addr = print_usb_driver(addr, 1, nflag);
	} else {
		prhead_usb_driver();
		while (args[optind]) {
			addr = print_usb_driver(getaddr(args[optind]), 0, nflag);
			optind++;
		}
	}
	return addr;
}

PRIVATE addr_t
usb_bus()
{
	addr_t addr = 0;
	int c;
	struct list_head usb_bus_list;

	while ((c = getopt(argcnt, args, "")) != EOF) {
		switch (c) {
		default:
			THROW(usage);
		}
	}

	GETADDR(usb_bus_list);

	if (optind == argcnt) {
		memread(usb_bus_list_addr, sizeof(usb_bus_list), &usb_bus_list, "usb_bus_list");
		prhead_usb_bus();
		addr = (addr_t)usb_bus_list.next;
		while (addr && usb_bus_list_addr != addr)
			addr = print_usb_bus(addr, 1);
	} else {
		prhead_usb_bus();
		while (args[optind]) {
			addr = print_usb_bus(getaddr(args[optind]), 0);
			optind++;
		}
	}
	return addr;
}

PRIVATE addr_t
usb_device()
{
	addr_t addr = 0;
	int c;

	while ((c = getopt(argcnt, args, "")) != EOF) {
		switch (c) {
		default:
			THROW(usage);
		}
	}

	if (optind == argcnt) {
		THROW(usage);
	} else {
		prhead_usb_device();
		while (args[optind]) {
			addr = print_usb_device(getaddr(args[optind]), 0);
			optind++;
		}
	}
	return addr;
}
