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

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

PRIVATE addr_t usb_driver();
const commandtable_t command_usb_driver =
	{"usb_driver", usb_driver, "address", "print usb_driver"};
extern void prhead_usb_driver();
extern addr_t print_usb_driver();

PRIVATE addr_t usb_bus();
const commandtable_t command_usb_bus =
	{"usb_bus", usb_bus, "[-f] [address]", "print usb_bus"};
extern void prhead_usb_bus();
extern addr_t print_usb_bus();

PRIVATE addr_t usb_device();
const commandtable_t command_usb_device =
	{"usb_device", usb_device, "[-f] address", "print usb_device"};
extern void prhead_usb_device();
extern addr_t print_usb_device();

PRIVATE addr_t usb_interface();
const commandtable_t command_usb_interface =
	{"usb_interface", usb_interface, "address", "print usb_interface"};
extern void prhead_usb_interface();
extern addr_t print_usb_interface();

addr_t usb_bus_list_addr;

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

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

	if (optind == argcnt) {
		THROW(usage);
	} else {
		prhead_usb_driver();
		while (args[optind]) {
			addr = print_usb_driver(getvalue(args[optind]), nflag);
			optind++;
		}
	}
	return addr;
}

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

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

	if (optind == argcnt) {
		GETADDR(usb_bus_list);
		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, full);
	} else {
		prhead_usb_bus();
		while (args[optind]) {
			addr = print_usb_bus(getvalue(args[optind]), 0, full);
			optind++;
		}
	}
	return addr;
}

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

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

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

PRIVATE addr_t
usb_interface()
{
	addr_t addr = 0;
	int full = 0;
	int c;

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

	if (optind == argcnt) {
		THROW(usage);
	} else {
		prhead_usb_interface();
		while (args[optind]) {
			addr = print_usb_interface(getvalue(args[optind]), full);
			optind++;
		}
	}
	return addr;
}
