Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 Jul 2009 09:31:29 GMT
From:      Sylvestre Gallon <syl@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 166536 for review
Message-ID:  <200907250931.n6P9VTfG074528@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=166536

Change 166536 by syl@syl_atuin on 2009/07/25 09:30:28

	Implement hub descriptor code
	Add missing structure in .h
	Implement s3c24dci_standard_chain.
	Implement s3c24dci_standard_chain_sub.
	Implement s3c24dci_roothub_exec.	

Affected files ...

.. //depot/projects/soc2009/syl_usb/src/sys/dev/usb/controller/s3c24xxdci.c#12 edit
.. //depot/projects/soc2009/syl_usb/src/sys/dev/usb/controller/s3c24xxdci.h#8 edit

Differences ...

==== //depot/projects/soc2009/syl_usb/src/sys/dev/usb/controller/s3c24xxdci.c#12 (text+ko) ====

@@ -72,6 +72,12 @@
     "s3c24xxdci debug level");
 #endif
 
+#define S3C24_DCI_INTR_ENDPT 1 
+
+static s3c24dci_cmd_t s3c24dci_setup_rx;
+static s3c24dci_cmd_t s3c24dci_data_rx;
+static s3c24dci_cmd_t s3c24dci_data_tx;
+static s3c24dci_cmd_t s3c24dci_data_tx_sync;
 static void	s3c24dci_device_done(struct usb_xfer *, usb_error_t);
 static void	s3c24dci_start_standard_chain(struct usb_xfer *xfer);
 
@@ -135,6 +141,30 @@
  * Transfer stuff.
  */
 
+static uint8_t 
+s3c24dci_setup_rx(struct s3c24dci_td *td)
+{
+	return 0;
+}
+
+static uint8_t 
+s3c24dci_data_rx(struct s3c24dci_td *td)
+{
+	return 0;
+}
+
+static uint8_t 
+s3c24dci_data_tx(struct s3c24dci_td *td)
+{
+	return 0;
+}
+
+static uint8_t 
+s3c24dci_data_tx_sync(struct s3c24dci_td *td)
+{
+	return 0;
+}
+
 static void
 s3c24dci_device_done(struct usb_xfer *xfer, usb_error_t error)
 {
@@ -350,9 +380,173 @@
 }
 
 static void
