diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/usb-s3c6400x.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/firmware/target/arm/usb-s3c6400x.c b/firmware/target/arm/usb-s3c6400x.c index af90be6944..4476549aa7 100644 --- a/firmware/target/arm/usb-s3c6400x.c +++ b/firmware/target/arm/usb-s3c6400x.c | |||
@@ -48,10 +48,18 @@ struct ep_type | |||
48 | } ; | 48 | } ; |
49 | 49 | ||
50 | static struct ep_type endpoints[USB_NUM_ENDPOINTS]; | 50 | static struct ep_type endpoints[USB_NUM_ENDPOINTS]; |
51 | static union | 51 | |
52 | /* USB control requests may be up to 64 bytes in size. | ||
53 | Even though we never use anything more than the 8 header bytes, | ||
54 | we are required to accept request packets of up to 64 bytes size. | ||
55 | Provide buffer space for these additional payload bytes so that | ||
56 | e.g. write descriptor requests (which are rejected by us, but the | ||
57 | payload is transferred anyway) do not cause memory corruption. | ||
58 | Fixes FS#12310. -- Michael Sparmann (theseven) */ | ||
59 | static struct | ||
52 | { | 60 | { |
53 | unsigned char data[64]; | 61 | struct usb_ctrlrequest header; /* 8 bytes */ |
54 | struct usb_ctrlrequest req; | 62 | unsigned char payload[64 - sizeof(struct usb_ctrlrequest)]; |
55 | } ctrlreq USB_DEVBSS_ATTR; | 63 | } ctrlreq USB_DEVBSS_ATTR; |
56 | 64 | ||
57 | int usb_drv_port_speed(void) | 65 | int usb_drv_port_speed(void) |
@@ -74,7 +82,7 @@ static void reset_endpoints(int reinit) | |||
74 | DOEPCTL0 = 0x8000; /* EP0 OUT ACTIVE */ | 82 | DOEPCTL0 = 0x8000; /* EP0 OUT ACTIVE */ |
75 | DOEPTSIZ0 = 0x20080040; /* EP0 OUT Transfer Size: | 83 | DOEPTSIZ0 = 0x20080040; /* EP0 OUT Transfer Size: |
76 | 64 Bytes, 1 Packet, 1 Setup Packet */ | 84 | 64 Bytes, 1 Packet, 1 Setup Packet */ |
77 | DOEPDMA0 = &ctrlreq.data; | 85 | DOEPDMA0 = &ctrlreq; |
78 | DOEPCTL0 |= 0x84000000; /* EP0 OUT ENABLE CLEARNAK */ | 86 | DOEPCTL0 |= 0x84000000; /* EP0 OUT ENABLE CLEARNAK */ |
79 | if (reinit) | 87 | if (reinit) |
80 | { | 88 | { |
@@ -247,14 +255,14 @@ void INT_USB_FUNC(void) | |||
247 | invalidate_dcache(); | 255 | invalidate_dcache(); |
248 | if (i == 0) | 256 | if (i == 0) |
249 | { | 257 | { |
250 | if (ctrlreq.req.bRequest == 5) | 258 | if (ctrlreq.header.bRequest == 5) |
251 | { | 259 | { |
252 | /* Already set the new address here, | 260 | /* Already set the new address here, |
253 | before passing the packet to the core. | 261 | before passing the packet to the core. |
254 | See below (usb_drv_set_address) for details. */ | 262 | See below (usb_drv_set_address) for details. */ |
255 | DCFG = (DCFG & ~0x7F0) | (ctrlreq.req.wValue << 4); | 263 | DCFG = (DCFG & ~0x7F0) | (ctrlreq.header.wValue << 4); |
256 | } | 264 | } |
257 | usb_core_control_request(&ctrlreq.req); | 265 | usb_core_control_request(&ctrlreq.header); |
258 | } | 266 | } |
259 | else panicf("USB: SETUP done on OUT EP%d!?", i); | 267 | else panicf("USB: SETUP done on OUT EP%d!?", i); |
260 | } | 268 | } |
@@ -262,7 +270,7 @@ void INT_USB_FUNC(void) | |||
262 | if (!i) | 270 | if (!i) |
263 | { | 271 | { |
264 | DOEPTSIZ0 = 0x20080040; | 272 | DOEPTSIZ0 = 0x20080040; |
265 | DOEPDMA0 = &ctrlreq.data; | 273 | DOEPDMA0 = &ctrlreq; |
266 | DOEPCTL0 |= 0x84000000; | 274 | DOEPCTL0 |= 0x84000000; |
267 | } | 275 | } |
268 | DOEPINT(i) = epints; | 276 | DOEPINT(i) = epints; |