PERFORCE change 166536 for review
Sylvestre Gallon
syl at FreeBSD.org
Sat Jul 25 09:31:31 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=166536
Change 166536 by syl at 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);
More information about the p4-projects
mailing list