+s3c24dci_setup_standard_chain_sub(struct s3c24dci_std_temp *temp)
+{
+	struct s3c24dci_td *td;
+
+	/* get current Transfer Descriptor */
+	td = temp->td_next;
+	temp->td = td;
+
+	/* prepare for next TD */
+	temp->td_next = td->obj_next;
+
+	/* fill out the Transfer Descriptor */
+	td->func = temp->func;
+	td->pc = temp->pc;
+	td->offset = temp->offset;
+	td->remainder = temp->len;
+	td->error = 0;
+	td->did_stall = temp->did_stall;
+	td->short_pkt = temp->short_pkt;
+	td->alt_next = temp->setup_alt_next;
+}
+
+static void
 s3c24dci_setup_standard_chain(struct usb_xfer *xfer)
 {
+	struct s3c24dci_std_temp temp;
+	struct s3c24dci_softc *sc;
+	struct s3c24dci_td *td;
+	uint32_t x;
+	uint8_t ep_no;
+	uint8_t need_sync;
+
+	DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
+	   xfer->address, UE_GET_ADDR(xfer->endpointno),
+	   xfer->sumlen, usbd_get_speed(xfer->xroot->udev));
+
+	temp.max_frame_size = xfer->max_frame_size;
+
+	td = xfer->td_start[0];
+	xfer->td_transfer_first = td;
+	xfer->td_transfer_cache = td;
+
+	/* setup temp */
+
+	temp.td = NULL;
+	temp.td_next =  xfer->td_start[0];
+	temp.offset = 0;
+	temp.setup_alt_next = xfer->flags_int.short_frames_ok;
+	temp.did_stall = !xfer->flags_int.control_stall;
+
+	sc = S3C24_DCI_BUS2SC(xfer->xroot->bus);
+	ep_no = (xfer->endpointno & UE_ADDR);
+
+	/* check if we should prepend a setup message */
+
+	if (xfer->flags_int.control_xfr) {
+		if (xfer->flags_int.control_hdr) {
+			temp.func = &s3c24dci_setup_rx;
+			temp.len = xfer->frlengths[0];
+			temp.pc = xfer->frbuffers + 0;
+			temp.short_pkt = temp.len ? 1 : 0;
+			/* check for last frame */
+			if (xfer->nframes == 1) {
+				/* no STATUS stage yet, SETUP is last */
+				if (xfer->flags_int.control_act)
+					temp.setup_alt_next = 0;
+			}
+			s3c24dci_setup_standard_chain_sub(&temp);
+		}
+		x = 1;
+	} else {
+		x = 0;
+	}
+
+	if (x != xfer->nframes) {
+		if (xfer->endpointno & UE_DIR_IN) {
+			temp.func = &s3c24dci_data_tx;
+			need_sync = 1;
+		} else { 
+			temp.func = &s3c24dci_data_rx;
+			need_sync = 1;
+		}
+
+		/* setup "pc" pointer */
+		temp.pc = xfer->frbuffers + x;
+	} else {
+		need_sync = 0;
+	}
+	while (x != xfer->nframes) {
+
+		/* DATA0 / DATA2 message */
+		temp.len = xfer->frlengths[x];
+		x++;
+
+		if (x == xfer->nframes) {
+			if (xfer->flags_int.control_xfr) {
+				if (xfer->flags_int.control_act) {
+					temp.setup_alt_next = 0;
+				}
+			} else {
+				temp.setup_alt_next = 0;
+			}
+		}
+		if (temp.len == 0) {
+
+			/* make sure that we send an USB packet */
+
+			temp.short_pkt = 0;
+
+		} else {
+			
+			/* regular data pointer */
+			temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
+		}
+		s3c24dci_setup_standard_chain_sub(&temp);
+
+		if (xfer->flags_int.isochronous_xfr) {
+			temp.offset += temp.len;
+		} else {
+			/* get next Page Cache pointer */
+			temp.pc = xfer->frbuffers + x;
+		}
+	}
+
+	/* check for control transfer */
+	if (xfer->flags_int.control_xfr) {
+
+		/* always setup a valid "pc" pointer for status and sync */
+		temp.pc = xfer->frbuffers + 0 ;
+		temp.len = 0;
+		temp.short_pkt = 0;
+		temp.setup_alt_next = 0;
+
+		/* check if we need to sync */
+		if (need_sync) {
+			/* we need a SYNC point afer TX */
+			temp.func = &s3c24dci_data_tx_sync;
+			s3c24dci_setup_standard_chain_sub(&temp);
+		
+		}
+
+		/* check if we should append a status stage */
+		if (!xfer->flags_int.control_act) {
+			/*
+			 * Sen a DATA1 message and invert the current
+			 * endpoint direction
+			 */
+			if (xfer->endpointno & UE_DIR_IN) {
+				temp.func = &s3c24dci_data_rx;
+				need_sync = 0;
+			} else {
+				temp.func = &s3c24dci_data_tx;
+				need_sync = 1;
+			}
+
+			s3c24dci_setup_standard_chain_sub(&temp);
+			if (need_sync) {
+				/* we need a SYNC point after TX */
+				temp.func = &s3c24dci_data_tx_sync;
+				s3c24dci_setup_standard_chain_sub(&temp);
+			}
+		}
+	}
 
