copy_bdt.c
1.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*HEADER******************************************************************
**************************************************************************
***
*** Copyright (c) 2001-2002 ARC International.
*** All rights reserved
***
*** This software embodies materials and concepts which are
*** confidential to ARC International and is made
*** available solely pursuant to the terms of a written license
*** agreement with ARC International
***
*** File: vusbh11.c
***
*** Comments:
*** This file contains the low-level Host API functions specific to the VUSB
*** chip.
***
**************************************************************************
*END*********************************************************************/
#include "osint.h"
/*
* BDTs are in special SRAM which only supports 32 bit accesses.
* What's more the ARC core accesses the BDTs as Little Endian.
* The ARC driver code assumes it can whack bytes in the BDTS.
* So both the word only access problem and the endianness can
* be solved by unwrapping the BDT into a buffer and then
* rewrapping it on output.
*/
void _usb_bdt_copy_swab(HOST_BDT_STRUCT_PTR from_bdt, HOST_BDT_STRUCT_PTR to_bdt)
{
struct work {
uint_32 w1;
uint_32 w2;
};
register uint_32 x, y;
/*
* Be careful we don't do more accesses to the HW than necessary.
*
* Another subtlety is that word1 must be updated last, since it
* contains the OWN bit which is the semaphore between the cpu
* and the VUSB hardware.
*/
x = ((struct work *)from_bdt)->w2;
y = swab32(x);
((struct work *)to_bdt)->w2 = y;
x = ((struct work *)from_bdt)->w1;
y = swab32(x);
((struct work *)to_bdt)->w1 = y;
/*
* Note that the BDT pointers are K1 addresses (uncached), so
* there is no need to do a writeback here.
*/
}