usbquery.c 2.8 KB
#include "os_bb.h"
#include "osint.h"
#include "host.h"
#include "device.h"

/*
 * osBbUsbDevQuery
 *
 * Description:
 *	Find out what devices are present on one of the USB controllers, if
 *	it is acting as a USB host.  If the controller is configured as a
 *	device, this call returns the device info and attachment state.
 *
 * Returns:
 * 	Number of devices found (0 if none)
 */
s32
osBbUsbDevQuery(s32 which, OSBbUsbInfo *ip, s32 nip)
{
#ifdef USB_HOST
	HOST_GLOBAL_STRUCT *hgp;
#endif

	if (which < 0 || which >= OS_USB_MAX_CONTROLLERS) {
		PRINTF("osBbUsbDevQuery called with bad arg %d\n", which);
		return(-1);
	}

	if (nip == 0)
		return(0);

	if (_usb_ctlr_state[which].ucs_mode == UCS_MODE_IDLE) {
		return(0);
	}

	/*
	 * If this controller is a device (USB0 with mini-B connector inserted),
	 * return the info about what device it implements and whether it has
	 * a host connected or not.
	 */
	if (_usb_ctlr_state[which].ucs_mode == UCS_MODE_DEVICE) {
		bzero((void *)ip, nip * sizeof (*ip));
		dev_global_struct.funcs->query(ip);
		return(1);
	}

#ifdef USB_HOST
	if (_usb_ctlr_state[which].ucs_mode != UCS_MODE_HOST) {
		PRINTF("osBbUsbDevQuery called for ctlr %d with invalid mode %d\n",
			which, _usb_ctlr_state[which].ucs_mode);
		return(0);
	}

	hgp = &host_global_struct[which];

	if (hgp->DEVICE_ATTACHED == 0)
		return(0);

	/*
	 * If there is an attached device, wait for enumeration
	 * to complete.
	 * XXX how long to wait?
	 */
	while (hgp->ENUMERATION_DONE == 0) {
		/* USB devices can disappear arbitrarily */
		if (hgp->DEVICE_ATTACHED == 0)
			return(0);
		osYieldThread();
	}

	/*
	 * A device is there.  Check whether to do the Chapter 9
	 * negotiation.
	 */
	if (hgp->driver == NULL)
		__usb_host_chapter9_negotiation(which);
	
	bzero((void *)ip, nip * sizeof (*ip));

	/*
	 * The current model is that hubs are not supported,
	 * so there is really never more than one device.
	 * More sophisticated devices may present several
	 * different interfaces, though.  XXX deal with that later.
	 */
	ip->ua_type = OS_USB_TYPE_HOST;
	ip->ua_state = OS_USB_STATE_ATTACHED;
	ip->ua_class = hgp->RX_DESC_DEVICE.BDEVICECLASS;
	ip->ua_subclass = hgp->RX_DESC_DEVICE.BDEVICESUBCLASS;
	ip->ua_protocol = hgp->RX_DESC_DEVICE.BDEVICEPROTOCOL;
	ip->ua_vendor = swab16(hgp->RX_DESC_DEVICE.IDVENDOR);
	ip->ua_product = swab16(hgp->RX_DESC_DEVICE.IDPRODUCT);
	ip->ua_cfg = 0;		/* XXX */
	ip->ua_ep = 1;		/* XXX */
	ip->ua_speed = OS_USB_FULL_SPEED;	/* XXX */
	ip->ua_mode = OS_USB_MODE_RW;	/* XXX */
	ip->ua_blksize = hgp->RX_DESC_DEVICE.BMAXPACKETSIZE;
	ip->ua_mfr_str = hgp->MFG_STR;
	ip->ua_prod_str = hgp->PROD_STR;
	if (hgp->driver) {
		ip->ua_driver_name = hgp->driver->name;
		ip->ua_support = TRUE;
	} else {
		ip->ua_driver_name = "(No driver found)";
		ip->ua_support = FALSE;
	}

	return(1);
#else
	return(0);
#endif	/* !USB_HOST */
}