* as unions so that the parameters can be used in the request processing.
*/
static struct {
- union {
- u8 StandardDeviceRequest;
- u8 bmRequestType;
- } byte0;
- union {
- u8 FbRequest;
- u8 bRequest;
- } byte1;
- union {
- struct {
- u8 bDescriptorType;
- u8 bDescriptorIndex;
- } byte23;
- u16 FwValue;
- u16 wValue;
- u16 wFeatureSelector;
- } word1;
- union {
- struct {
- u8 byteh;
- u8 bytel;
- } byte45;
- u16 wTargetSelector;
- u16 FwIndex;
- u16 wIndex;
- } word2;
- union {
- struct {
- u8 byteh;
- u8 bytel;
- } byte67;
- u16 wLength;
- } word3;
+ struct usb_ctrlrequest setup;
u8 *contreadptr;
u8 *contwriteptr;
u32 contreadcount;
u8 contreaddatabuffer[64];
} ch9_cmdbuf;
-
- /* union for 32 bit integer memory access to the Dual Port RAM.*/
-static union {
- u32 word;
- struct {
- u8 zero;
- u8 one;
- u8 two;
- u8 three;
- } byte;
-} usbmemdata;
-
/*
* Initial Fixed locations provided for endpoint memory address
* in the USB core. The user needs to modify this as per his application.
return container_of(g, struct xusb_udc, gadget);
}
+static void xusb_write32(u32 val, void __iomem *addr)
+{
+ iowrite32(val, addr);
+}
+
+static unsigned int xusb_read32(void __iomem *addr)
+{
+ return ioread32(addr);
+}
+
static void xusb_write32_be(u32 val, void __iomem *addr)
{
iowrite32be(val, addr);
{
u32 epcfgreg;
- switch (ch9_cmdbuf.word1.wValue) {
+ switch (ch9_cmdbuf.setup.wValue) {
case 0:
/*
* This configuration value resets the device to the
u8 outinbit;
u32 epcfgreg;
- switch (ch9_cmdbuf.byte0.bmRequestType) {
+ switch (ch9_cmdbuf.setup.bRequestType) {
case STANDARD_OUT_DEVICE:
- switch (ch9_cmdbuf.word1.wValue) {
+ switch (ch9_cmdbuf.setup.wValue) {
case USB_DEVICE_REMOTE_WAKEUP:
/* User needs to add code here.*/
break;
break;
case STANDARD_OUT_ENDPOINT:
- if (!ch9_cmdbuf.word1.wValue) {
- endpoint = ch9_cmdbuf.word2.wIndex & 0xf;
- outinbit = ch9_cmdbuf.word2.wIndex & 0x80;
+ if (!ch9_cmdbuf.setup.wValue) {
+ endpoint = ch9_cmdbuf.setup.wIndex & 0xf;
+ outinbit = ch9_cmdbuf.setup.wIndex & 0x80;
outinbit = outinbit >> 7;
/* Make sure direction matches.*/
static int execute_command(struct xusb_udc *udc)
{
- if ((ch9_cmdbuf.byte0.bmRequestType & USB_TYPE_MASK) ==
+ if ((ch9_cmdbuf.setup.bRequestType & USB_TYPE_MASK) ==
USB_TYPE_STANDARD) {
/* Process the chapter 9 command.*/
- switch (ch9_cmdbuf.byte1.bRequest) {
+ switch (ch9_cmdbuf.setup.bRequest) {
case USB_REQ_CLEAR_FEATURE:
set_clear_feature(udc, 0);
case USB_REQ_SET_CONFIGURATION:
set_configuration(udc);
- return ch9_cmdbuf.byte1.bRequest;
+ return ch9_cmdbuf.setup.bRequest;
default:
/*
* Return the same request to application for
* handling.
*/
- return ch9_cmdbuf.byte1.bRequest;
+ return ch9_cmdbuf.setup.bRequest;
}
} else
- if ((ch9_cmdbuf.byte0.bmRequestType & USB_TYPE_MASK) ==
+ if ((ch9_cmdbuf.setup.bRequestType & USB_TYPE_MASK) ==
USB_TYPE_CLASS)
- return ch9_cmdbuf.byte1.bRequest;
-
+ return ch9_cmdbuf.setup.bRequest;
return 0;
}
/* Load up the chapter 9 command buffer.*/
ep0rambase = (u32 __force *) (udc->base_address +
XUSB_SETUP_PKT_ADDR_OFFSET);
+ memcpy((void *)&ch9_cmdbuf.setup, (void *)ep0rambase, 8);
- /* Get the first 4 bytes of the setup packet */
- usbmemdata.word = *ep0rambase;
- ch9_cmdbuf.byte0.bmRequestType = usbmemdata.byte.zero;
- ch9_cmdbuf.byte1.bRequest = usbmemdata.byte.one;
- ch9_cmdbuf.word1.byte23.bDescriptorIndex = usbmemdata.byte.two;
- ch9_cmdbuf.word1.byte23.bDescriptorType = usbmemdata.byte.three;
-
- /* Get the last 4 bytes of the setup packet.*/
- ep0rambase += 1;
- usbmemdata.word = *ep0rambase;
+ ctrl->bRequestType = ch9_cmdbuf.setup.bRequestType;
+ ctrl->bRequest = ch9_cmdbuf.setup.bRequest;
+ ctrl->wValue = ch9_cmdbuf.setup.wValue;
+ ctrl->wIndex = ch9_cmdbuf.setup.wIndex;
+ ctrl->wLength = ch9_cmdbuf.setup.wLength;
- /*
- * Byte swapping for next 4 bytes for BE machines is defined in
- * the different layout of BECB verses LECB.
- */
- ch9_cmdbuf.word2.byte45.bytel = usbmemdata.byte.zero;
- ch9_cmdbuf.word2.byte45.byteh = usbmemdata.byte.one;
- ch9_cmdbuf.word3.byte67.bytel = usbmemdata.byte.two;
- ch9_cmdbuf.word3.byte67.byteh = usbmemdata.byte.three;
- ctrl->bRequestType = ch9_cmdbuf.byte0.bmRequestType;
- ctrl->bRequest = ch9_cmdbuf.byte1.bRequest;
- ctrl->wValue = cpu_to_le16(ch9_cmdbuf.word1.wValue);
- ctrl->wIndex = cpu_to_le16(ch9_cmdbuf.word2.wIndex);
- ctrl->wLength = cpu_to_le16(ch9_cmdbuf.word3.wLength);
+ ch9_cmdbuf.setup.wValue = cpu_to_le16(ch9_cmdbuf.setup.wValue);
+ ch9_cmdbuf.setup.wIndex = cpu_to_le16(ch9_cmdbuf.setup.wIndex);
+ ch9_cmdbuf.setup.wLength = cpu_to_le16(ch9_cmdbuf.setup.wLength);
/* Restore ReadPtr to data buffer.*/
ch9_cmdbuf.contreadptr = &ch9_cmdbuf.contreaddatabuffer[0];
- if (ch9_cmdbuf.byte0.bmRequestType & USB_DIR_IN) {
+ if (ch9_cmdbuf.setup.bRequestType & USB_DIR_IN) {
/* Execute the get command.*/
ch9_cmdbuf.setupseqrx = STATUS_PHASE;
ch9_cmdbuf.setupseqtx = DATA_PHASE;
/* Execute the put command.*/
ch9_cmdbuf.setupseqrx = DATA_PHASE;
ch9_cmdbuf.setupseqtx = STATUS_PHASE;
- if (!ch9_cmdbuf.word3.wLength)
+ if (!ch9_cmdbuf.setup.wLength)
return execute_command(udc);
}
/* Control should never come here.*/
XUSB_EP_BUF0COUNT_OFFSET));
udc->write_fn(1, (udc->base_address + XUSB_BUFFREADY_OFFSET));
- if (ch9_cmdbuf.word3.wLength == ch9_cmdbuf.contreadcount)
+ if (ch9_cmdbuf.setup.wLength == ch9_cmdbuf.contreadcount)
execute_command(udc);
break;
switch (ch9_cmdbuf.setupseqtx) {
case STATUS_PHASE:
- if (ch9_cmdbuf.byte1.bRequest == USB_REQ_SET_ADDRESS) {
+ if (ch9_cmdbuf.setup.bRequest == USB_REQ_SET_ADDRESS) {
/* Set the address of the device.*/
- udc->write_fn(ch9_cmdbuf.word1.byte23.bDescriptorIndex,
+ udc->write_fn(ch9_cmdbuf.setup.wValue,
(udc->base_address +
XUSB_ADDRESS_OFFSET));
} else
- if (ch9_cmdbuf.byte1.bRequest == USB_REQ_SET_FEATURE) {
- if (ch9_cmdbuf.byte0.bmRequestType ==
+ if (ch9_cmdbuf.setup.bRequest == USB_REQ_SET_FEATURE) {
+ if (ch9_cmdbuf.setup.bRequestType ==
STANDARD_OUT_DEVICE) {
- if (ch9_cmdbuf.word1.wValue ==
+ if (ch9_cmdbuf.setup.wValue ==
USB_DEVICE_TEST_MODE)
udc->write_fn(TEST_J,
(udc->base_address +
spin_lock_init(&udc->lock);
+ /* Check for IP endianness */
+ udc->write_fn(TEST_J, (udc->base_address + XUSB_TESTMODE_OFFSET));
+ if ((udc->read_fn(udc->base_address + XUSB_TESTMODE_OFFSET))
+ != TEST_J) {
+ controller.write_fn = xusb_write32;
+ controller.read_fn = xusb_read32;
+ }
+ udc->write_fn(0, (udc->base_address + XUSB_TESTMODE_OFFSET));
xudc_reinit(udc);
/* Set device address to 0.*/