+	/* must have at least one frame ! */
+	td = temp.td;
+	xfer->td_transfer_last = td;
 }
 
 /*
@@ -402,6 +596,94 @@
 };
 
 /*
+ * s3c24dci root control support
+ * Simulate a hardware HUB by handling all the necessary requests.
+ */
+
+static const struct usb_device_descriptor s3c24dci_devd = {
+	.bLength = sizeof(struct usb_device_descriptor),
+	.bDescriptorType = UDESC_DEVICE,
+	.bcdUSB = {0x00, 0x02},
+	.bDeviceClass = UDCLASS_HUB,
+	.bDeviceSubClass = UDSUBCLASS_HUB,
+	.bDeviceProtocol = UDPROTO_HSHUBSTT,
+	.bMaxPacketSize = 64,
+	.bcdDevice = {0x00, 0x01},
+	.iManufacturer = 1,
+	.iProduct = 2,
+	.bNumConfigurations = 1,
+};
+
+static const struct usb_device_qualifier s3c24dci_odevd = {
+	.bLength = sizeof(struct usb_device_qualifier),
+	.bDescriptorType = UDESC_DEVICE_QUALIFIER,
+	.bcdUSB = {0x00, 0x02},
+	.bDeviceClass = UDCLASS_HUB,
+	.bDeviceSubClass = UDSUBCLASS_HUB,
+	.bDeviceProtocol = UDPROTO_FSHUB,
+	.bMaxPacketSize0 = 0,
+	.bNumConfigurations = 0,
+	
+};
+
+static const struct s3c24dci_config_desc s3c24dci_confd = {
+	.confd = {
+		.bLength = sizeof(struct usb_config_descriptor),
+		.bDescriptorType = UDESC_CONFIG,
+		.wTotalLength[0] = sizeof(s3c24dci_confd),
+		.bNumInterface = 1,
+		.bConfigurationValue = 1,
+		.iConfiguration = 0,
+		.bmAttributes = UC_SELF_POWERED,
+		.bMaxPower = 0,
+	},
+	.ifcd = {
+		.bLength = sizeof(struct usb_interface_descriptor),
+		.bDescriptorType = UDESC_INTERFACE,
+		.bNumEndpoints = 1,
+		.bInterfaceClass = UICLASS_HUB,
+		.bInterfaceSubClass = UISUBCLASS_HUB,
+		.bInterfaceProtocol = UIPROTO_HSHUBSTT,
+	},
+	.endpd = {
+		.bLength = sizeof(struct usb_endpoint_descriptor),
+		.bDescriptorType = UDESC_ENDPOINT,
+		.bEndpointAddress = (UE_DIR_IN | S3C24_DCI_INTR_ENDPT),
+		.bmAttributes = UE_INTERRUPT,
+		.wMaxPacketSize[0] = 8,
+		.bInterval = 255,
+	},
+};
+
+static const struct usb_hub_descriptor_min s3c24dci_hubd = {
+	.bDescLength = sizeof(s3c24dci_hubd),
+	.bDescriptorType = UDESC_HUB,
+	.bNbrPorts = 1,
+	.wHubCharacteristics[0] =
+	(UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) & 0xFF,
+	.wHubCharacteristics[1] =
+	(UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 8,
+	.bPwrOn2PwrGood = 50,
+	.bHubContrCurrent = 0,
+	.DeviceRemovable = {0},		/* port is removable */
+};
+
+#define	STRING_LANG \
+  0x09, 0x04,				/* American English */
+
+#define	STRING_VENDOR \
+  'S', 0, 'A', 0, 'M', 0, 'S', 0, 'U', 0, 'N', 0, 'G', 0
+
+#define	STRING_PRODUCT \
+  'D', 0, 'C', 0, 'I', 0, ' ', 0, 'R', 0, \
+  'o', 0, 'o', 0, 't', 0, ' ', 0, 'H', 0, \
+  'U', 0, 'B', 0,
+
+USB_MAKE_STRING_DESC(STRING_LANG, s3c24dci_langtab);
+USB_MAKE_STRING_DESC(STRING_VENDOR, s3c24dci_vendor);
+USB_MAKE_STRING_DESC(STRING_PRODUCT, s3c24dci_product);
+
+/*
  * USB FN interface
  */
 
@@ -565,11 +847,428 @@
 	return ;
 }
 
