Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 31 Jul 2013 07:52:08 GMT
From:      bguan@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r255384 - soc2013/bguan/head/sys/dev/xen/usbfront
Message-ID:  <201307310752.r6V7q8pQ061443@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bguan
Date: Wed Jul 31 07:52:07 2013
New Revision: 255384
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=255384

Log:
  debug method xenhci_roothub_exec() for xen usb host controller

Modified:
  soc2013/bguan/head/sys/dev/xen/usbfront/xenhci.c

Modified: soc2013/bguan/head/sys/dev/xen/usbfront/xenhci.c
==============================================================================
--- soc2013/bguan/head/sys/dev/xen/usbfront/xenhci.c	Wed Jul 31 07:51:55 2013	(r255383)
+++ soc2013/bguan/head/sys/dev/xen/usbfront/xenhci.c	Wed Jul 31 07:52:07 2013	(r255384)
@@ -67,6 +67,7 @@
 #endif			/* USB_GLOBAL_INCLUDE_FILE */
 
 #include <dev/xen/usbfront/xenhci.h>
+#include <dev/xen/usbfront/xenhcireg.h>
 
 #define	XENHCI_BUS2SC(bus) \
    ((struct xenhci_softc *)(((uint8_t *)(bus)) - \
@@ -89,6 +90,8 @@
 TUNABLE_INT("hw.usb.xenhci.use_polling", &xenhcipolling);
 #endif
 
+#define	XENHCI_INTR_ENDPT 1
+
 extern struct usb_bus_methods xenhci_bus_methods;
 
 
@@ -96,19 +99,7 @@
 static void
 xenhci_iterate_hw_softc(struct usb_bus *bus, usb_bus_mem_sub_cb_t *cb)
 {
-	struct xhci_softc *sc = XENHCI_BUS2SC(bus);
-	uint8_t i;
-
-	cb(bus, &sc->sc_hw.root_pc, &sc->sc_hw.root_pg,
-	   sizeof(struct xhci_hw_root), XENHCI_PAGE_SIZE);
-
-	cb(bus, &sc->sc_hw.ctx_pc, &sc->sc_hw.ctx_pg,
-	   sizeof(struct xhci_dev_ctx_addr), XENHCI_PAGE_SIZE);
-
-	for (i = 0; i != XHCI_MAX_SCRATCHPADS; i++) {
-		cb(bus, &sc->sc_hw.scratch_pc[i], &sc->sc_hw.scratch_pg[i],
-		    XENHCI_PAGE_SIZE, XENHCI_PAGE_SIZE);
-	}
+	//TODO need this method()?
 }*/
 
 usb_error_t
@@ -157,22 +148,444 @@
 	//TODO
 	return (0);
 }
+
 /*------------------------------------------------------------------------*
  * xenhci root HUB support
  *------------------------------------------------------------------------*
  * Simulate a HUB by handling all the necessary requests.
  *------------------------------------------------------------------------*/
+/*------------------------------------------------------------------------*
+ * xenhci root HUB support
+ *------------------------------------------------------------------------*
+ * Simulate a hardware HUB by handling all the necessary requests.
+ *------------------------------------------------------------------------*/
+
+#define	HSETW(ptr, val) ptr = { (uint8_t)(val), (uint8_t)((val) >> 8) }
+
+static const
+struct usb_device_descriptor xenhci_devd =
+{
+	.bLength = sizeof(xenhci_devd),
+	.bDescriptorType = UDESC_DEVICE,	/* type */
+	HSETW(.bcdUSB, 0x0200),			/* USB version */
+	.bDeviceClass = UDCLASS_HUB,		/* class */
+	.bDeviceSubClass = UDSUBCLASS_HUB,	/* subclass */
+	.bDeviceProtocol = UDPROTO_HSHUBSTT,	/* protocol */
+	.bMaxPacketSize = 64,			/* max packet size */
+	HSETW(.idVendor, 0x0000),		/* vendor */
+	HSETW(.idProduct, 0x0000),		/* product */
+	HSETW(.bcdDevice, 0x0100),		/* device version */
+	.iManufacturer = 1,
+	.iProduct = 2,
+	.iSerialNumber = 0,
+	.bNumConfigurations = 1,		/* # of configurations */
+};
+
+static const
+struct xenhci_config_desc xenhci_confd = {
+	.confd = {
+		.bLength = sizeof(xenhci_confd.confd),
+		.bDescriptorType = UDESC_CONFIG,
+		.wTotalLength[0] = sizeof(xenhci_confd),
+		.bNumInterface = 1,
+		.bConfigurationValue = 1,
+		.iConfiguration = 0,
+		.bmAttributes = UC_SELF_POWERED,
+		.bMaxPower = 0		/* max power */
+	},
+	.ifcd = {
+		.bLength = sizeof(xenhci_confd.ifcd),
+		.bDescriptorType = UDESC_INTERFACE,
+		.bNumEndpoints = 1,
+		.bInterfaceClass = UICLASS_HUB,
+		.bInterfaceSubClass = UISUBCLASS_HUB,
+		.bInterfaceProtocol = 0,
+	},
+	.endpd = {
+		.bLength = sizeof(xenhci_confd.endpd),
+		.bDescriptorType = UDESC_ENDPOINT,
+		.bEndpointAddress = UE_DIR_IN | XENHCI_INTR_ENDPT,
+		.bmAttributes = UE_INTERRUPT,
+		.wMaxPacketSize[0] = 5,		/* max 63 ports */
+		.bInterval = 255,
+	},
+	/*.endpcd = {
+		.bLength = sizeof(xenhci_confd.endpcd),
+		.bDescriptorType = UDESC_ENDPOINT_SS_COMP,
+		.bMaxBurst = 0,
+		.bmAttributes = 0,
+	},*/
+};
+
+static const
+struct usb_hub_descriptor xenhci_hubd =
+{
+	.bDescLength = 0,		/* dynamic length */
+	.bDescriptorType = UDESC_HUB,
+};
 
 static usb_error_t
 xenhci_roothub_exec(struct usb_device *udev,
     struct usb_device_request *req, const void **pptr, uint16_t *plength)
 {
 	printf("[gbtest-pv]xenhci.c: xenhci_roothub_exec()\n");
-	//usb_error_t err;
 
-	//return (err);
-	//TODO
-	return (0);
+	struct xenhci_softc *sc = XENHCI_BUS2SC(udev->bus);
+	const char *str_ptr;
+	const void *ptr;
+	uint32_t port;
+	//uint32_t v;
+	uint16_t len;
+	uint16_t i=0;
+	uint16_t value;
+	uint16_t index;
+	//uint8_t j;
+	usb_error_t err;
+
+	USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
+
+	/* buffer reset */
+	ptr = (const void *)&sc->sc_hub_desc;
+	len = 0;
+	err = 0;
+
+	value = UGETW(req->wValue);
+	index = UGETW(req->wIndex);
+
+	DPRINTFN(3, "type=0x%02x request=0x%02x wLen=0x%04x "
+	    "wValue=0x%04x wIndex=0x%04x\n",
+	    req->bmRequestType, req->bRequest,
+	    UGETW(req->wLength), value, index);
+
+#define	C(x,y) ((x) | ((y) << 8))
+	switch (C(req->bRequest, req->bmRequestType)) {
+	case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
+	case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
+	case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
+		/*
+		 * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
+		 * for the integrated root hub.
+		 */
+		break;
+	case C(UR_GET_CONFIG, UT_READ_DEVICE):
+		len = 1;
+		sc->sc_hub_desc.temp[0] = sc->sc_conf;
+		break;
+	case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
+		switch (value >> 8) {
+		case UDESC_DEVICE:
+			if ((value & 0xff) != 0) {
+				err = USB_ERR_IOERROR;
+				goto done;
+			}
+			len = sizeof(xenhci_devd);
+			ptr = (const void *)&xenhci_devd;
+			break;
+
+		//TODO require these?
+		/*case UDESC_BOS:
+			if ((value & 0xff) != 0) {
+				err = USB_ERR_IOERROR;
+				goto done;
+			}
+			len = sizeof(xhci_bosd);
+			ptr = (const void *)&xhci_bosd;
+			break;
+		*/
+
+			/*
+			 * We can't really operate at another speed,
+			 * but the specification says we need this
+			 * descriptor:
+			 */
+		/*case UDESC_DEVICE_QUALIFIER:
+			if ((value & 0xff) != 0) {
+				err = USB_ERR_IOERROR;
+				goto done;
+			}
+			len = sizeof(ehci_odevd);
+			ptr = (const void *)&ehci_odevd;
+			break;
+		*/
+
+		case UDESC_CONFIG:
+			if ((value & 0xff) != 0) {
+				err = USB_ERR_IOERROR;
+				goto done;
+			}
+			len = sizeof(xenhci_confd);
+			ptr = (const void *)&xenhci_confd;
+			break;
+
+		case UDESC_STRING:
+			switch (value & 0xff) {
+			case 0:	/* Language table */
+				str_ptr = "\001";
+				break;
+
+			case 1:	/* Vendor */
+				str_ptr = sc->sc_vendor;
+				break;
+
+			case 2:	/* Product */
+				str_ptr = "XENHCI root HUB";
+				break;
+
+			default:
+				str_ptr = "";
+				break;
+			}
+
+			len = usb_make_str_desc(
+			    sc->sc_hub_desc.temp,
+			    sizeof(sc->sc_hub_desc.temp),
+			    str_ptr);
+			break;
+
+		default:
+			err = USB_ERR_IOERROR;
+			goto done;
+		}
+		break;
+	case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
+		len = 1;
+		sc->sc_hub_desc.temp[0] = 0;
+		break;
+	case C(UR_GET_STATUS, UT_READ_DEVICE):
+		len = 2;
+		USETW(sc->sc_hub_desc.stat.wStatus, UDS_SELF_POWERED);
+		break;
+	case C(UR_GET_STATUS, UT_READ_INTERFACE):
+	case C(UR_GET_STATUS, UT_READ_ENDPOINT):
+		len = 2;
+		USETW(sc->sc_hub_desc.stat.wStatus, 0);
+		break;
+	case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
+		if (value >= XENHCI_MAX_DEVICES) {
+			err = USB_ERR_IOERROR;
+			goto done;
+		}
+		break;
+	case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
+		if (value != 0 && value != 1) {
+			err = USB_ERR_IOERROR;
+			goto done;
+		}
+		sc->sc_conf = value;
+		break;
+	case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
+		break;
+	case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
+	case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
+	case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
+		err = USB_ERR_IOERROR;
+		goto done;
+	case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
+		break;
+	case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
+		break;
+		/* Hub requests */
+	case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
+		break;
+	case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
+		DPRINTFN(9, "UR_CLEAR_PORT_FEATURE\n");
+
+		if ((index < 1) ||
+		    (index > sc->sc_noport)) {
+			err = USB_ERR_IOERROR;
+			goto done;
+		}
+		port = XENHCI_PORTSC(index);
+
+		//v = XREAD4(sc, oper, port);
+		//i = XENHCI_PS_PLS_GET(v);
+		//v &= ~XENHCI_PS_CLEAR;
+
+		//TODO how to set all the "case" according to "value"
+		switch (value) {
+		case UHF_C_PORT_SUSPEND:
+			printf("UHF_PORT_SUSPEND\n");//TODO
+			break;
+		case UHF_C_PORT_CONNECTION:
+			printf("UHF_PORT_CONNECTION\n");//TODO
+			break;
+		case UHF_C_PORT_ENABLE:
+			printf("UHF_PORT_ENABLE\n");//TODO
+			break;
+		case UHF_C_PORT_OVER_CURRENT:
+			printf("UHF_PORT_OVER_CURRENT\n");//TODO
+			break;
+		case UHF_C_PORT_RESET:
+			printf("UHF_PORT_RESET\n");//TODO
+			break;
+		case UHF_PORT_ENABLE:
+			printf("UHF_PORT_ENABLE\n");//TODO
+			break;
+		case UHF_PORT_POWER:
+			printf("UHF_PORT_POWER\n");//TODO
+			break;
+		case UHF_PORT_INDICATOR:
+			printf("UHF_PORT_INDICATOR\n");//TODO
+			break;
+		case UHF_PORT_SUSPEND:
+			printf("UHF_PORT_SUSPEND\n");//TODO
+			break;
+		case UHF_PORT_TEST:
+			printf("UHF_PORT_TEST\n");//TODO
+			break;
+		default:
+			err = USB_ERR_IOERROR;
+			goto done;
+		}
+		break;
+
+	case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
+		printf("[gbtest-pv]case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE)\n");
+		if ((value & 0xff) != 0) {
+			err = USB_ERR_IOERROR;
+			goto done;
+		}
+		//TODO?
+		//len = sizeof(uhci_hubd_piix);
+		//ptr = (const void *)&uhci_hubd_piix;
+		break;
+
+	case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
+		len = 16;
+		memset(sc->sc_hub_desc.temp, 0, 16);
+		break;
+
+	case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): //TODO?
+		DPRINTFN(9, "UR_GET_STATUS i=%d\n", index);
+
+		if ((index < 1) ||
+		    (index > sc->sc_noport)) {
+			err = USB_ERR_IOERROR;
+			goto done;
+		}
+
+		printf("[gbtest-pv]case C(UR_GET_STATUS, UT_READ_CLASS_OTHER)\n");
+		//v = XREAD4(sc, oper, XENHCI_PORTSC(index));
+		//DPRINTFN(9, "port status=0x%08x\n", v);
+
+		/*i = UPS_PORT_LINK_STATE_SET(XENHCI_PS_PLS_GET(v));
+
+		switch (XENHCI_PS_SPEED_GET(v)) {
+		case 3:
+			i |= UPS_HIGH_SPEED;
+			break;
+		case 2:
+			i |= UPS_LOW_SPEED;
+			break;
+		case 1:
+		*/	/* FULL speed */
+		/*	break;
+		default:
+			i |= UPS_OTHER_SPEED;
+			break;
+		}
+
+		if (v & XENHCI_PS_CCS)
+			i |= UPS_CURRENT_CONNECT_STATUS;
+		if (v & XENHCI_PS_PED)
+			i |= UPS_PORT_ENABLED;
+		if (v & XENHCI_PS_OCA)
+			i |= UPS_OVERCURRENT_INDICATOR;
+		if (v & XENHCI_PS_PR)
+			i |= UPS_RESET;
+		if (v & XENHCI_PS_PP) {
+		*/	/*
+			 * The USB 3.0 RH is using the
+			 * USB 2.0's power bit
+			 */
+		/*	i |= UPS_PORT_POWER;
+		}
+		*/
+		USETW(sc->sc_hub_desc.ps.wPortStatus, i);
+
+		i = 0;
+		/*if (v & XENHCI_PS_CSC)
+			i |= UPS_C_CONNECT_STATUS;
+		if (v & XENHCI_PS_PEC)
+			i |= UPS_C_PORT_ENABLED;
+		if (v & XENHCI_PS_OCC)
+			i |= UPS_C_OVERCURRENT_INDICATOR;
+		if (v & XENHCI_PS_WRC)
+			i |= UPS_C_BH_PORT_RESET;
+		if (v & XENHCI_PS_PRC)
+			i |= UPS_C_PORT_RESET;
+		if (v & XENHCI_PS_PLC)
+			i |= UPS_C_PORT_LINK_STATE;
+		if (v & XENHCI_PS_CEC)
+			i |= UPS_C_PORT_CONFIG_ERROR;
+		*/
+		USETW(sc->sc_hub_desc.ps.wPortChange, i);
+		len = sizeof(sc->sc_hub_desc.ps);
+		break;
+
+	case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
+		err = USB_ERR_IOERROR;
+		goto done;
+
+	case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
+		break;
+
+	case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
+
+		i = index >> 8;
+		index &= 0x00FF;
+
+		if ((index < 1) ||
+		    (index > sc->sc_noport)) {
+			err = USB_ERR_IOERROR;
+			goto done;
+		}
+
+		//port = XENHCI_PORTSC(index);
+		//v = XREAD4(sc, oper, port) & ~XENHCI_PS_CLEAR;
+
+		//TODO how to set all the "case" according to "value"
+		switch (value) {
+		case UHF_PORT_LINK_STATE:
+			printf("UHF_PORT_LINK_STATE\n");//TODO
+			break;
+		case UHF_PORT_ENABLE:
+			printf("UHF_PORT_ENABLE\n");//TODO
+			break;
+		case UHF_PORT_SUSPEND:
+			printf("UHF_PORT_SUSPEND\n");//TODO
+			break;
+		case UHF_PORT_RESET:
+			printf("UHF_PORT_RESET\n");//TODO
+			break;
+		case UHF_PORT_POWER:
+			printf("UHF_PORT_POWER\n");//TODO
+			break;
+		case UHF_PORT_TEST:
+			printf("UHF_PORT_TEST\n");//TODO
+			break;
+		case UHF_PORT_INDICATOR:
+			printf("UHF_PORT_INDICATOR\n");//TODO
+			break;
+		default:
+			err = USB_ERR_IOERROR;
+			goto done;
+		}
+		break;
+
+	case C(UR_CLEAR_TT_BUFFER, UT_WRITE_CLASS_OTHER):
+	case C(UR_RESET_TT, UT_WRITE_CLASS_OTHER):
+	case C(UR_GET_TT_STATE, UT_READ_CLASS_OTHER):
+	case C(UR_STOP_TT, UT_WRITE_CLASS_OTHER):
+		break;
+	default:
+		err = USB_ERR_IOERROR;
+		goto done;
+	}
+done:
+	*plength = len;
+	*pptr = ptr;
+	return (err);
 }
 
 static void