+static void
+s3c24dci_clocks_on(struct s3c24dci_softc *sc)
+{
+
+}
+
+static void
+s3c24dci_clocks_off(struct s3c24dci_softc *sc)
+{
+
+}
+
+static void
+s3c24dci_pull_up(struct s3c24dci_softc *sc)
+{
+
+}
+
+static void
+s3c24dci_pull_down(struct s3c24dci_softc *sc)
+{
+
+}
+
+static void
+s3c24dci_wakeup_peer(struct s3c24dci_softc *sc)
+{
+
+}
+
 static usb_error_t
 s3c24dci_roothub_exec(struct usb_device *udev,
     struct usb_device_request *req, const void **pptr, uint16_t *plength)
 {
+	struct s3c24dci_softc *sc = S3C24_DCI_BUS2SC(udev->bus);
+	const void *ptr;
+	uint16_t len;
+	uint16_t value;
+	uint16_t index;
+	usb_error_t err;
+
+	USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
+
+	/* buffer reset */
+	ptr = (const void *)&sc->sc_hub_temp;
+	len = 0;
+	err = 0;
+
+	value = UGETW(req->wValue);
+	index = UGETW(req->wIndex);
+
+	/* demultiplex the control request */
+
+	switch (req->bmRequestType) {
+	case UT_READ_DEVICE:
+		switch (req->bRequest) {
+		case UR_GET_DESCRIPTOR:
+			goto tr_handle_get_descriptor;
+		case UR_GET_CONFIG:
+			goto tr_handle_get_config;
+		case UR_GET_STATUS:
+			goto tr_handle_get_status;
+		default:
+			goto tr_stalled;
+		}
+		break;
+	
+	case UT_WRITE_DEVICE:
+		switch (req->bRequest) {
+		case UR_SET_ADDRESS:
+			goto tr_handle_set_address;
+		case UR_SET_CONFIG:
+			goto tr_handle_set_config;
+		case UR_CLEAR_FEATURE:
+			goto tr_valid;	/* nop */
+		case UR_SET_DESCRIPTOR:
+			goto tr_valid;	/* nop */
+		case UR_SET_FEATURE:
+		default:
+			goto tr_stalled;
+		}
+		break;
+	
+	case UT_WRITE_ENDPOINT:
+		switch (req->bRequest) {
+		case UR_CLEAR_FEATURE:
+			switch (UGETW(req->wValue)) {
+			case UF_ENDPOINT_HALT:
+				goto tr_handle_clear_halt;
+			case UF_DEVICE_REMOTE_WAKEUP:
+				goto tr_handle_clear_wakeup;
+			default:
+				goto tr_stalled;
+			}
+			break;
+		case UR_SET_FEATURE:
+			switch (UGETW(req->wValue)) {
+			case UF_ENDPOINT_HALT:
+				goto tr_handle_set_halt;
+			case UF_DEVICE_REMOTE_WAKEUP:
+				goto tr_handle_set_wakeup;
+			default:
+				goto tr_stalled;
+			}
+			break;
+		case UR_SYNCH_FRAME:
+			goto tr_valid;	/* nop */
+		default:
+			goto tr_stalled;
+		}
+		break;
+
+	case UT_READ_ENDPOINT:
+		switch (req->bRequest) {
+		case UR_GET_STATUS:
+			goto tr_handle_get_ep_status;
+		default:
+			goto tr_stalled;
+		}
+		break;
+
+	case UT_WRITE_INTERFACE:
+		switch (req->bRequest) {
+		case UR_SET_INTERFACE:
+			goto tr_handle_set_interface;
+		case UR_CLEAR_FEATURE:
+			goto tr_valid;	/* nop */
+		case UR_SET_FEATURE:
+		default:
+			goto tr_stalled;
+		}
+		break;
+
+	case UT_READ_INTERFACE:
+		switch (req->bRequest) {
+		case UR_GET_INTERFACE:
+			goto tr_handle_get_interface;
+		case UR_GET_STATUS:
+			goto tr_handle_get_iface_status;
+		default:
+			goto tr_stalled;
+		}
+		break;
+
+	case UT_WRITE_CLASS_INTERFACE:
+	case UT_WRITE_VENDOR_INTERFACE:
+		/* XXX forward */
+		break;
+
+	case UT_READ_CLASS_INTERFACE:
+	case UT_READ_VENDOR_INTERFACE:
+		/* XXX forward */
+		break;
+
+	case UT_WRITE_CLASS_DEVICE:
+		switch (req->bRequest) {
+		case UR_CLEAR_FEATURE:
+			goto tr_valid;
+		case UR_SET_DESCRIPTOR:
+		case UR_SET_FEATURE:
+			break;
+		default:
+			goto tr_stalled;
+		}
+		break;
+
+	case UT_WRITE_CLASS_OTHER:
+		switch (req->bRequest) {
+		case UR_CLEAR_FEATURE:
+			goto tr_handle_clear_port_feature;
+		case UR_SET_FEATURE:
+			goto tr_handle_set_port_feature;
+		case UR_CLEAR_TT_BUFFER:
+		case UR_RESET_TT:
+		case UR_STOP_TT:
+			goto tr_valid;
+
+		default:
+			goto tr_stalled;
+		}
+		break;
+
+	case UT_READ_CLASS_OTHER:
+		switch (req->bRequest) {
+		case UR_GET_TT_STATE:
+			goto tr_handle_get_tt_state;
+		case UR_GET_STATUS:
+			goto tr_handle_get_port_status;
+		default:
+			goto tr_stalled;
+		}
+		break;
+
+	case UT_READ_CLASS_DEVICE:
+		switch (req->bRequest) {
+		case UR_GET_DESCRIPTOR:
+			goto tr_handle_get_class_descriptor;
+		case UR_GET_STATUS:
+			goto tr_handle_get_class_status;
+
+		default:
+			goto tr_stalled;
+		}
+		break;
+	default:
+		goto tr_stalled;
+	}
+	goto tr_valid;
+
+tr_handle_get_descriptor:
+	switch (value >> 8) {
+	case UDESC_DEVICE:
+		if (value & 0xff) {
+			goto tr_stalled;
+		}
+		len = sizeof(s3c24dci_devd);
+		ptr = (const void *)&s3c24dci_devd;
+		goto tr_valid;
+	case UDESC_CONFIG:
+		if (value & 0xff) {
+			goto tr_stalled;
+		}
+		len = sizeof(s3c24dci_confd);
+		ptr = (const void *)&s3c24dci_confd;
+		goto tr_valid;
+	case UDESC_STRING:
+		switch (value & 0xff) {
+		case 0:		/* Language table */
+			len = sizeof(s3c24dci_langtab);
+			ptr = (const void *)&s3c24dci_langtab;
+			goto tr_valid;
+
+		case 1:		/* Vendor */
+			len = sizeof(s3c24dci_vendor);
+			ptr = (const void *)&s3c24dci_vendor;
+			goto tr_valid;
+
+		case 2:		/* Product */
+			len = sizeof(s3c24dci_product);
+			ptr = (const void *)&s3c24dci_product;
+			goto tr_valid;
+		default:
+			break;
+		}
+		break;
+	default:
+		goto tr_stalled;
+	}
+	goto tr_stalled;
+	
+tr_handle_get_config:
+	len = 1;
+	sc->sc_hub_temp.wValue[0] = sc->sc_conf;
+	goto tr_valid;
+
+tr_handle_get_status:
+	len = 2;
+	USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
+	goto tr_valid;
+
+tr_handle_set_address:
+	if (value & 0xFF00) {
+		goto tr_stalled;
+	}
+	sc->sc_rt_addr = value;
+	goto tr_valid;
+
+tr_handle_set_config:
+	if (value >= 2) {
+		goto tr_stalled;
+	}
+	sc->sc_conf = value;
+	goto tr_valid;
+
+tr_handle_get_interface:
+	len = 1;
+	sc->sc_hub_temp.wValue[0] = 0;
+	goto tr_valid;
+
+tr_handle_get_tt_state:
+tr_handle_get_class_status:
+tr_handle_get_iface_status:
+tr_handle_get_ep_status:
+	len = 2;
+	USETW(sc->sc_hub_temp.wValue, 0);
+	goto tr_valid;
+
+tr_handle_set_halt:
+tr_handle_set_interface:
+tr_handle_set_wakeup:
+tr_handle_clear_wakeup:
+tr_handle_clear_halt:
+	goto tr_valid;
+
 	return (USB_ERR_STALLED);	
+
+tr_handle_clear_port_feature:
+	if (index != 1) {
+		goto tr_stalled;
+	}
+	DPRINTFN(9, "UR_CLEAR_PORT_FEATURE on port %d\n", index);
+
+	switch (value) {
+	case UHF_PORT_SUSPEND:
+		s3c24dci_wakeup_peer(sc);
+		break;
+
+	case UHF_PORT_ENABLE:
+		sc->sc_flags.port_enabled = 0;
+		break;
+
+	case UHF_PORT_TEST:
+	case UHF_PORT_INDICATOR:
+	case UHF_C_PORT_ENABLE:
+	case UHF_C_PORT_OVER_CURRENT:
+	case UHF_C_PORT_RESET:
+		/* nops */
+		break;
+	case UHF_PORT_POWER:
+		sc->sc_flags.port_powered = 0;
+		s3c24dci_pull_down(sc);
+		s3c24dci_clocks_off(sc);
+		break;
+	case UHF_C_PORT_CONNECTION:
+		sc->sc_flags.change_connect = 0;
+		break;
+	case UHF_C_PORT_SUSPEND:
+		sc->sc_flags.change_suspend = 0;
+		break;
+	default:
+		err = USB_ERR_IOERROR;
+		goto done;
+	}
+	goto tr_valid;
+
+tr_handle_set_port_feature:
+	if (index != 1) {
+		goto tr_stalled;
+	}
+	DPRINTFN(9, "UR_SET_PORT_FEATURE\n");
+
+	switch (value) {
+	case UHF_PORT_ENABLE:
+		sc->sc_flags.port_enabled = 1;
+		break;
+	case UHF_PORT_SUSPEND:
+	case UHF_PORT_RESET:
+	case UHF_PORT_TEST:
+	case UHF_PORT_INDICATOR:
+		/* nops */
+		break;
+	case UHF_PORT_POWER:
+		sc->sc_flags.port_powered = 1;
+		break;
+	default:
+		err = USB_ERR_IOERROR;
+		goto done;
+	}
+	goto tr_valid;
+	
+tr_handle_get_port_status:
+
+	DPRINTFN(9, "UR_GET_PORT_STATUS\n");
+
+	if (index != 1) {
+		goto tr_stalled;
+	}
+	if (sc->sc_flags.status_vbus) {
+		s3c24dci_clocks_on(sc);
+		s3c24dci_pull_up(sc);
+	} else {
+		s3c24dci_pull_down(sc);
+		s3c24dci_clocks_off(sc);
+	}
+
+	/* Select FULL-speed and Device Side Mode */
+
+	value = UPS_PORT_MODE_DEVICE;
+
+	if (sc->sc_flags.port_powered) {
+		value |= UPS_PORT_POWER;
+	}
+	if (sc->sc_flags.port_enabled) {
+		value |= UPS_PORT_ENABLED;
+	}
+	if (sc->sc_flags.status_vbus &&
+	    sc->sc_flags.status_bus_reset) {
+		value |= UPS_CURRENT_CONNECT_STATUS;
+	}
+	if (sc->sc_flags.status_suspend) {
+		value |= UPS_SUSPEND;
+	}
+	USETW(sc->sc_hub_temp.ps.wPortStatus, value);
+
+	value = 0;
+
+	if (sc->sc_flags.change_connect) {
+		value |= UPS_C_CONNECT_STATUS;
+
+	}
+	if (sc->sc_flags.change_suspend) {
+		value |= UPS_C_SUSPEND;
+	}
+	USETW(sc->sc_hub_temp.ps.wPortChange, value);
+	len = sizeof(sc->sc_hub_temp.ps);
+	goto tr_valid;
+
+tr_handle_get_class_descriptor:
+	if (value & 0xFF) {
+		goto tr_stalled;
+	}
+	ptr = (const void *)&s3c24dci_hubd;
+	len = sizeof(s3c24dci_hubd);
+	goto tr_valid;
+
+tr_stalled:
+	err = USB_ERR_STALLED;
+tr_valid:
+done:
+	*plength = len;
+	*pptr = ptr;
+	return (err);
 }
 
 static void

==== //depot/projects/soc2009/syl_usb/src/sys/dev/usb/controller/s3c24xxdci.h#8 (text+ko) ====

@@ -195,8 +195,51 @@
 	uint8_t did_stall:1;
 };
 
+struct s3c24dci_std_temp {
+	s3c24dci_cmd_t *func;
+	struct usb_page_cache *pc;
+	struct s3c24dci_td *td;
+	struct s3c24dci_td *td_next;
+	uint32_t len;
+	uint32_t offset;
+	uint16_t max_frame_size;
+	uint8_t short_pkt;
+	/* 
+	 * short_pkt = 0: transfer should be short terminated
+	 * short_pkt = 1: transfer should not be should terminated
+}	 */
+	uint8_t setup_alt_next;
+	uint8_t did_stall;
+};
+
+struct s3c24dci_config_desc {
+	struct usb_config_descriptor confd;
+	struct usb_interface_descriptor ifcd;
+	struct usb_endpoint_descriptor endpd;
+} __packed;
+
+union s3c24dci_hub_temp {
+	uWord wValue;
+	struct usb_port_status ps;
+};
+
+struct s3c24dci_flags {
+	uint8_t	change_connect:1;
+	uint8_t	change_suspend:1;
+	uint8_t	status_suspend:1;	/* set if suspended */
+	uint8_t	status_vbus:1;		/* set if present */
+	uint8_t	status_bus_reset:1;	/* set if reset complete */
+	uint8_t	remote_wakeup:1;
+	uint8_t	self_powered:1;
+	uint8_t	clocks_off:1;
+	uint8_t	port_powered:1;
+	uint8_t	port_enabled:1;
+	uint8_t	d_pulled_up:1;
+};
+
 struct s3c24dci_softc {
 	struct usb_bus sc_bus;
+	union s3c24dci_hub_temp sc_hub_temp;
 
 	struct usb_device *sc_devices[2];
 	bus_space_tag_t sc_io_tag;
@@ -207,6 +250,8 @@
 	uint8_t	sc_conf;		/* root HUB config */
 
 	uint8_t	sc_hub_idata[1];
+
+	struct s3c24dci_flags sc_flags;
 };
 
 usb_error_t s3c24dci_init(struct s3c24dci_softc *sc);



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