@@ -209,14 +622,15 @@
 	DPRINTFN(2, "endpoint=%p, addr=%d, endpt=%d, mode=%d\n",
 	    ep, udev->address, edesc->bEndpointAddress, udev->flags.usb_mode);
 
-	printf("[gb-test]endpoint=%p, addr=%d, endpt=%d, mode=%d\n",
+	printf("[gbtest-pv]endpoint=%p, addr=%d, endpt=%d, mode=%d\n",
 	    ep, udev->address, edesc->bEndpointAddress, udev->flags.usb_mode);
 	if (udev->parent_hub == NULL) {
 		/* root HUB has special endpoint handling */
-		printf("[gb-test]xenhci.c: xenhci_ep_init():udev->parent_hub == NULL\n");
+		printf("[gbtest-pv]xenhci.c: xenhci_ep_init():udev->parent_hub == NULL\n");
 		return;
 	}
 
+	printf("[gbtest-pv]xenhci.c: xenhci_ep_init():TODO?...\n");
 	//ep->methods = &xhci_device_generic_methods;
 
 	//pepext = xhci_get_endpoint_ext(udev, edesc);
@@ -303,7 +717,7 @@
 
 	/* check for root HUB */
 	if (udev->parent_hub == NULL) {
-		printf("[gb-test]xenhci.c: xenhci_device_state_change(): udev->parent_hub == NULL\n");
+		printf("[gbtest-pv]xenhci.c: xenhci_device_state_change(): udev->parent_hub == NULL\n");
 		return;
 	}
 
@@ -312,26 +726,27 @@
 	//DPRINTF("\n");
 
 	if (usb_get_device_state(udev) == USB_STATE_CONFIGURED) {
-		printf("[gb-test]state(udev) == USB_STATE_CONFIGURED\n");
+		printf("[gbtest-pv]state(udev) == USB_STATE_CONFIGURED\n");
 	}
 
 	//XHCI_CMD_LOCK(sc);
 
+	//TODO how to?
 	switch (usb_get_device_state(udev)) {
 	case USB_STATE_POWERED:
-		printf("[gb-test]state(udev) == USB_STATE_POWERED\n");
+		printf("[gbtest-pv]state(udev) == USB_STATE_POWERED\n");
 		break;
 
 	case USB_STATE_ADDRESSED:
-		printf("[gb-test]state(udev) == USB_STATE_ADDRESSED\n");
+		printf("[gbtest-pv]state(udev) == USB_STATE_ADDRESSED\n");
 		break;
 
 	case USB_STATE_CONFIGURED:
-		printf("[gb-test]state(udev) == USB_STATE_CONFIGURED\n");
+		printf("[gbtest-pv]state(udev) == USB_STATE_CONFIGURED\n");
 		break;
 
 	default:
-		printf("[gb-test]state(udev) == other!!\n");
+		printf("[gbtest-pv]state(udev) == other!!\n");
 		break;
 	}
 	//XHCI_CMD_UNLOCK(sc);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201307310752.r6V7q8pQ061443>