blob: 9d268d1f3ea5f94a64bb9c7062ec17c5bb88c837 [file] [log] [blame]
David Lopoaa69a802008-11-17 14:14:51 -08001/*
2 * ci13xxx_udc.c - MIPS USB IP core family device controller
3 *
4 * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
5 *
6 * Author: David Lopo
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13/*
14 * Description: MIPS USB IP core family device controller
15 * Currently it only supports IP part number CI13412
16 *
17 * This driver is composed of several blocks:
18 * - HW: hardware interface
19 * - DBG: debug facilities (optional)
20 * - UTIL: utilities
21 * - ISR: interrupts handling
22 * - ENDPT: endpoint operations (Gadget API)
23 * - GADGET: gadget operations (Gadget API)
24 * - BUS: bus glue code, bus abstraction layer
David Lopoaa69a802008-11-17 14:14:51 -080025 *
26 * Compile Options
27 * - CONFIG_USB_GADGET_DEBUG_FILES: enable debug facilities
28 * - STALL_IN: non-empty bulk-in pipes cannot be halted
29 * if defined mass storage compliance succeeds but with warnings
30 * => case 4: Hi > Dn
31 * => case 5: Hi > Di
32 * => case 8: Hi <> Do
33 * if undefined usbtest 13 fails
34 * - TRACE: enable function tracing (depends on DEBUG)
35 *
36 * Main Features
37 * - Chapter 9 & Mass Storage Compliance with Gadget File Storage
38 * - Chapter 9 Compliance with Gadget Zero (STALL_IN undefined)
39 * - Normal & LPM support
40 *
41 * USBTEST Report
42 * - OK: 0-12, 13 (STALL_IN defined) & 14
43 * - Not Supported: 15 & 16 (ISO)
44 *
45 * TODO List
46 * - OTG
47 * - Isochronous & Interrupt Traffic
48 * - Handle requests which spawns into several TDs
49 * - GET_STATUS(device) - always reports 0
50 * - Gadget API (majority of optional features)
51 * - Suspend & Remote Wakeup
52 */
Matthias Kaehlcke36825a22009-04-15 22:28:36 +020053#include <linux/delay.h>
David Lopoaa69a802008-11-17 14:14:51 -080054#include <linux/device.h>
55#include <linux/dmapool.h>
56#include <linux/dma-mapping.h>
57#include <linux/init.h>
58#include <linux/interrupt.h>
David Lopoaa69a802008-11-17 14:14:51 -080059#include <linux/io.h>
60#include <linux/irq.h>
61#include <linux/kernel.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090062#include <linux/slab.h>
Pavankumar Kondetic0360192010-12-07 17:54:04 +053063#include <linux/pm_runtime.h>
David Lopoaa69a802008-11-17 14:14:51 -080064#include <linux/usb/ch9.h>
65#include <linux/usb/gadget.h>
Pavankumar Kondetif01ef572010-12-07 17:54:02 +053066#include <linux/usb/otg.h>
David Lopoaa69a802008-11-17 14:14:51 -080067
68#include "ci13xxx_udc.h"
69
70
71/******************************************************************************
72 * DEFINE
73 *****************************************************************************/
74/* ctrl register bank access */
75static DEFINE_SPINLOCK(udc_lock);
76
David Lopoaa69a802008-11-17 14:14:51 -080077/* control endpoint description */
78static const struct usb_endpoint_descriptor
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +053079ctrl_endpt_out_desc = {
David Lopoaa69a802008-11-17 14:14:51 -080080 .bLength = USB_DT_ENDPOINT_SIZE,
81 .bDescriptorType = USB_DT_ENDPOINT,
82
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +053083 .bEndpointAddress = USB_DIR_OUT,
84 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
85 .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX),
86};
87
88static const struct usb_endpoint_descriptor
89ctrl_endpt_in_desc = {
90 .bLength = USB_DT_ENDPOINT_SIZE,
91 .bDescriptorType = USB_DT_ENDPOINT,
92
93 .bEndpointAddress = USB_DIR_IN,
David Lopoaa69a802008-11-17 14:14:51 -080094 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
95 .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX),
96};
97
98/* UDC descriptor */
99static struct ci13xxx *_udc;
100
101/* Interrupt statistics */
102#define ISR_MASK 0x1F
103static struct {
104 u32 test;
105 u32 ui;
106 u32 uei;
107 u32 pci;
108 u32 uri;
109 u32 sli;
110 u32 none;
111 struct {
112 u32 cnt;
113 u32 buf[ISR_MASK+1];
114 u32 idx;
115 } hndl;
116} isr_statistics;
117
118/**
119 * ffs_nr: find first (least significant) bit set
120 * @x: the word to search
121 *
122 * This function returns bit number (instead of position)
123 */
124static int ffs_nr(u32 x)
125{
126 int n = ffs(x);
127
128 return n ? n-1 : 32;
129}
130
131/******************************************************************************
132 * HW block
133 *****************************************************************************/
134/* register bank descriptor */
135static struct {
136 unsigned lpm; /* is LPM? */
137 void __iomem *abs; /* bus map offset */
138 void __iomem *cap; /* bus map offset + CAP offset + CAP data */
139 size_t size; /* bank size */
140} hw_bank;
141
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530142/* MSM specific */
143#define ABS_AHBBURST (0x0090UL)
144#define ABS_AHBMODE (0x0098UL)
David Lopoaa69a802008-11-17 14:14:51 -0800145/* UDC register map */
146#define ABS_CAPLENGTH (0x100UL)
147#define ABS_HCCPARAMS (0x108UL)
148#define ABS_DCCPARAMS (0x124UL)
149#define ABS_TESTMODE (hw_bank.lpm ? 0x0FCUL : 0x138UL)
150/* offset to CAPLENTGH (addr + data) */
151#define CAP_USBCMD (0x000UL)
152#define CAP_USBSTS (0x004UL)
153#define CAP_USBINTR (0x008UL)
154#define CAP_DEVICEADDR (0x014UL)
155#define CAP_ENDPTLISTADDR (0x018UL)
156#define CAP_PORTSC (0x044UL)
David Lopof23e6492009-04-16 14:35:24 -0700157#define CAP_DEVLC (0x084UL)
David Lopoaa69a802008-11-17 14:14:51 -0800158#define CAP_USBMODE (hw_bank.lpm ? 0x0C8UL : 0x068UL)
159#define CAP_ENDPTSETUPSTAT (hw_bank.lpm ? 0x0D8UL : 0x06CUL)
160#define CAP_ENDPTPRIME (hw_bank.lpm ? 0x0DCUL : 0x070UL)
161#define CAP_ENDPTFLUSH (hw_bank.lpm ? 0x0E0UL : 0x074UL)
162#define CAP_ENDPTSTAT (hw_bank.lpm ? 0x0E4UL : 0x078UL)
163#define CAP_ENDPTCOMPLETE (hw_bank.lpm ? 0x0E8UL : 0x07CUL)
164#define CAP_ENDPTCTRL (hw_bank.lpm ? 0x0ECUL : 0x080UL)
165#define CAP_LAST (hw_bank.lpm ? 0x12CUL : 0x0C0UL)
166
167/* maximum number of enpoints: valid only after hw_device_reset() */
168static unsigned hw_ep_max;
169
170/**
171 * hw_ep_bit: calculates the bit number
172 * @num: endpoint number
173 * @dir: endpoint direction
174 *
175 * This function returns bit number
176 */
177static inline int hw_ep_bit(int num, int dir)
178{
179 return num + (dir ? 16 : 0);
180}
181
182/**
183 * hw_aread: reads from register bitfield
184 * @addr: address relative to bus map
185 * @mask: bitfield mask
186 *
187 * This function returns register bitfield data
188 */
189static u32 hw_aread(u32 addr, u32 mask)
190{
191 return ioread32(addr + hw_bank.abs) & mask;
192}
193
194/**
195 * hw_awrite: writes to register bitfield
196 * @addr: address relative to bus map
197 * @mask: bitfield mask
198 * @data: new data
199 */
200static void hw_awrite(u32 addr, u32 mask, u32 data)
201{
202 iowrite32(hw_aread(addr, ~mask) | (data & mask),
203 addr + hw_bank.abs);
204}
205
206/**
207 * hw_cread: reads from register bitfield
208 * @addr: address relative to CAP offset plus content
209 * @mask: bitfield mask
210 *
211 * This function returns register bitfield data
212 */
213static u32 hw_cread(u32 addr, u32 mask)
214{
215 return ioread32(addr + hw_bank.cap) & mask;
216}
217
218/**
219 * hw_cwrite: writes to register bitfield
220 * @addr: address relative to CAP offset plus content
221 * @mask: bitfield mask
222 * @data: new data
223 */
224static void hw_cwrite(u32 addr, u32 mask, u32 data)
225{
226 iowrite32(hw_cread(addr, ~mask) | (data & mask),
227 addr + hw_bank.cap);
228}
229
230/**
231 * hw_ctest_and_clear: tests & clears register bitfield
232 * @addr: address relative to CAP offset plus content
233 * @mask: bitfield mask
234 *
235 * This function returns register bitfield data
236 */
237static u32 hw_ctest_and_clear(u32 addr, u32 mask)
238{
239 u32 reg = hw_cread(addr, mask);
240
241 iowrite32(reg, addr + hw_bank.cap);
242 return reg;
243}
244
245/**
246 * hw_ctest_and_write: tests & writes register bitfield
247 * @addr: address relative to CAP offset plus content
248 * @mask: bitfield mask
249 * @data: new data
250 *
251 * This function returns register bitfield data
252 */
253static u32 hw_ctest_and_write(u32 addr, u32 mask, u32 data)
254{
255 u32 reg = hw_cread(addr, ~0);
256
257 iowrite32((reg & ~mask) | (data & mask), addr + hw_bank.cap);
258 return (reg & mask) >> ffs_nr(mask);
259}
260
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530261static int hw_device_init(void __iomem *base)
David Lopoaa69a802008-11-17 14:14:51 -0800262{
263 u32 reg;
264
265 /* bank is a module variable */
266 hw_bank.abs = base;
267
268 hw_bank.cap = hw_bank.abs;
269 hw_bank.cap += ABS_CAPLENGTH;
270 hw_bank.cap += ioread8(hw_bank.cap);
271
272 reg = hw_aread(ABS_HCCPARAMS, HCCPARAMS_LEN) >> ffs_nr(HCCPARAMS_LEN);
273 hw_bank.lpm = reg;
274 hw_bank.size = hw_bank.cap - hw_bank.abs;
275 hw_bank.size += CAP_LAST;
276 hw_bank.size /= sizeof(u32);
277
David Lopoaa69a802008-11-17 14:14:51 -0800278 reg = hw_aread(ABS_DCCPARAMS, DCCPARAMS_DEN) >> ffs_nr(DCCPARAMS_DEN);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +0530279 hw_ep_max = reg * 2; /* cache hw ENDPT_MAX */
David Lopoaa69a802008-11-17 14:14:51 -0800280
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +0530281 if (hw_ep_max == 0 || hw_ep_max > ENDPT_MAX)
282 return -ENODEV;
David Lopoaa69a802008-11-17 14:14:51 -0800283
284 /* setup lock mode ? */
285
286 /* ENDPTSETUPSTAT is '0' by default */
287
288 /* HCSPARAMS.bf.ppc SHOULD BE zero for device */
289
290 return 0;
291}
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530292/**
293 * hw_device_reset: resets chip (execute without interruption)
294 * @base: register base address
295 *
296 * This function returns an error code
297 */
298static int hw_device_reset(struct ci13xxx *udc)
299{
300 /* should flush & stop before reset */
301 hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0);
302 hw_cwrite(CAP_USBCMD, USBCMD_RS, 0);
303
304 hw_cwrite(CAP_USBCMD, USBCMD_RST, USBCMD_RST);
305 while (hw_cread(CAP_USBCMD, USBCMD_RST))
306 udelay(10); /* not RTOS friendly */
307
308
309 if (udc->udc_driver->notify_event)
310 udc->udc_driver->notify_event(udc,
311 CI13XXX_CONTROLLER_RESET_EVENT);
312
Pavankumar Kondeti8c2387a2011-05-02 11:56:28 +0530313 if (udc->udc_driver->flags & CI13XXX_DISABLE_STREAMING)
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530314 hw_cwrite(CAP_USBMODE, USBMODE_SDIS, USBMODE_SDIS);
315
316 /* USBMODE should be configured step by step */
317 hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE);
318 hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_DEVICE);
319 hw_cwrite(CAP_USBMODE, USBMODE_SLOM, USBMODE_SLOM); /* HW >= 2.3 */
320
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700321 /*
322 * ITC (Interrupt Threshold Control) field is to set the maximum
323 * rate at which the device controller will issue interrupts.
324 * The maximum interrupt interval measured in micro frames.
325 * Valid values are 0, 1, 2, 4, 8, 16, 32, 64. The default value is
326 * 8 micro frames. If CPU can handle interrupts at faster rate, ITC
327 * can be set to lesser value to gain performance.
328 */
329 if (udc->udc_driver->flags & CI13XXX_ZERO_ITC)
330 hw_cwrite(CAP_USBCMD, USBCMD_ITC_MASK, USBCMD_ITC(0));
331
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530332 if (hw_cread(CAP_USBMODE, USBMODE_CM) != USBMODE_CM_DEVICE) {
333 pr_err("cannot enter in device mode");
334 pr_err("lpm = %i", hw_bank.lpm);
335 return -ENODEV;
336 }
337
338 return 0;
339}
David Lopoaa69a802008-11-17 14:14:51 -0800340
341/**
342 * hw_device_state: enables/disables interrupts & starts/stops device (execute
343 * without interruption)
344 * @dma: 0 => disable, !0 => enable and set dma engine
345 *
346 * This function returns an error code
347 */
348static int hw_device_state(u32 dma)
349{
350 if (dma) {
351 hw_cwrite(CAP_ENDPTLISTADDR, ~0, dma);
352 /* interrupt, error, port change, reset, sleep/suspend */
353 hw_cwrite(CAP_USBINTR, ~0,
354 USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI);
355 hw_cwrite(CAP_USBCMD, USBCMD_RS, USBCMD_RS);
356 } else {
357 hw_cwrite(CAP_USBCMD, USBCMD_RS, 0);
358 hw_cwrite(CAP_USBINTR, ~0, 0);
359 }
360 return 0;
361}
362
363/**
364 * hw_ep_flush: flush endpoint fifo (execute without interruption)
365 * @num: endpoint number
366 * @dir: endpoint direction
367 *
368 * This function returns an error code
369 */
370static int hw_ep_flush(int num, int dir)
371{
372 int n = hw_ep_bit(num, dir);
373
374 do {
375 /* flush any pending transfer */
376 hw_cwrite(CAP_ENDPTFLUSH, BIT(n), BIT(n));
377 while (hw_cread(CAP_ENDPTFLUSH, BIT(n)))
378 cpu_relax();
379 } while (hw_cread(CAP_ENDPTSTAT, BIT(n)));
380
381 return 0;
382}
383
384/**
385 * hw_ep_disable: disables endpoint (execute without interruption)
386 * @num: endpoint number
387 * @dir: endpoint direction
388 *
389 * This function returns an error code
390 */
391static int hw_ep_disable(int num, int dir)
392{
393 hw_ep_flush(num, dir);
394 hw_cwrite(CAP_ENDPTCTRL + num * sizeof(u32),
395 dir ? ENDPTCTRL_TXE : ENDPTCTRL_RXE, 0);
396 return 0;
397}
398
399/**
400 * hw_ep_enable: enables endpoint (execute without interruption)
401 * @num: endpoint number
402 * @dir: endpoint direction
403 * @type: endpoint type
404 *
405 * This function returns an error code
406 */
407static int hw_ep_enable(int num, int dir, int type)
408{
409 u32 mask, data;
410
411 if (dir) {
412 mask = ENDPTCTRL_TXT; /* type */
413 data = type << ffs_nr(mask);
414
415 mask |= ENDPTCTRL_TXS; /* unstall */
416 mask |= ENDPTCTRL_TXR; /* reset data toggle */
417 data |= ENDPTCTRL_TXR;
418 mask |= ENDPTCTRL_TXE; /* enable */
419 data |= ENDPTCTRL_TXE;
420 } else {
421 mask = ENDPTCTRL_RXT; /* type */
422 data = type << ffs_nr(mask);
423
424 mask |= ENDPTCTRL_RXS; /* unstall */
425 mask |= ENDPTCTRL_RXR; /* reset data toggle */
426 data |= ENDPTCTRL_RXR;
427 mask |= ENDPTCTRL_RXE; /* enable */
428 data |= ENDPTCTRL_RXE;
429 }
430 hw_cwrite(CAP_ENDPTCTRL + num * sizeof(u32), mask, data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700431
432 /* make sure endpoint is enabled before returning */
433 mb();
434
David Lopoaa69a802008-11-17 14:14:51 -0800435 return 0;
436}
437
438/**
439 * hw_ep_get_halt: return endpoint halt status
440 * @num: endpoint number
441 * @dir: endpoint direction
442 *
443 * This function returns 1 if endpoint halted
444 */
445static int hw_ep_get_halt(int num, int dir)
446{
447 u32 mask = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
448
449 return hw_cread(CAP_ENDPTCTRL + num * sizeof(u32), mask) ? 1 : 0;
450}
451
452/**
David Lopoaa69a802008-11-17 14:14:51 -0800453 * hw_test_and_clear_setup_status: test & clear setup status (execute without
454 * interruption)
455 * @n: bit number (endpoint)
456 *
457 * This function returns setup status
458 */
459static int hw_test_and_clear_setup_status(int n)
460{
461 return hw_ctest_and_clear(CAP_ENDPTSETUPSTAT, BIT(n));
462}
463
464/**
465 * hw_ep_prime: primes endpoint (execute without interruption)
466 * @num: endpoint number
467 * @dir: endpoint direction
468 * @is_ctrl: true if control endpoint
469 *
470 * This function returns an error code
471 */
472static int hw_ep_prime(int num, int dir, int is_ctrl)
473{
474 int n = hw_ep_bit(num, dir);
475
David Lopoaa69a802008-11-17 14:14:51 -0800476 if (is_ctrl && dir == RX && hw_cread(CAP_ENDPTSETUPSTAT, BIT(num)))
477 return -EAGAIN;
478
479 hw_cwrite(CAP_ENDPTPRIME, BIT(n), BIT(n));
480
481 while (hw_cread(CAP_ENDPTPRIME, BIT(n)))
482 cpu_relax();
483 if (is_ctrl && dir == RX && hw_cread(CAP_ENDPTSETUPSTAT, BIT(num)))
484 return -EAGAIN;
485
486 /* status shoult be tested according with manual but it doesn't work */
487 return 0;
488}
489
490/**
491 * hw_ep_set_halt: configures ep halt & resets data toggle after clear (execute
492 * without interruption)
493 * @num: endpoint number
494 * @dir: endpoint direction
495 * @value: true => stall, false => unstall
496 *
497 * This function returns an error code
498 */
499static int hw_ep_set_halt(int num, int dir, int value)
500{
Pavankumar Kondeti05598942011-07-06 16:58:44 +0530501 u32 addr, mask_xs, mask_xr;
502
David Lopoaa69a802008-11-17 14:14:51 -0800503 if (value != 0 && value != 1)
504 return -EINVAL;
505
506 do {
Pavankumar Kondeti05598942011-07-06 16:58:44 +0530507 if (hw_cread(CAP_ENDPTSETUPSTAT, BIT(num)))
508 return 0;
509
510 addr = CAP_ENDPTCTRL + num * sizeof(u32);
511 mask_xs = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
512 mask_xr = dir ? ENDPTCTRL_TXR : ENDPTCTRL_RXR;
David Lopoaa69a802008-11-17 14:14:51 -0800513
514 /* data toggle - reserved for EP0 but it's in ESS */
515 hw_cwrite(addr, mask_xs|mask_xr, value ? mask_xs : mask_xr);
516
517 } while (value != hw_ep_get_halt(num, dir));
518
519 return 0;
520}
521
522/**
523 * hw_intr_clear: disables interrupt & clears interrupt status (execute without
524 * interruption)
525 * @n: interrupt bit
526 *
527 * This function returns an error code
528 */
529static int hw_intr_clear(int n)
530{
531 if (n >= REG_BITS)
532 return -EINVAL;
533
534 hw_cwrite(CAP_USBINTR, BIT(n), 0);
535 hw_cwrite(CAP_USBSTS, BIT(n), BIT(n));
536 return 0;
537}
538
539/**
540 * hw_intr_force: enables interrupt & forces interrupt status (execute without
541 * interruption)
542 * @n: interrupt bit
543 *
544 * This function returns an error code
545 */
546static int hw_intr_force(int n)
547{
548 if (n >= REG_BITS)
549 return -EINVAL;
550
551 hw_awrite(ABS_TESTMODE, TESTMODE_FORCE, TESTMODE_FORCE);
552 hw_cwrite(CAP_USBINTR, BIT(n), BIT(n));
553 hw_cwrite(CAP_USBSTS, BIT(n), BIT(n));
554 hw_awrite(ABS_TESTMODE, TESTMODE_FORCE, 0);
555 return 0;
556}
557
558/**
559 * hw_is_port_high_speed: test if port is high speed
560 *
561 * This function returns true if high speed port
562 */
563static int hw_port_is_high_speed(void)
564{
565 return hw_bank.lpm ? hw_cread(CAP_DEVLC, DEVLC_PSPD) :
566 hw_cread(CAP_PORTSC, PORTSC_HSP);
567}
568
569/**
570 * hw_port_test_get: reads port test mode value
571 *
572 * This function returns port test mode value
573 */
574static u8 hw_port_test_get(void)
575{
576 return hw_cread(CAP_PORTSC, PORTSC_PTC) >> ffs_nr(PORTSC_PTC);
577}
578
579/**
580 * hw_port_test_set: writes port test mode (execute without interruption)
581 * @mode: new value
582 *
583 * This function returns an error code
584 */
585static int hw_port_test_set(u8 mode)
586{
587 const u8 TEST_MODE_MAX = 7;
588
589 if (mode > TEST_MODE_MAX)
590 return -EINVAL;
591
592 hw_cwrite(CAP_PORTSC, PORTSC_PTC, mode << ffs_nr(PORTSC_PTC));
593 return 0;
594}
595
596/**
597 * hw_read_intr_enable: returns interrupt enable register
598 *
599 * This function returns register data
600 */
601static u32 hw_read_intr_enable(void)
602{
603 return hw_cread(CAP_USBINTR, ~0);
604}
605
606/**
607 * hw_read_intr_status: returns interrupt status register
608 *
609 * This function returns register data
610 */
611static u32 hw_read_intr_status(void)
612{
613 return hw_cread(CAP_USBSTS, ~0);
614}
615
616/**
617 * hw_register_read: reads all device registers (execute without interruption)
618 * @buf: destination buffer
619 * @size: buffer size
620 *
621 * This function returns number of registers read
622 */
623static size_t hw_register_read(u32 *buf, size_t size)
624{
625 unsigned i;
626
627 if (size > hw_bank.size)
628 size = hw_bank.size;
629
630 for (i = 0; i < size; i++)
631 buf[i] = hw_aread(i * sizeof(u32), ~0);
632
633 return size;
634}
635
636/**
637 * hw_register_write: writes to register
638 * @addr: register address
639 * @data: register value
640 *
641 * This function returns an error code
642 */
643static int hw_register_write(u16 addr, u32 data)
644{
645 /* align */
646 addr /= sizeof(u32);
647
648 if (addr >= hw_bank.size)
649 return -EINVAL;
650
651 /* align */
652 addr *= sizeof(u32);
653
654 hw_awrite(addr, ~0, data);
655 return 0;
656}
657
658/**
659 * hw_test_and_clear_complete: test & clear complete status (execute without
660 * interruption)
661 * @n: bit number (endpoint)
662 *
663 * This function returns complete status
664 */
665static int hw_test_and_clear_complete(int n)
666{
667 return hw_ctest_and_clear(CAP_ENDPTCOMPLETE, BIT(n));
668}
669
670/**
671 * hw_test_and_clear_intr_active: test & clear active interrupts (execute
672 * without interruption)
673 *
674 * This function returns active interrutps
675 */
676static u32 hw_test_and_clear_intr_active(void)
677{
678 u32 reg = hw_read_intr_status() & hw_read_intr_enable();
679
680 hw_cwrite(CAP_USBSTS, ~0, reg);
681 return reg;
682}
683
684/**
685 * hw_test_and_clear_setup_guard: test & clear setup guard (execute without
686 * interruption)
687 *
688 * This function returns guard value
689 */
690static int hw_test_and_clear_setup_guard(void)
691{
692 return hw_ctest_and_write(CAP_USBCMD, USBCMD_SUTW, 0);
693}
694
695/**
696 * hw_test_and_set_setup_guard: test & set setup guard (execute without
697 * interruption)
698 *
699 * This function returns guard value
700 */
701static int hw_test_and_set_setup_guard(void)
702{
703 return hw_ctest_and_write(CAP_USBCMD, USBCMD_SUTW, USBCMD_SUTW);
704}
705
706/**
707 * hw_usb_set_address: configures USB address (execute without interruption)
708 * @value: new USB address
709 *
710 * This function returns an error code
711 */
712static int hw_usb_set_address(u8 value)
713{
714 /* advance */
715 hw_cwrite(CAP_DEVICEADDR, DEVICEADDR_USBADR | DEVICEADDR_USBADRA,
716 value << ffs_nr(DEVICEADDR_USBADR) | DEVICEADDR_USBADRA);
717 return 0;
718}
719
720/**
721 * hw_usb_reset: restart device after a bus reset (execute without
722 * interruption)
723 *
724 * This function returns an error code
725 */
726static int hw_usb_reset(void)
727{
728 hw_usb_set_address(0);
729
730 /* ESS flushes only at end?!? */
731 hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0); /* flush all EPs */
732
733 /* clear setup token semaphores */
734 hw_cwrite(CAP_ENDPTSETUPSTAT, 0, 0); /* writes its content */
735
736 /* clear complete status */
737 hw_cwrite(CAP_ENDPTCOMPLETE, 0, 0); /* writes its content */
738
739 /* wait until all bits cleared */
740 while (hw_cread(CAP_ENDPTPRIME, ~0))
741 udelay(10); /* not RTOS friendly */
742
743 /* reset all endpoints ? */
744
745 /* reset internal status and wait for further instructions
746 no need to verify the port reset status (ESS does it) */
747
748 return 0;
749}
750
751/******************************************************************************
752 * DBG block
753 *****************************************************************************/
754/**
755 * show_device: prints information about device capabilities and status
756 *
757 * Check "device.h" for details
758 */
759static ssize_t show_device(struct device *dev, struct device_attribute *attr,
760 char *buf)
761{
762 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
763 struct usb_gadget *gadget = &udc->gadget;
764 int n = 0;
765
766 dbg_trace("[%s] %p\n", __func__, buf);
767 if (attr == NULL || buf == NULL) {
768 dev_err(dev, "[%s] EINVAL\n", __func__);
769 return 0;
770 }
771
772 n += scnprintf(buf + n, PAGE_SIZE - n, "speed = %d\n",
773 gadget->speed);
774 n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n",
775 gadget->is_dualspeed);
776 n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n",
777 gadget->is_otg);
778 n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n",
779 gadget->is_a_peripheral);
780 n += scnprintf(buf + n, PAGE_SIZE - n, "b_hnp_enable = %d\n",
781 gadget->b_hnp_enable);
782 n += scnprintf(buf + n, PAGE_SIZE - n, "a_hnp_support = %d\n",
783 gadget->a_hnp_support);
784 n += scnprintf(buf + n, PAGE_SIZE - n, "a_alt_hnp_support = %d\n",
785 gadget->a_alt_hnp_support);
786 n += scnprintf(buf + n, PAGE_SIZE - n, "name = %s\n",
787 (gadget->name ? gadget->name : ""));
788
789 return n;
790}
791static DEVICE_ATTR(device, S_IRUSR, show_device, NULL);
792
793/**
794 * show_driver: prints information about attached gadget (if any)
795 *
796 * Check "device.h" for details
797 */
798static ssize_t show_driver(struct device *dev, struct device_attribute *attr,
799 char *buf)
800{
801 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
802 struct usb_gadget_driver *driver = udc->driver;
803 int n = 0;
804
805 dbg_trace("[%s] %p\n", __func__, buf);
806 if (attr == NULL || buf == NULL) {
807 dev_err(dev, "[%s] EINVAL\n", __func__);
808 return 0;
809 }
810
811 if (driver == NULL)
812 return scnprintf(buf, PAGE_SIZE,
813 "There is no gadget attached!\n");
814
815 n += scnprintf(buf + n, PAGE_SIZE - n, "function = %s\n",
816 (driver->function ? driver->function : ""));
817 n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n",
818 driver->speed);
819
820 return n;
821}
822static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL);
823
824/* Maximum event message length */
825#define DBG_DATA_MSG 64UL
826
827/* Maximum event messages */
828#define DBG_DATA_MAX 128UL
829
830/* Event buffer descriptor */
831static struct {
832 char (buf[DBG_DATA_MAX])[DBG_DATA_MSG]; /* buffer */
833 unsigned idx; /* index */
834 unsigned tty; /* print to console? */
835 rwlock_t lck; /* lock */
836} dbg_data = {
837 .idx = 0,
838 .tty = 0,
839 .lck = __RW_LOCK_UNLOCKED(lck)
840};
841
842/**
843 * dbg_dec: decrements debug event index
844 * @idx: buffer index
845 */
846static void dbg_dec(unsigned *idx)
847{
848 *idx = (*idx - 1) & (DBG_DATA_MAX-1);
849}
850
851/**
852 * dbg_inc: increments debug event index
853 * @idx: buffer index
854 */
855static void dbg_inc(unsigned *idx)
856{
857 *idx = (*idx + 1) & (DBG_DATA_MAX-1);
858}
859
860/**
861 * dbg_print: prints the common part of the event
862 * @addr: endpoint address
863 * @name: event name
864 * @status: status
865 * @extra: extra information
866 */
867static void dbg_print(u8 addr, const char *name, int status, const char *extra)
868{
869 struct timeval tval;
870 unsigned int stamp;
871 unsigned long flags;
872
873 write_lock_irqsave(&dbg_data.lck, flags);
874
875 do_gettimeofday(&tval);
876 stamp = tval.tv_sec & 0xFFFF; /* 2^32 = 4294967296. Limit to 4096s */
877 stamp = stamp * 1000000 + tval.tv_usec;
878
879 scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG,
880 "%04X\t» %02X %-7.7s %4i «\t%s\n",
881 stamp, addr, name, status, extra);
882
883 dbg_inc(&dbg_data.idx);
884
885 write_unlock_irqrestore(&dbg_data.lck, flags);
886
887 if (dbg_data.tty != 0)
888 pr_notice("%04X\t» %02X %-7.7s %4i «\t%s\n",
889 stamp, addr, name, status, extra);
890}
891
892/**
893 * dbg_done: prints a DONE event
894 * @addr: endpoint address
895 * @td: transfer descriptor
896 * @status: status
897 */
898static void dbg_done(u8 addr, const u32 token, int status)
899{
900 char msg[DBG_DATA_MSG];
901
902 scnprintf(msg, sizeof(msg), "%d %02X",
903 (int)(token & TD_TOTAL_BYTES) >> ffs_nr(TD_TOTAL_BYTES),
904 (int)(token & TD_STATUS) >> ffs_nr(TD_STATUS));
905 dbg_print(addr, "DONE", status, msg);
906}
907
908/**
909 * dbg_event: prints a generic event
910 * @addr: endpoint address
911 * @name: event name
912 * @status: status
913 */
914static void dbg_event(u8 addr, const char *name, int status)
915{
916 if (name != NULL)
917 dbg_print(addr, name, status, "");
918}
919
920/*
921 * dbg_queue: prints a QUEUE event
922 * @addr: endpoint address
923 * @req: USB request
924 * @status: status
925 */
926static void dbg_queue(u8 addr, const struct usb_request *req, int status)
927{
928 char msg[DBG_DATA_MSG];
929
930 if (req != NULL) {
931 scnprintf(msg, sizeof(msg),
932 "%d %d", !req->no_interrupt, req->length);
933 dbg_print(addr, "QUEUE", status, msg);
934 }
935}
936
937/**
938 * dbg_setup: prints a SETUP event
939 * @addr: endpoint address
940 * @req: setup request
941 */
942static void dbg_setup(u8 addr, const struct usb_ctrlrequest *req)
943{
944 char msg[DBG_DATA_MSG];
945
946 if (req != NULL) {
947 scnprintf(msg, sizeof(msg),
948 "%02X %02X %04X %04X %d", req->bRequestType,
949 req->bRequest, le16_to_cpu(req->wValue),
950 le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
951 dbg_print(addr, "SETUP", 0, msg);
952 }
953}
954
955/**
956 * show_events: displays the event buffer
957 *
958 * Check "device.h" for details
959 */
960static ssize_t show_events(struct device *dev, struct device_attribute *attr,
961 char *buf)
962{
963 unsigned long flags;
964 unsigned i, j, n = 0;
965
966 dbg_trace("[%s] %p\n", __func__, buf);
967 if (attr == NULL || buf == NULL) {
968 dev_err(dev, "[%s] EINVAL\n", __func__);
969 return 0;
970 }
971
972 read_lock_irqsave(&dbg_data.lck, flags);
973
974 i = dbg_data.idx;
975 for (dbg_dec(&i); i != dbg_data.idx; dbg_dec(&i)) {
976 n += strlen(dbg_data.buf[i]);
977 if (n >= PAGE_SIZE) {
978 n -= strlen(dbg_data.buf[i]);
979 break;
980 }
981 }
982 for (j = 0, dbg_inc(&i); j < n; dbg_inc(&i))
983 j += scnprintf(buf + j, PAGE_SIZE - j,
984 "%s", dbg_data.buf[i]);
985
986 read_unlock_irqrestore(&dbg_data.lck, flags);
987
988 return n;
989}
990
991/**
992 * store_events: configure if events are going to be also printed to console
993 *
994 * Check "device.h" for details
995 */
996static ssize_t store_events(struct device *dev, struct device_attribute *attr,
997 const char *buf, size_t count)
998{
999 unsigned tty;
1000
1001 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1002 if (attr == NULL || buf == NULL) {
1003 dev_err(dev, "[%s] EINVAL\n", __func__);
1004 goto done;
1005 }
1006
1007 if (sscanf(buf, "%u", &tty) != 1 || tty > 1) {
1008 dev_err(dev, "<1|0>: enable|disable console log\n");
1009 goto done;
1010 }
1011
1012 dbg_data.tty = tty;
1013 dev_info(dev, "tty = %u", dbg_data.tty);
1014
1015 done:
1016 return count;
1017}
1018static DEVICE_ATTR(events, S_IRUSR | S_IWUSR, show_events, store_events);
1019
1020/**
1021 * show_inters: interrupt status, enable status and historic
1022 *
1023 * Check "device.h" for details
1024 */
1025static ssize_t show_inters(struct device *dev, struct device_attribute *attr,
1026 char *buf)
1027{
1028 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1029 unsigned long flags;
1030 u32 intr;
1031 unsigned i, j, n = 0;
1032
1033 dbg_trace("[%s] %p\n", __func__, buf);
1034 if (attr == NULL || buf == NULL) {
1035 dev_err(dev, "[%s] EINVAL\n", __func__);
1036 return 0;
1037 }
1038
1039 spin_lock_irqsave(udc->lock, flags);
1040
1041 n += scnprintf(buf + n, PAGE_SIZE - n,
1042 "status = %08x\n", hw_read_intr_status());
1043 n += scnprintf(buf + n, PAGE_SIZE - n,
1044 "enable = %08x\n", hw_read_intr_enable());
1045
1046 n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n",
1047 isr_statistics.test);
1048 n += scnprintf(buf + n, PAGE_SIZE - n, "» ui = %d\n",
1049 isr_statistics.ui);
1050 n += scnprintf(buf + n, PAGE_SIZE - n, "» uei = %d\n",
1051 isr_statistics.uei);
1052 n += scnprintf(buf + n, PAGE_SIZE - n, "» pci = %d\n",
1053 isr_statistics.pci);
1054 n += scnprintf(buf + n, PAGE_SIZE - n, "» uri = %d\n",
1055 isr_statistics.uri);
1056 n += scnprintf(buf + n, PAGE_SIZE - n, "» sli = %d\n",
1057 isr_statistics.sli);
1058 n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n",
1059 isr_statistics.none);
1060 n += scnprintf(buf + n, PAGE_SIZE - n, "*hndl = %d\n",
1061 isr_statistics.hndl.cnt);
1062
1063 for (i = isr_statistics.hndl.idx, j = 0; j <= ISR_MASK; j++, i++) {
1064 i &= ISR_MASK;
1065 intr = isr_statistics.hndl.buf[i];
1066
1067 if (USBi_UI & intr)
1068 n += scnprintf(buf + n, PAGE_SIZE - n, "ui ");
1069 intr &= ~USBi_UI;
1070 if (USBi_UEI & intr)
1071 n += scnprintf(buf + n, PAGE_SIZE - n, "uei ");
1072 intr &= ~USBi_UEI;
1073 if (USBi_PCI & intr)
1074 n += scnprintf(buf + n, PAGE_SIZE - n, "pci ");
1075 intr &= ~USBi_PCI;
1076 if (USBi_URI & intr)
1077 n += scnprintf(buf + n, PAGE_SIZE - n, "uri ");
1078 intr &= ~USBi_URI;
1079 if (USBi_SLI & intr)
1080 n += scnprintf(buf + n, PAGE_SIZE - n, "sli ");
1081 intr &= ~USBi_SLI;
1082 if (intr)
1083 n += scnprintf(buf + n, PAGE_SIZE - n, "??? ");
1084 if (isr_statistics.hndl.buf[i])
1085 n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
1086 }
1087
1088 spin_unlock_irqrestore(udc->lock, flags);
1089
1090 return n;
1091}
1092
1093/**
1094 * store_inters: enable & force or disable an individual interrutps
1095 * (to be used for test purposes only)
1096 *
1097 * Check "device.h" for details
1098 */
1099static ssize_t store_inters(struct device *dev, struct device_attribute *attr,
1100 const char *buf, size_t count)
1101{
1102 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1103 unsigned long flags;
1104 unsigned en, bit;
1105
1106 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1107 if (attr == NULL || buf == NULL) {
1108 dev_err(dev, "[%s] EINVAL\n", __func__);
1109 goto done;
1110 }
1111
1112 if (sscanf(buf, "%u %u", &en, &bit) != 2 || en > 1) {
1113 dev_err(dev, "<1|0> <bit>: enable|disable interrupt");
1114 goto done;
1115 }
1116
1117 spin_lock_irqsave(udc->lock, flags);
1118 if (en) {
1119 if (hw_intr_force(bit))
1120 dev_err(dev, "invalid bit number\n");
1121 else
1122 isr_statistics.test++;
1123 } else {
1124 if (hw_intr_clear(bit))
1125 dev_err(dev, "invalid bit number\n");
1126 }
1127 spin_unlock_irqrestore(udc->lock, flags);
1128
1129 done:
1130 return count;
1131}
1132static DEVICE_ATTR(inters, S_IRUSR | S_IWUSR, show_inters, store_inters);
1133
1134/**
1135 * show_port_test: reads port test mode
1136 *
1137 * Check "device.h" for details
1138 */
1139static ssize_t show_port_test(struct device *dev,
1140 struct device_attribute *attr, char *buf)
1141{
1142 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1143 unsigned long flags;
1144 unsigned mode;
1145
1146 dbg_trace("[%s] %p\n", __func__, buf);
1147 if (attr == NULL || buf == NULL) {
1148 dev_err(dev, "[%s] EINVAL\n", __func__);
1149 return 0;
1150 }
1151
1152 spin_lock_irqsave(udc->lock, flags);
1153 mode = hw_port_test_get();
1154 spin_unlock_irqrestore(udc->lock, flags);
1155
1156 return scnprintf(buf, PAGE_SIZE, "mode = %u\n", mode);
1157}
1158
1159/**
1160 * store_port_test: writes port test mode
1161 *
1162 * Check "device.h" for details
1163 */
1164static ssize_t store_port_test(struct device *dev,
1165 struct device_attribute *attr,
1166 const char *buf, size_t count)
1167{
1168 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1169 unsigned long flags;
1170 unsigned mode;
1171
1172 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1173 if (attr == NULL || buf == NULL) {
1174 dev_err(dev, "[%s] EINVAL\n", __func__);
1175 goto done;
1176 }
1177
1178 if (sscanf(buf, "%u", &mode) != 1) {
1179 dev_err(dev, "<mode>: set port test mode");
1180 goto done;
1181 }
1182
1183 spin_lock_irqsave(udc->lock, flags);
1184 if (hw_port_test_set(mode))
1185 dev_err(dev, "invalid mode\n");
1186 spin_unlock_irqrestore(udc->lock, flags);
1187
1188 done:
1189 return count;
1190}
1191static DEVICE_ATTR(port_test, S_IRUSR | S_IWUSR,
1192 show_port_test, store_port_test);
1193
1194/**
1195 * show_qheads: DMA contents of all queue heads
1196 *
1197 * Check "device.h" for details
1198 */
1199static ssize_t show_qheads(struct device *dev, struct device_attribute *attr,
1200 char *buf)
1201{
1202 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1203 unsigned long flags;
1204 unsigned i, j, n = 0;
1205
1206 dbg_trace("[%s] %p\n", __func__, buf);
1207 if (attr == NULL || buf == NULL) {
1208 dev_err(dev, "[%s] EINVAL\n", __func__);
1209 return 0;
1210 }
1211
1212 spin_lock_irqsave(udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301213 for (i = 0; i < hw_ep_max/2; i++) {
1214 struct ci13xxx_ep *mEpRx = &udc->ci13xxx_ep[i];
1215 struct ci13xxx_ep *mEpTx = &udc->ci13xxx_ep[i + hw_ep_max/2];
David Lopoaa69a802008-11-17 14:14:51 -08001216 n += scnprintf(buf + n, PAGE_SIZE - n,
1217 "EP=%02i: RX=%08X TX=%08X\n",
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301218 i, (u32)mEpRx->qh.dma, (u32)mEpTx->qh.dma);
David Lopoaa69a802008-11-17 14:14:51 -08001219 for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) {
1220 n += scnprintf(buf + n, PAGE_SIZE - n,
1221 " %04X: %08X %08X\n", j,
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301222 *((u32 *)mEpRx->qh.ptr + j),
1223 *((u32 *)mEpTx->qh.ptr + j));
David Lopoaa69a802008-11-17 14:14:51 -08001224 }
1225 }
1226 spin_unlock_irqrestore(udc->lock, flags);
1227
1228 return n;
1229}
1230static DEVICE_ATTR(qheads, S_IRUSR, show_qheads, NULL);
1231
1232/**
1233 * show_registers: dumps all registers
1234 *
1235 * Check "device.h" for details
1236 */
1237static ssize_t show_registers(struct device *dev,
1238 struct device_attribute *attr, char *buf)
1239{
1240 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1241 unsigned long flags;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001242 u32 *dump;
David Lopoaa69a802008-11-17 14:14:51 -08001243 unsigned i, k, n = 0;
1244
1245 dbg_trace("[%s] %p\n", __func__, buf);
1246 if (attr == NULL || buf == NULL) {
1247 dev_err(dev, "[%s] EINVAL\n", __func__);
1248 return 0;
1249 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001250 dump = kmalloc(2048, GFP_KERNEL);
1251 if (dump == NULL)
1252 return -ENOMEM;
David Lopoaa69a802008-11-17 14:14:51 -08001253
1254 spin_lock_irqsave(udc->lock, flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001255 k = hw_register_read(dump, 512);
David Lopoaa69a802008-11-17 14:14:51 -08001256 spin_unlock_irqrestore(udc->lock, flags);
1257
1258 for (i = 0; i < k; i++) {
1259 n += scnprintf(buf + n, PAGE_SIZE - n,
1260 "reg[0x%04X] = 0x%08X\n",
1261 i * (unsigned)sizeof(u32), dump[i]);
1262 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001263 kfree(dump);
David Lopoaa69a802008-11-17 14:14:51 -08001264 return n;
1265}
1266
1267/**
1268 * store_registers: writes value to register address
1269 *
1270 * Check "device.h" for details
1271 */
1272static ssize_t store_registers(struct device *dev,
1273 struct device_attribute *attr,
1274 const char *buf, size_t count)
1275{
1276 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1277 unsigned long addr, data, flags;
1278
1279 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1280 if (attr == NULL || buf == NULL) {
1281 dev_err(dev, "[%s] EINVAL\n", __func__);
1282 goto done;
1283 }
1284
1285 if (sscanf(buf, "%li %li", &addr, &data) != 2) {
1286 dev_err(dev, "<addr> <data>: write data to register address");
1287 goto done;
1288 }
1289
1290 spin_lock_irqsave(udc->lock, flags);
1291 if (hw_register_write(addr, data))
1292 dev_err(dev, "invalid address range\n");
1293 spin_unlock_irqrestore(udc->lock, flags);
1294
1295 done:
1296 return count;
1297}
1298static DEVICE_ATTR(registers, S_IRUSR | S_IWUSR,
1299 show_registers, store_registers);
1300
1301/**
1302 * show_requests: DMA contents of all requests currently queued (all endpts)
1303 *
1304 * Check "device.h" for details
1305 */
1306static ssize_t show_requests(struct device *dev, struct device_attribute *attr,
1307 char *buf)
1308{
1309 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1310 unsigned long flags;
1311 struct list_head *ptr = NULL;
1312 struct ci13xxx_req *req = NULL;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301313 unsigned i, j, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32);
David Lopoaa69a802008-11-17 14:14:51 -08001314
1315 dbg_trace("[%s] %p\n", __func__, buf);
1316 if (attr == NULL || buf == NULL) {
1317 dev_err(dev, "[%s] EINVAL\n", __func__);
1318 return 0;
1319 }
1320
1321 spin_lock_irqsave(udc->lock, flags);
1322 for (i = 0; i < hw_ep_max; i++)
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301323 list_for_each(ptr, &udc->ci13xxx_ep[i].qh.queue)
1324 {
1325 req = list_entry(ptr, struct ci13xxx_req, queue);
David Lopoaa69a802008-11-17 14:14:51 -08001326
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301327 n += scnprintf(buf + n, PAGE_SIZE - n,
1328 "EP=%02i: TD=%08X %s\n",
1329 i % hw_ep_max/2, (u32)req->dma,
1330 ((i < hw_ep_max/2) ? "RX" : "TX"));
1331
1332 for (j = 0; j < qSize; j++)
David Lopoaa69a802008-11-17 14:14:51 -08001333 n += scnprintf(buf + n, PAGE_SIZE - n,
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301334 " %04X: %08X\n", j,
1335 *((u32 *)req->ptr + j));
1336 }
David Lopoaa69a802008-11-17 14:14:51 -08001337 spin_unlock_irqrestore(udc->lock, flags);
1338
1339 return n;
1340}
1341static DEVICE_ATTR(requests, S_IRUSR, show_requests, NULL);
1342
Vamsi Krishna603d1cb2011-07-24 17:17:04 -07001343/* EP# and Direction */
1344static ssize_t prime_ept(struct device *dev,
1345 struct device_attribute *attr,
1346 const char *buf, size_t count)
1347{
1348 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1349 struct ci13xxx_ep *mEp;
1350 unsigned int ep_num, dir;
1351 int n;
1352 struct ci13xxx_req *mReq = NULL;
1353
1354 if (sscanf(buf, "%u %u", &ep_num, &dir) != 2) {
1355 dev_err(dev, "<ep_num> <dir>: prime the ep");
1356 goto done;
1357 }
1358
1359 if (dir)
1360 mEp = &udc->ci13xxx_ep[ep_num + hw_ep_max/2];
1361 else
1362 mEp = &udc->ci13xxx_ep[ep_num];
1363
1364 n = hw_ep_bit(mEp->num, mEp->dir);
1365 mReq = list_entry(mEp->qh.queue.next, struct ci13xxx_req, queue);
1366 mEp->qh.ptr->td.next = mReq->dma;
1367 mEp->qh.ptr->td.token &= ~TD_STATUS;
1368
1369 wmb();
1370
1371 hw_cwrite(CAP_ENDPTPRIME, BIT(n), BIT(n));
1372 while (hw_cread(CAP_ENDPTPRIME, BIT(n)))
1373 cpu_relax();
1374
1375 pr_info("%s: prime:%08x stat:%08x ep#%d dir:%s\n", __func__,
1376 hw_cread(CAP_ENDPTPRIME, ~0),
1377 hw_cread(CAP_ENDPTSTAT, ~0),
1378 mEp->num, mEp->dir ? "IN" : "OUT");
1379done:
1380 return count;
1381
1382}
1383static DEVICE_ATTR(prime, S_IWUSR, NULL, prime_ept);
1384
1385/* EP# and Direction */
1386static ssize_t print_dtds(struct device *dev,
1387 struct device_attribute *attr,
1388 const char *buf, size_t count)
1389{
1390 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1391 struct ci13xxx_ep *mEp;
1392 unsigned int ep_num, dir;
1393 int n;
1394 struct list_head *ptr = NULL;
1395 struct ci13xxx_req *req = NULL;
1396
1397 if (sscanf(buf, "%u %u", &ep_num, &dir) != 2) {
1398 dev_err(dev, "<ep_num> <dir>: to print dtds");
1399 goto done;
1400 }
1401
1402 if (dir)
1403 mEp = &udc->ci13xxx_ep[ep_num + hw_ep_max/2];
1404 else
1405 mEp = &udc->ci13xxx_ep[ep_num];
1406
1407 n = hw_ep_bit(mEp->num, mEp->dir);
1408
1409 pr_info("ep#%d dir:%s\n", mEp->num, mEp->dir ? "IN" : "OUT");
1410 pr_info("QH: cap:%08x cur:%08x next:%08x token:%08x\n",
1411 mEp->qh.ptr->cap, mEp->qh.ptr->curr,
1412 mEp->qh.ptr->td.next, mEp->qh.ptr->td.token);
1413
1414 list_for_each(ptr, &mEp->qh.queue) {
1415 req = list_entry(ptr, struct ci13xxx_req, queue);
1416
1417 pr_info("\treq:%08x next:%08x token:%08x page0:%08x status:%d\n",
1418 req->dma, req->ptr->next, req->ptr->token,
1419 req->ptr->page[0], req->req.status);
1420 }
1421done:
1422 return count;
1423
1424}
1425static DEVICE_ATTR(dtds, S_IWUSR, NULL, print_dtds);
1426
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001427static int ci13xxx_wakeup(struct usb_gadget *_gadget)
1428{
1429 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
1430 unsigned long flags;
1431 int ret = 0;
1432
1433 trace();
1434
1435 spin_lock_irqsave(udc->lock, flags);
1436 if (!udc->remote_wakeup) {
1437 ret = -EOPNOTSUPP;
1438 dbg_trace("remote wakeup feature is not enabled\n");
1439 goto out;
1440 }
1441 if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) {
1442 ret = -EINVAL;
1443 dbg_trace("port is not suspended\n");
1444 goto out;
1445 }
1446 hw_cwrite(CAP_PORTSC, PORTSC_FPR, PORTSC_FPR);
1447out:
1448 spin_unlock_irqrestore(udc->lock, flags);
1449 return ret;
1450}
1451
1452static ssize_t usb_remote_wakeup(struct device *dev,
1453 struct device_attribute *attr, const char *buf, size_t count)
1454{
1455 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1456
1457 ci13xxx_wakeup(&udc->gadget);
1458
1459 return count;
1460}
1461static DEVICE_ATTR(wakeup, S_IWUSR, 0, usb_remote_wakeup);
1462
David Lopoaa69a802008-11-17 14:14:51 -08001463/**
1464 * dbg_create_files: initializes the attribute interface
1465 * @dev: device
1466 *
1467 * This function returns an error code
1468 */
1469__maybe_unused static int dbg_create_files(struct device *dev)
1470{
1471 int retval = 0;
1472
1473 if (dev == NULL)
1474 return -EINVAL;
1475 retval = device_create_file(dev, &dev_attr_device);
1476 if (retval)
1477 goto done;
1478 retval = device_create_file(dev, &dev_attr_driver);
1479 if (retval)
1480 goto rm_device;
1481 retval = device_create_file(dev, &dev_attr_events);
1482 if (retval)
1483 goto rm_driver;
1484 retval = device_create_file(dev, &dev_attr_inters);
1485 if (retval)
1486 goto rm_events;
1487 retval = device_create_file(dev, &dev_attr_port_test);
1488 if (retval)
1489 goto rm_inters;
1490 retval = device_create_file(dev, &dev_attr_qheads);
1491 if (retval)
1492 goto rm_port_test;
1493 retval = device_create_file(dev, &dev_attr_registers);
1494 if (retval)
1495 goto rm_qheads;
1496 retval = device_create_file(dev, &dev_attr_requests);
1497 if (retval)
1498 goto rm_registers;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001499 retval = device_create_file(dev, &dev_attr_wakeup);
1500 if (retval)
1501 goto rm_remote_wakeup;
Vamsi Krishna603d1cb2011-07-24 17:17:04 -07001502 retval = device_create_file(dev, &dev_attr_prime);
1503 if (retval)
1504 goto rm_prime;
1505 retval = device_create_file(dev, &dev_attr_dtds);
1506 if (retval)
1507 goto rm_dtds;
1508
David Lopoaa69a802008-11-17 14:14:51 -08001509 return 0;
1510
Vamsi Krishna603d1cb2011-07-24 17:17:04 -07001511rm_dtds:
1512 device_remove_file(dev, &dev_attr_dtds);
1513rm_prime:
1514 device_remove_file(dev, &dev_attr_prime);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001515rm_remote_wakeup:
1516 device_remove_file(dev, &dev_attr_wakeup);
David Lopoaa69a802008-11-17 14:14:51 -08001517 rm_registers:
1518 device_remove_file(dev, &dev_attr_registers);
1519 rm_qheads:
1520 device_remove_file(dev, &dev_attr_qheads);
1521 rm_port_test:
1522 device_remove_file(dev, &dev_attr_port_test);
1523 rm_inters:
1524 device_remove_file(dev, &dev_attr_inters);
1525 rm_events:
1526 device_remove_file(dev, &dev_attr_events);
1527 rm_driver:
1528 device_remove_file(dev, &dev_attr_driver);
1529 rm_device:
1530 device_remove_file(dev, &dev_attr_device);
1531 done:
1532 return retval;
1533}
1534
1535/**
1536 * dbg_remove_files: destroys the attribute interface
1537 * @dev: device
1538 *
1539 * This function returns an error code
1540 */
1541__maybe_unused static int dbg_remove_files(struct device *dev)
1542{
1543 if (dev == NULL)
1544 return -EINVAL;
1545 device_remove_file(dev, &dev_attr_requests);
1546 device_remove_file(dev, &dev_attr_registers);
1547 device_remove_file(dev, &dev_attr_qheads);
1548 device_remove_file(dev, &dev_attr_port_test);
1549 device_remove_file(dev, &dev_attr_inters);
1550 device_remove_file(dev, &dev_attr_events);
1551 device_remove_file(dev, &dev_attr_driver);
1552 device_remove_file(dev, &dev_attr_device);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001553 device_remove_file(dev, &dev_attr_wakeup);
David Lopoaa69a802008-11-17 14:14:51 -08001554 return 0;
1555}
1556
1557/******************************************************************************
1558 * UTIL block
1559 *****************************************************************************/
1560/**
1561 * _usb_addr: calculates endpoint address from direction & number
1562 * @ep: endpoint
1563 */
1564static inline u8 _usb_addr(struct ci13xxx_ep *ep)
1565{
1566 return ((ep->dir == TX) ? USB_ENDPOINT_DIR_MASK : 0) | ep->num;
1567}
1568
1569/**
1570 * _hardware_queue: configures a request at hardware level
1571 * @gadget: gadget
1572 * @mEp: endpoint
1573 *
1574 * This function returns an error code
1575 */
1576static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
1577{
1578 unsigned i;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301579 int ret = 0;
1580 unsigned length = mReq->req.length;
David Lopoaa69a802008-11-17 14:14:51 -08001581
1582 trace("%p, %p", mEp, mReq);
1583
1584 /* don't queue twice */
1585 if (mReq->req.status == -EALREADY)
1586 return -EALREADY;
1587
David Lopoaa69a802008-11-17 14:14:51 -08001588 mReq->req.status = -EALREADY;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301589 if (length && !mReq->req.dma) {
David Lopoaa69a802008-11-17 14:14:51 -08001590 mReq->req.dma = \
1591 dma_map_single(mEp->device, mReq->req.buf,
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301592 length, mEp->dir ? DMA_TO_DEVICE :
1593 DMA_FROM_DEVICE);
David Lopoaa69a802008-11-17 14:14:51 -08001594 if (mReq->req.dma == 0)
1595 return -ENOMEM;
1596
1597 mReq->map = 1;
1598 }
1599
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301600 if (mReq->req.zero && length && (length % mEp->ep.maxpacket == 0)) {
1601 mReq->zptr = dma_pool_alloc(mEp->td_pool, GFP_ATOMIC,
1602 &mReq->zdma);
1603 if (mReq->zptr == NULL) {
1604 if (mReq->map) {
1605 dma_unmap_single(mEp->device, mReq->req.dma,
1606 length, mEp->dir ? DMA_TO_DEVICE :
1607 DMA_FROM_DEVICE);
1608 mReq->req.dma = 0;
1609 mReq->map = 0;
1610 }
1611 return -ENOMEM;
1612 }
1613 memset(mReq->zptr, 0, sizeof(*mReq->zptr));
1614 mReq->zptr->next = TD_TERMINATE;
1615 mReq->zptr->token = TD_STATUS_ACTIVE;
1616 if (!mReq->req.no_interrupt)
1617 mReq->zptr->token |= TD_IOC;
1618 }
David Lopoaa69a802008-11-17 14:14:51 -08001619 /*
1620 * TD configuration
1621 * TODO - handle requests which spawns into several TDs
1622 */
1623 memset(mReq->ptr, 0, sizeof(*mReq->ptr));
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301624 mReq->ptr->token = length << ffs_nr(TD_TOTAL_BYTES);
David Lopoaa69a802008-11-17 14:14:51 -08001625 mReq->ptr->token &= TD_TOTAL_BYTES;
David Lopoaa69a802008-11-17 14:14:51 -08001626 mReq->ptr->token |= TD_STATUS_ACTIVE;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301627 if (mReq->zptr) {
1628 mReq->ptr->next = mReq->zdma;
1629 } else {
1630 mReq->ptr->next = TD_TERMINATE;
1631 if (!mReq->req.no_interrupt)
1632 mReq->ptr->token |= TD_IOC;
1633 }
David Lopoaa69a802008-11-17 14:14:51 -08001634 mReq->ptr->page[0] = mReq->req.dma;
1635 for (i = 1; i < 5; i++)
1636 mReq->ptr->page[i] =
Artem Leonenko0a313c42010-12-14 23:47:06 -08001637 (mReq->req.dma + i * CI13XXX_PAGE_SIZE) & ~TD_RESERVED_MASK;
David Lopoaa69a802008-11-17 14:14:51 -08001638
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301639 if (!list_empty(&mEp->qh.queue)) {
1640 struct ci13xxx_req *mReqPrev;
1641 int n = hw_ep_bit(mEp->num, mEp->dir);
1642 int tmp_stat;
1643
1644 mReqPrev = list_entry(mEp->qh.queue.prev,
1645 struct ci13xxx_req, queue);
1646 if (mReqPrev->zptr)
1647 mReqPrev->zptr->next = mReq->dma & TD_ADDR_MASK;
1648 else
1649 mReqPrev->ptr->next = mReq->dma & TD_ADDR_MASK;
1650 wmb();
1651 if (hw_cread(CAP_ENDPTPRIME, BIT(n)))
1652 goto done;
1653 do {
1654 hw_cwrite(CAP_USBCMD, USBCMD_ATDTW, USBCMD_ATDTW);
1655 tmp_stat = hw_cread(CAP_ENDPTSTAT, BIT(n));
1656 } while (!hw_cread(CAP_USBCMD, USBCMD_ATDTW));
1657 hw_cwrite(CAP_USBCMD, USBCMD_ATDTW, 0);
1658 if (tmp_stat)
1659 goto done;
1660 }
1661
1662 /* QH configuration */
Vamsi Krishna603d1cb2011-07-24 17:17:04 -07001663 if (!list_empty(&mEp->qh.queue)) {
1664 struct ci13xxx_req *mReq = \
1665 list_entry(mEp->qh.queue.next,
1666 struct ci13xxx_req, queue);
1667
1668 if (TD_STATUS_ACTIVE & mReq->ptr->token) {
1669 mEp->qh.ptr->td.next = mReq->dma;
1670 mEp->qh.ptr->td.token &= ~TD_STATUS;
1671 goto prime;
1672 }
1673 }
1674
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301675 mEp->qh.ptr->td.next = mReq->dma; /* TERMINATE = 0 */
1676 mEp->qh.ptr->td.token &= ~TD_STATUS; /* clear status */
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301677 mEp->qh.ptr->cap |= QH_ZLT;
David Lopoaa69a802008-11-17 14:14:51 -08001678
Vamsi Krishna603d1cb2011-07-24 17:17:04 -07001679prime:
David Lopoaa69a802008-11-17 14:14:51 -08001680 wmb(); /* synchronize before ep prime */
1681
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301682 ret = hw_ep_prime(mEp->num, mEp->dir,
David Lopoaa69a802008-11-17 14:14:51 -08001683 mEp->type == USB_ENDPOINT_XFER_CONTROL);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301684done:
1685 return ret;
David Lopoaa69a802008-11-17 14:14:51 -08001686}
1687
1688/**
1689 * _hardware_dequeue: handles a request at hardware level
1690 * @gadget: gadget
1691 * @mEp: endpoint
1692 *
1693 * This function returns an error code
1694 */
1695static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
1696{
1697 trace("%p, %p", mEp, mReq);
1698
1699 if (mReq->req.status != -EALREADY)
1700 return -EINVAL;
1701
Vijayavardhan Vennapusa590b8ce2011-10-20 02:38:14 +05301702 /* clean speculative fetches on req->ptr->token */
1703 mb();
1704
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301705 if ((TD_STATUS_ACTIVE & mReq->ptr->token) != 0)
1706 return -EBUSY;
1707
1708 if (mReq->zptr) {
1709 if ((TD_STATUS_ACTIVE & mReq->zptr->token) != 0)
1710 return -EBUSY;
1711 dma_pool_free(mEp->td_pool, mReq->zptr, mReq->zdma);
1712 mReq->zptr = NULL;
1713 }
David Lopoaa69a802008-11-17 14:14:51 -08001714
1715 mReq->req.status = 0;
1716
1717 if (mReq->map) {
1718 dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
1719 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
1720 mReq->req.dma = 0;
1721 mReq->map = 0;
1722 }
1723
1724 mReq->req.status = mReq->ptr->token & TD_STATUS;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301725 if ((TD_STATUS_HALTED & mReq->req.status) != 0)
David Lopoaa69a802008-11-17 14:14:51 -08001726 mReq->req.status = -1;
1727 else if ((TD_STATUS_DT_ERR & mReq->req.status) != 0)
1728 mReq->req.status = -1;
1729 else if ((TD_STATUS_TR_ERR & mReq->req.status) != 0)
1730 mReq->req.status = -1;
1731
1732 mReq->req.actual = mReq->ptr->token & TD_TOTAL_BYTES;
1733 mReq->req.actual >>= ffs_nr(TD_TOTAL_BYTES);
1734 mReq->req.actual = mReq->req.length - mReq->req.actual;
1735 mReq->req.actual = mReq->req.status ? 0 : mReq->req.actual;
1736
1737 return mReq->req.actual;
1738}
1739
1740/**
1741 * _ep_nuke: dequeues all endpoint requests
1742 * @mEp: endpoint
1743 *
1744 * This function returns an error code
1745 * Caller must hold lock
1746 */
1747static int _ep_nuke(struct ci13xxx_ep *mEp)
1748__releases(mEp->lock)
1749__acquires(mEp->lock)
1750{
Pavankumar Kondeti05cdbdb2011-09-12 09:13:12 +05301751 struct ci13xxx_ep *mEpTemp = mEp;
1752
David Lopoaa69a802008-11-17 14:14:51 -08001753 trace("%p", mEp);
1754
1755 if (mEp == NULL)
1756 return -EINVAL;
1757
1758 hw_ep_flush(mEp->num, mEp->dir);
1759
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301760 while (!list_empty(&mEp->qh.queue)) {
David Lopoaa69a802008-11-17 14:14:51 -08001761
1762 /* pop oldest request */
1763 struct ci13xxx_req *mReq = \
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301764 list_entry(mEp->qh.queue.next,
David Lopoaa69a802008-11-17 14:14:51 -08001765 struct ci13xxx_req, queue);
1766 list_del_init(&mReq->queue);
1767 mReq->req.status = -ESHUTDOWN;
1768
Artem Leonenko7c25a822010-12-14 23:46:55 -08001769 if (mReq->req.complete != NULL) {
David Lopoaa69a802008-11-17 14:14:51 -08001770 spin_unlock(mEp->lock);
Pavankumar Kondeti05cdbdb2011-09-12 09:13:12 +05301771 if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
1772 mReq->req.length)
1773 mEpTemp = &_udc->ep0in;
1774 mReq->req.complete(&mEpTemp->ep, &mReq->req);
David Lopoaa69a802008-11-17 14:14:51 -08001775 spin_lock(mEp->lock);
1776 }
1777 }
1778 return 0;
1779}
1780
1781/**
1782 * _gadget_stop_activity: stops all USB activity, flushes & disables all endpts
1783 * @gadget: gadget
1784 *
1785 * This function returns an error code
1786 * Caller must hold lock
1787 */
1788static int _gadget_stop_activity(struct usb_gadget *gadget)
David Lopoaa69a802008-11-17 14:14:51 -08001789{
1790 struct usb_ep *ep;
1791 struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301792 unsigned long flags;
David Lopoaa69a802008-11-17 14:14:51 -08001793
1794 trace("%p", gadget);
1795
1796 if (gadget == NULL)
1797 return -EINVAL;
1798
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301799 spin_lock_irqsave(udc->lock, flags);
1800 udc->gadget.speed = USB_SPEED_UNKNOWN;
1801 udc->remote_wakeup = 0;
1802 udc->suspended = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001803 udc->configured = 0;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301804 spin_unlock_irqrestore(udc->lock, flags);
1805
David Lopoaa69a802008-11-17 14:14:51 -08001806 /* flush all endpoints */
1807 gadget_for_each_ep(ep, gadget) {
1808 usb_ep_fifo_flush(ep);
1809 }
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301810 usb_ep_fifo_flush(&udc->ep0out.ep);
1811 usb_ep_fifo_flush(&udc->ep0in.ep);
David Lopoaa69a802008-11-17 14:14:51 -08001812
1813 udc->driver->disconnect(gadget);
1814
1815 /* make sure to disable all endpoints */
1816 gadget_for_each_ep(ep, gadget) {
1817 usb_ep_disable(ep);
1818 }
David Lopoaa69a802008-11-17 14:14:51 -08001819
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301820 if (udc->status != NULL) {
1821 usb_ep_free_request(&udc->ep0in.ep, udc->status);
1822 udc->status = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08001823 }
1824
David Lopoaa69a802008-11-17 14:14:51 -08001825 return 0;
1826}
1827
1828/******************************************************************************
1829 * ISR block
1830 *****************************************************************************/
1831/**
1832 * isr_reset_handler: USB reset interrupt handler
1833 * @udc: UDC device
1834 *
1835 * This function resets USB engine after a bus reset occurred
1836 */
1837static void isr_reset_handler(struct ci13xxx *udc)
1838__releases(udc->lock)
1839__acquires(udc->lock)
1840{
David Lopoaa69a802008-11-17 14:14:51 -08001841 int retval;
1842
1843 trace("%p", udc);
1844
1845 if (udc == NULL) {
1846 err("EINVAL");
1847 return;
1848 }
1849
1850 dbg_event(0xFF, "BUS RST", 0);
1851
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05301852 spin_unlock(udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08001853 retval = _gadget_stop_activity(&udc->gadget);
1854 if (retval)
1855 goto done;
1856
1857 retval = hw_usb_reset();
1858 if (retval)
1859 goto done;
1860
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05301861 udc->status = usb_ep_alloc_request(&udc->ep0in.ep, GFP_ATOMIC);
1862 if (udc->status == NULL)
1863 retval = -ENOMEM;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301864
David Lopoaa69a802008-11-17 14:14:51 -08001865 spin_lock(udc->lock);
1866
1867 done:
1868 if (retval)
1869 err("error: %i", retval);
1870}
1871
1872/**
1873 * isr_get_status_complete: get_status request complete function
1874 * @ep: endpoint
1875 * @req: request handled
1876 *
1877 * Caller must release lock
1878 */
1879static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req)
1880{
1881 trace("%p, %p", ep, req);
1882
1883 if (ep == NULL || req == NULL) {
1884 err("EINVAL");
1885 return;
1886 }
1887
1888 kfree(req->buf);
1889 usb_ep_free_request(ep, req);
1890}
1891
1892/**
1893 * isr_get_status_response: get_status request response
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301894 * @udc: udc struct
David Lopoaa69a802008-11-17 14:14:51 -08001895 * @setup: setup request packet
1896 *
1897 * This function returns an error code
1898 */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301899static int isr_get_status_response(struct ci13xxx *udc,
David Lopoaa69a802008-11-17 14:14:51 -08001900 struct usb_ctrlrequest *setup)
1901__releases(mEp->lock)
1902__acquires(mEp->lock)
1903{
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301904 struct ci13xxx_ep *mEp = &udc->ep0in;
David Lopoaa69a802008-11-17 14:14:51 -08001905 struct usb_request *req = NULL;
1906 gfp_t gfp_flags = GFP_ATOMIC;
1907 int dir, num, retval;
1908
1909 trace("%p, %p", mEp, setup);
1910
1911 if (mEp == NULL || setup == NULL)
1912 return -EINVAL;
1913
1914 spin_unlock(mEp->lock);
1915 req = usb_ep_alloc_request(&mEp->ep, gfp_flags);
1916 spin_lock(mEp->lock);
1917 if (req == NULL)
1918 return -ENOMEM;
1919
1920 req->complete = isr_get_status_complete;
1921 req->length = 2;
1922 req->buf = kzalloc(req->length, gfp_flags);
1923 if (req->buf == NULL) {
1924 retval = -ENOMEM;
1925 goto err_free_req;
1926 }
1927
1928 if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301929 /* Assume that device is bus powered for now. */
1930 *((u16 *)req->buf) = _udc->remote_wakeup << 1;
David Lopoaa69a802008-11-17 14:14:51 -08001931 retval = 0;
1932 } else if ((setup->bRequestType & USB_RECIP_MASK) \
1933 == USB_RECIP_ENDPOINT) {
1934 dir = (le16_to_cpu(setup->wIndex) & USB_ENDPOINT_DIR_MASK) ?
1935 TX : RX;
1936 num = le16_to_cpu(setup->wIndex) & USB_ENDPOINT_NUMBER_MASK;
1937 *((u16 *)req->buf) = hw_ep_get_halt(num, dir);
1938 }
1939 /* else do nothing; reserved for future use */
1940
1941 spin_unlock(mEp->lock);
1942 retval = usb_ep_queue(&mEp->ep, req, gfp_flags);
1943 spin_lock(mEp->lock);
1944 if (retval)
1945 goto err_free_buf;
1946
1947 return 0;
1948
1949 err_free_buf:
1950 kfree(req->buf);
1951 err_free_req:
1952 spin_unlock(mEp->lock);
1953 usb_ep_free_request(&mEp->ep, req);
1954 spin_lock(mEp->lock);
1955 return retval;
1956}
1957
1958/**
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301959 * isr_setup_status_complete: setup_status request complete function
1960 * @ep: endpoint
1961 * @req: request handled
1962 *
1963 * Caller must release lock. Put the port in test mode if test mode
1964 * feature is selected.
1965 */
1966static void
1967isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req)
1968{
1969 struct ci13xxx *udc = req->context;
1970 unsigned long flags;
1971
1972 trace("%p, %p", ep, req);
1973
1974 spin_lock_irqsave(udc->lock, flags);
1975 if (udc->test_mode)
1976 hw_port_test_set(udc->test_mode);
1977 spin_unlock_irqrestore(udc->lock, flags);
1978}
1979
1980/**
David Lopoaa69a802008-11-17 14:14:51 -08001981 * isr_setup_status_phase: queues the status phase of a setup transation
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301982 * @udc: udc struct
David Lopoaa69a802008-11-17 14:14:51 -08001983 *
1984 * This function returns an error code
1985 */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301986static int isr_setup_status_phase(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -08001987__releases(mEp->lock)
1988__acquires(mEp->lock)
1989{
1990 int retval;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301991 struct ci13xxx_ep *mEp;
David Lopoaa69a802008-11-17 14:14:51 -08001992
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301993 trace("%p", udc);
David Lopoaa69a802008-11-17 14:14:51 -08001994
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301995 mEp = (udc->ep0_dir == TX) ? &udc->ep0out : &udc->ep0in;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301996 udc->status->context = udc;
1997 udc->status->complete = isr_setup_status_complete;
David Lopoaa69a802008-11-17 14:14:51 -08001998
1999 spin_unlock(mEp->lock);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302000 retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC);
David Lopoaa69a802008-11-17 14:14:51 -08002001 spin_lock(mEp->lock);
2002
2003 return retval;
2004}
2005
2006/**
2007 * isr_tr_complete_low: transaction complete low level handler
2008 * @mEp: endpoint
2009 *
2010 * This function returns an error code
2011 * Caller must hold lock
2012 */
2013static int isr_tr_complete_low(struct ci13xxx_ep *mEp)
2014__releases(mEp->lock)
2015__acquires(mEp->lock)
2016{
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302017 struct ci13xxx_req *mReq, *mReqTemp;
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05302018 struct ci13xxx_ep *mEpTemp = mEp;
Pavankumar Kondeti986b11b2011-05-02 11:56:29 +05302019 int uninitialized_var(retval);
David Lopoaa69a802008-11-17 14:14:51 -08002020
2021 trace("%p", mEp);
2022
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302023 if (list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08002024 return -EINVAL;
2025
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302026 list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue,
2027 queue) {
2028 retval = _hardware_dequeue(mEp, mReq);
2029 if (retval < 0)
2030 break;
2031 list_del_init(&mReq->queue);
2032 dbg_done(_usb_addr(mEp), mReq->ptr->token, retval);
2033 if (mReq->req.complete != NULL) {
2034 spin_unlock(mEp->lock);
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05302035 if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
2036 mReq->req.length)
2037 mEpTemp = &_udc->ep0in;
2038 mReq->req.complete(&mEpTemp->ep, &mReq->req);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302039 spin_lock(mEp->lock);
2040 }
2041 }
David Lopoaa69a802008-11-17 14:14:51 -08002042
Pavankumar Kondetief907482011-05-02 11:56:27 +05302043 if (retval == -EBUSY)
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302044 retval = 0;
2045 if (retval < 0)
David Lopoaa69a802008-11-17 14:14:51 -08002046 dbg_event(_usb_addr(mEp), "DONE", retval);
David Lopoaa69a802008-11-17 14:14:51 -08002047
David Lopoaa69a802008-11-17 14:14:51 -08002048 return retval;
2049}
2050
2051/**
2052 * isr_tr_complete_handler: transaction complete interrupt handler
2053 * @udc: UDC descriptor
2054 *
2055 * This function handles traffic events
2056 */
2057static void isr_tr_complete_handler(struct ci13xxx *udc)
2058__releases(udc->lock)
2059__acquires(udc->lock)
2060{
2061 unsigned i;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05302062 u8 tmode = 0;
David Lopoaa69a802008-11-17 14:14:51 -08002063
2064 trace("%p", udc);
2065
2066 if (udc == NULL) {
2067 err("EINVAL");
2068 return;
2069 }
2070
2071 for (i = 0; i < hw_ep_max; i++) {
2072 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302073 int type, num, dir, err = -EINVAL;
David Lopoaa69a802008-11-17 14:14:51 -08002074 struct usb_ctrlrequest req;
2075
David Lopoaa69a802008-11-17 14:14:51 -08002076 if (mEp->desc == NULL)
2077 continue; /* not configured */
2078
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302079 if (hw_test_and_clear_complete(i)) {
David Lopoaa69a802008-11-17 14:14:51 -08002080 err = isr_tr_complete_low(mEp);
2081 if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
2082 if (err > 0) /* needs status phase */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302083 err = isr_setup_status_phase(udc);
David Lopoaa69a802008-11-17 14:14:51 -08002084 if (err < 0) {
2085 dbg_event(_usb_addr(mEp),
2086 "ERROR", err);
2087 spin_unlock(udc->lock);
2088 if (usb_ep_set_halt(&mEp->ep))
2089 err("error: ep_set_halt");
2090 spin_lock(udc->lock);
2091 }
2092 }
2093 }
2094
2095 if (mEp->type != USB_ENDPOINT_XFER_CONTROL ||
2096 !hw_test_and_clear_setup_status(i))
2097 continue;
2098
2099 if (i != 0) {
2100 warn("ctrl traffic received at endpoint");
2101 continue;
2102 }
2103
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302104 /*
2105 * Flush data and handshake transactions of previous
2106 * setup packet.
2107 */
2108 _ep_nuke(&udc->ep0out);
2109 _ep_nuke(&udc->ep0in);
2110
David Lopoaa69a802008-11-17 14:14:51 -08002111 /* read_setup_packet */
2112 do {
2113 hw_test_and_set_setup_guard();
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302114 memcpy(&req, &mEp->qh.ptr->setup, sizeof(req));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002115 /* Ensure buffer is read before acknowledging to h/w */
2116 mb();
David Lopoaa69a802008-11-17 14:14:51 -08002117 } while (!hw_test_and_clear_setup_guard());
2118
2119 type = req.bRequestType;
2120
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302121 udc->ep0_dir = (type & USB_DIR_IN) ? TX : RX;
David Lopoaa69a802008-11-17 14:14:51 -08002122
2123 dbg_setup(_usb_addr(mEp), &req);
2124
2125 switch (req.bRequest) {
2126 case USB_REQ_CLEAR_FEATURE:
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302127 if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
2128 le16_to_cpu(req.wValue) ==
2129 USB_ENDPOINT_HALT) {
2130 if (req.wLength != 0)
David Lopoaa69a802008-11-17 14:14:51 -08002131 break;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302132 num = le16_to_cpu(req.wIndex);
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302133 dir = num & USB_ENDPOINT_DIR_MASK;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302134 num &= USB_ENDPOINT_NUMBER_MASK;
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302135 if (dir) /* TX */
2136 num += hw_ep_max/2;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302137 if (!udc->ci13xxx_ep[num].wedge) {
2138 spin_unlock(udc->lock);
2139 err = usb_ep_clear_halt(
2140 &udc->ci13xxx_ep[num].ep);
2141 spin_lock(udc->lock);
2142 if (err)
2143 break;
2144 }
2145 err = isr_setup_status_phase(udc);
2146 } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) &&
2147 le16_to_cpu(req.wValue) ==
2148 USB_DEVICE_REMOTE_WAKEUP) {
2149 if (req.wLength != 0)
2150 break;
2151 udc->remote_wakeup = 0;
2152 err = isr_setup_status_phase(udc);
2153 } else {
2154 goto delegate;
David Lopoaa69a802008-11-17 14:14:51 -08002155 }
David Lopoaa69a802008-11-17 14:14:51 -08002156 break;
2157 case USB_REQ_GET_STATUS:
2158 if (type != (USB_DIR_IN|USB_RECIP_DEVICE) &&
2159 type != (USB_DIR_IN|USB_RECIP_ENDPOINT) &&
2160 type != (USB_DIR_IN|USB_RECIP_INTERFACE))
2161 goto delegate;
2162 if (le16_to_cpu(req.wLength) != 2 ||
2163 le16_to_cpu(req.wValue) != 0)
2164 break;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302165 err = isr_get_status_response(udc, &req);
David Lopoaa69a802008-11-17 14:14:51 -08002166 break;
2167 case USB_REQ_SET_ADDRESS:
2168 if (type != (USB_DIR_OUT|USB_RECIP_DEVICE))
2169 goto delegate;
2170 if (le16_to_cpu(req.wLength) != 0 ||
2171 le16_to_cpu(req.wIndex) != 0)
2172 break;
2173 err = hw_usb_set_address((u8)le16_to_cpu(req.wValue));
2174 if (err)
2175 break;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302176 err = isr_setup_status_phase(udc);
David Lopoaa69a802008-11-17 14:14:51 -08002177 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002178 case USB_REQ_SET_CONFIGURATION:
2179 if (type == (USB_DIR_OUT|USB_TYPE_STANDARD))
2180 udc->configured = !!req.wValue;
2181 goto delegate;
David Lopoaa69a802008-11-17 14:14:51 -08002182 case USB_REQ_SET_FEATURE:
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302183 if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
2184 le16_to_cpu(req.wValue) ==
2185 USB_ENDPOINT_HALT) {
2186 if (req.wLength != 0)
2187 break;
2188 num = le16_to_cpu(req.wIndex);
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302189 dir = num & USB_ENDPOINT_DIR_MASK;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302190 num &= USB_ENDPOINT_NUMBER_MASK;
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302191 if (dir) /* TX */
2192 num += hw_ep_max/2;
David Lopoaa69a802008-11-17 14:14:51 -08002193
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302194 spin_unlock(udc->lock);
2195 err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep);
2196 spin_lock(udc->lock);
2197 if (!err)
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05302198 isr_setup_status_phase(udc);
2199 } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE)) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302200 if (req.wLength != 0)
2201 break;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05302202 switch (le16_to_cpu(req.wValue)) {
2203 case USB_DEVICE_REMOTE_WAKEUP:
2204 udc->remote_wakeup = 1;
2205 err = isr_setup_status_phase(udc);
2206 break;
2207 case USB_DEVICE_TEST_MODE:
2208 tmode = le16_to_cpu(req.wIndex) >> 8;
2209 switch (tmode) {
2210 case TEST_J:
2211 case TEST_K:
2212 case TEST_SE0_NAK:
2213 case TEST_PACKET:
2214 case TEST_FORCE_EN:
2215 udc->test_mode = tmode;
2216 err = isr_setup_status_phase(
2217 udc);
2218 break;
2219 default:
2220 break;
2221 }
2222 default:
2223 goto delegate;
2224 }
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302225 } else {
2226 goto delegate;
2227 }
David Lopoaa69a802008-11-17 14:14:51 -08002228 break;
2229 default:
2230delegate:
2231 if (req.wLength == 0) /* no data phase */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302232 udc->ep0_dir = TX;
David Lopoaa69a802008-11-17 14:14:51 -08002233
2234 spin_unlock(udc->lock);
2235 err = udc->driver->setup(&udc->gadget, &req);
2236 spin_lock(udc->lock);
2237 break;
2238 }
2239
2240 if (err < 0) {
2241 dbg_event(_usb_addr(mEp), "ERROR", err);
2242
2243 spin_unlock(udc->lock);
2244 if (usb_ep_set_halt(&mEp->ep))
2245 err("error: ep_set_halt");
2246 spin_lock(udc->lock);
2247 }
2248 }
2249}
2250
2251/******************************************************************************
2252 * ENDPT block
2253 *****************************************************************************/
2254/**
2255 * ep_enable: configure endpoint, making it usable
2256 *
2257 * Check usb_ep_enable() at "usb_gadget.h" for details
2258 */
2259static int ep_enable(struct usb_ep *ep,
2260 const struct usb_endpoint_descriptor *desc)
2261{
2262 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302263 int retval = 0;
David Lopoaa69a802008-11-17 14:14:51 -08002264 unsigned long flags;
2265
2266 trace("%p, %p", ep, desc);
2267
2268 if (ep == NULL || desc == NULL)
2269 return -EINVAL;
2270
2271 spin_lock_irqsave(mEp->lock, flags);
2272
2273 /* only internal SW should enable ctrl endpts */
2274
2275 mEp->desc = desc;
2276
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302277 if (!list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08002278 warn("enabling a non-empty endpoint!");
2279
Matthias Kaehlcke15739bb2009-04-15 22:28:41 +02002280 mEp->dir = usb_endpoint_dir_in(desc) ? TX : RX;
2281 mEp->num = usb_endpoint_num(desc);
2282 mEp->type = usb_endpoint_type(desc);
David Lopoaa69a802008-11-17 14:14:51 -08002283
2284 mEp->ep.maxpacket = __constant_le16_to_cpu(desc->wMaxPacketSize);
2285
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302286 dbg_event(_usb_addr(mEp), "ENABLE", 0);
David Lopoaa69a802008-11-17 14:14:51 -08002287
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302288 mEp->qh.ptr->cap = 0;
David Lopof23e6492009-04-16 14:35:24 -07002289
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302290 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2291 mEp->qh.ptr->cap |= QH_IOS;
2292 else if (mEp->type == USB_ENDPOINT_XFER_ISOC)
2293 mEp->qh.ptr->cap &= ~QH_MULT;
2294 else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002295 mEp->qh.ptr->cap |= QH_ZLT;
David Lopoaa69a802008-11-17 14:14:51 -08002296
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302297 mEp->qh.ptr->cap |=
2298 (mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT;
2299 mEp->qh.ptr->td.next |= TD_TERMINATE; /* needed? */
David Lopoaa69a802008-11-17 14:14:51 -08002300
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002301 /* complete all the updates to ept->head before enabling endpoint*/
2302 mb();
2303
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302304 /*
2305 * Enable endpoints in the HW other than ep0 as ep0
2306 * is always enabled
2307 */
2308 if (mEp->num)
2309 retval |= hw_ep_enable(mEp->num, mEp->dir, mEp->type);
David Lopoaa69a802008-11-17 14:14:51 -08002310
2311 spin_unlock_irqrestore(mEp->lock, flags);
2312 return retval;
2313}
2314
2315/**
2316 * ep_disable: endpoint is no longer usable
2317 *
2318 * Check usb_ep_disable() at "usb_gadget.h" for details
2319 */
2320static int ep_disable(struct usb_ep *ep)
2321{
2322 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2323 int direction, retval = 0;
2324 unsigned long flags;
2325
2326 trace("%p", ep);
2327
2328 if (ep == NULL)
2329 return -EINVAL;
2330 else if (mEp->desc == NULL)
2331 return -EBUSY;
2332
2333 spin_lock_irqsave(mEp->lock, flags);
2334
2335 /* only internal SW should disable ctrl endpts */
2336
2337 direction = mEp->dir;
2338 do {
2339 dbg_event(_usb_addr(mEp), "DISABLE", 0);
2340
2341 retval |= _ep_nuke(mEp);
2342 retval |= hw_ep_disable(mEp->num, mEp->dir);
2343
2344 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2345 mEp->dir = (mEp->dir == TX) ? RX : TX;
2346
2347 } while (mEp->dir != direction);
2348
2349 mEp->desc = NULL;
2350
2351 spin_unlock_irqrestore(mEp->lock, flags);
2352 return retval;
2353}
2354
2355/**
2356 * ep_alloc_request: allocate a request object to use with this endpoint
2357 *
2358 * Check usb_ep_alloc_request() at "usb_gadget.h" for details
2359 */
2360static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
2361{
2362 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2363 struct ci13xxx_req *mReq = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002364
2365 trace("%p, %i", ep, gfp_flags);
2366
2367 if (ep == NULL) {
2368 err("EINVAL");
2369 return NULL;
2370 }
2371
David Lopoaa69a802008-11-17 14:14:51 -08002372 mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);
2373 if (mReq != NULL) {
2374 INIT_LIST_HEAD(&mReq->queue);
2375
2376 mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags,
2377 &mReq->dma);
2378 if (mReq->ptr == NULL) {
2379 kfree(mReq);
2380 mReq = NULL;
2381 }
2382 }
2383
2384 dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL);
2385
David Lopoaa69a802008-11-17 14:14:51 -08002386 return (mReq == NULL) ? NULL : &mReq->req;
2387}
2388
2389/**
2390 * ep_free_request: frees a request object
2391 *
2392 * Check usb_ep_free_request() at "usb_gadget.h" for details
2393 */
2394static void ep_free_request(struct usb_ep *ep, struct usb_request *req)
2395{
2396 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2397 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2398 unsigned long flags;
2399
2400 trace("%p, %p", ep, req);
2401
2402 if (ep == NULL || req == NULL) {
2403 err("EINVAL");
2404 return;
2405 } else if (!list_empty(&mReq->queue)) {
2406 err("EBUSY");
2407 return;
2408 }
2409
2410 spin_lock_irqsave(mEp->lock, flags);
2411
2412 if (mReq->ptr)
2413 dma_pool_free(mEp->td_pool, mReq->ptr, mReq->dma);
2414 kfree(mReq);
2415
2416 dbg_event(_usb_addr(mEp), "FREE", 0);
2417
2418 spin_unlock_irqrestore(mEp->lock, flags);
2419}
2420
2421/**
2422 * ep_queue: queues (submits) an I/O request to an endpoint
2423 *
2424 * Check usb_ep_queue()* at usb_gadget.h" for details
2425 */
2426static int ep_queue(struct usb_ep *ep, struct usb_request *req,
2427 gfp_t __maybe_unused gfp_flags)
2428{
2429 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2430 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2431 int retval = 0;
2432 unsigned long flags;
Anji jonnala6c174d42011-07-13 13:01:47 +05302433 struct ci13xxx *udc = _udc;
David Lopoaa69a802008-11-17 14:14:51 -08002434
2435 trace("%p, %p, %X", ep, req, gfp_flags);
2436
2437 if (ep == NULL || req == NULL || mEp->desc == NULL)
2438 return -EINVAL;
2439
2440 spin_lock_irqsave(mEp->lock, flags);
2441
Anji jonnala6c174d42011-07-13 13:01:47 +05302442 if (!udc->configured && mEp->type !=
2443 USB_ENDPOINT_XFER_CONTROL) {
2444 spin_unlock_irqrestore(mEp->lock, flags);
2445 trace("usb is not configured"
2446 "ept #%d, ept name#%s\n",
2447 mEp->num, mEp->ep.name);
2448 return -ESHUTDOWN;
2449 }
2450
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05302451 if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
2452 if (req->length)
2453 mEp = (_udc->ep0_dir == RX) ?
2454 &_udc->ep0out : &_udc->ep0in;
2455 if (!list_empty(&mEp->qh.queue)) {
2456 _ep_nuke(mEp);
2457 retval = -EOVERFLOW;
2458 warn("endpoint ctrl %X nuked", _usb_addr(mEp));
2459 }
David Lopoaa69a802008-11-17 14:14:51 -08002460 }
2461
2462 /* first nuke then test link, e.g. previous status has not sent */
2463 if (!list_empty(&mReq->queue)) {
2464 retval = -EBUSY;
2465 err("request already in queue");
2466 goto done;
2467 }
2468
Artem Leonenko0a313c42010-12-14 23:47:06 -08002469 if (req->length > (4 * CI13XXX_PAGE_SIZE)) {
2470 req->length = (4 * CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002471 retval = -EMSGSIZE;
2472 warn("request length truncated");
2473 }
2474
2475 dbg_queue(_usb_addr(mEp), req, retval);
2476
2477 /* push request */
2478 mReq->req.status = -EINPROGRESS;
2479 mReq->req.actual = 0;
David Lopoaa69a802008-11-17 14:14:51 -08002480
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302481 retval = _hardware_enqueue(mEp, mReq);
Artem Leonenkod9bb9c12010-12-14 23:45:50 -08002482
2483 if (retval == -EALREADY) {
David Lopoaa69a802008-11-17 14:14:51 -08002484 dbg_event(_usb_addr(mEp), "QUEUE", retval);
2485 retval = 0;
2486 }
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302487 if (!retval)
2488 list_add_tail(&mReq->queue, &mEp->qh.queue);
David Lopoaa69a802008-11-17 14:14:51 -08002489
2490 done:
2491 spin_unlock_irqrestore(mEp->lock, flags);
2492 return retval;
2493}
2494
2495/**
2496 * ep_dequeue: dequeues (cancels, unlinks) an I/O request from an endpoint
2497 *
2498 * Check usb_ep_dequeue() at "usb_gadget.h" for details
2499 */
2500static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
2501{
2502 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
Pavankumar Kondeti05cdbdb2011-09-12 09:13:12 +05302503 struct ci13xxx_ep *mEpTemp = mEp;
David Lopoaa69a802008-11-17 14:14:51 -08002504 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2505 unsigned long flags;
2506
2507 trace("%p, %p", ep, req);
2508
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302509 if (ep == NULL || req == NULL || mReq->req.status != -EALREADY ||
2510 mEp->desc == NULL || list_empty(&mReq->queue) ||
2511 list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08002512 return -EINVAL;
2513
2514 spin_lock_irqsave(mEp->lock, flags);
2515
2516 dbg_event(_usb_addr(mEp), "DEQUEUE", 0);
2517
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302518 hw_ep_flush(mEp->num, mEp->dir);
David Lopoaa69a802008-11-17 14:14:51 -08002519
2520 /* pop request */
2521 list_del_init(&mReq->queue);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302522 if (mReq->map) {
2523 dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
2524 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
2525 mReq->req.dma = 0;
2526 mReq->map = 0;
2527 }
David Lopoaa69a802008-11-17 14:14:51 -08002528 req->status = -ECONNRESET;
2529
Artem Leonenko7c25a822010-12-14 23:46:55 -08002530 if (mReq->req.complete != NULL) {
David Lopoaa69a802008-11-17 14:14:51 -08002531 spin_unlock(mEp->lock);
Pavankumar Kondeti05cdbdb2011-09-12 09:13:12 +05302532 if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
2533 mReq->req.length)
2534 mEpTemp = &_udc->ep0in;
2535 mReq->req.complete(&mEpTemp->ep, &mReq->req);
David Lopoaa69a802008-11-17 14:14:51 -08002536 spin_lock(mEp->lock);
2537 }
2538
2539 spin_unlock_irqrestore(mEp->lock, flags);
2540 return 0;
2541}
2542
2543/**
2544 * ep_set_halt: sets the endpoint halt feature
2545 *
2546 * Check usb_ep_set_halt() at "usb_gadget.h" for details
2547 */
2548static int ep_set_halt(struct usb_ep *ep, int value)
2549{
2550 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2551 int direction, retval = 0;
2552 unsigned long flags;
2553
2554 trace("%p, %i", ep, value);
2555
2556 if (ep == NULL || mEp->desc == NULL)
2557 return -EINVAL;
2558
2559 spin_lock_irqsave(mEp->lock, flags);
2560
2561#ifndef STALL_IN
2562 /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */
2563 if (value && mEp->type == USB_ENDPOINT_XFER_BULK && mEp->dir == TX &&
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302564 !list_empty(&mEp->qh.queue)) {
David Lopoaa69a802008-11-17 14:14:51 -08002565 spin_unlock_irqrestore(mEp->lock, flags);
2566 return -EAGAIN;
2567 }
2568#endif
2569
2570 direction = mEp->dir;
2571 do {
2572 dbg_event(_usb_addr(mEp), "HALT", value);
2573 retval |= hw_ep_set_halt(mEp->num, mEp->dir, value);
2574
2575 if (!value)
2576 mEp->wedge = 0;
2577
2578 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2579 mEp->dir = (mEp->dir == TX) ? RX : TX;
2580
2581 } while (mEp->dir != direction);
2582
2583 spin_unlock_irqrestore(mEp->lock, flags);
2584 return retval;
2585}
2586
2587/**
2588 * ep_set_wedge: sets the halt feature and ignores clear requests
2589 *
2590 * Check usb_ep_set_wedge() at "usb_gadget.h" for details
2591 */
2592static int ep_set_wedge(struct usb_ep *ep)
2593{
2594 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2595 unsigned long flags;
2596
2597 trace("%p", ep);
2598
2599 if (ep == NULL || mEp->desc == NULL)
2600 return -EINVAL;
2601
2602 spin_lock_irqsave(mEp->lock, flags);
2603
2604 dbg_event(_usb_addr(mEp), "WEDGE", 0);
2605 mEp->wedge = 1;
2606
2607 spin_unlock_irqrestore(mEp->lock, flags);
2608
2609 return usb_ep_set_halt(ep);
2610}
2611
2612/**
2613 * ep_fifo_flush: flushes contents of a fifo
2614 *
2615 * Check usb_ep_fifo_flush() at "usb_gadget.h" for details
2616 */
2617static void ep_fifo_flush(struct usb_ep *ep)
2618{
2619 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2620 unsigned long flags;
2621
2622 trace("%p", ep);
2623
2624 if (ep == NULL) {
2625 err("%02X: -EINVAL", _usb_addr(mEp));
2626 return;
2627 }
2628
2629 spin_lock_irqsave(mEp->lock, flags);
2630
2631 dbg_event(_usb_addr(mEp), "FFLUSH", 0);
2632 hw_ep_flush(mEp->num, mEp->dir);
2633
2634 spin_unlock_irqrestore(mEp->lock, flags);
2635}
2636
2637/**
2638 * Endpoint-specific part of the API to the USB controller hardware
2639 * Check "usb_gadget.h" for details
2640 */
2641static const struct usb_ep_ops usb_ep_ops = {
2642 .enable = ep_enable,
2643 .disable = ep_disable,
2644 .alloc_request = ep_alloc_request,
2645 .free_request = ep_free_request,
2646 .queue = ep_queue,
2647 .dequeue = ep_dequeue,
2648 .set_halt = ep_set_halt,
2649 .set_wedge = ep_set_wedge,
2650 .fifo_flush = ep_fifo_flush,
2651};
2652
2653/******************************************************************************
2654 * GADGET block
2655 *****************************************************************************/
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302656static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
2657{
2658 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2659 unsigned long flags;
2660 int gadget_ready = 0;
2661
2662 if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS))
2663 return -EOPNOTSUPP;
2664
2665 spin_lock_irqsave(udc->lock, flags);
2666 udc->vbus_active = is_active;
2667 if (udc->driver)
2668 gadget_ready = 1;
2669 spin_unlock_irqrestore(udc->lock, flags);
2670
2671 if (gadget_ready) {
2672 if (is_active) {
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302673 pm_runtime_get_sync(&_gadget->dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302674 hw_device_reset(udc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002675 if (udc->softconnect)
2676 hw_device_state(udc->ep0out.qh.dma);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302677 } else {
2678 hw_device_state(0);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302679 _gadget_stop_activity(&udc->gadget);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302680 pm_runtime_put_sync(&_gadget->dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302681 }
2682 }
2683
2684 return 0;
2685}
2686
Pavankumar Kondetid8608522011-05-04 10:19:47 +05302687static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
2688{
2689 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2690
2691 if (udc->transceiver)
2692 return otg_set_power(udc->transceiver, mA);
2693 return -ENOTSUPP;
2694}
2695
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002696static int ci13xxx_pullup(struct usb_gadget *_gadget, int is_active)
2697{
2698 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2699 unsigned long flags;
2700
2701 spin_lock_irqsave(udc->lock, flags);
2702 udc->softconnect = is_active;
2703 if (((udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) &&
2704 !udc->vbus_active) || !udc->driver) {
2705 spin_unlock_irqrestore(udc->lock, flags);
2706 return 0;
2707 }
2708 spin_unlock_irqrestore(udc->lock, flags);
2709
Pavankumar Kondetib7f53dc2011-08-23 12:40:33 +05302710 if (is_active)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002711 hw_device_state(udc->ep0out.qh.dma);
Pavankumar Kondetib7f53dc2011-08-23 12:40:33 +05302712 else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002713 hw_device_state(0);
Pavankumar Kondetib7f53dc2011-08-23 12:40:33 +05302714
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002715 return 0;
2716}
2717
2718
David Lopoaa69a802008-11-17 14:14:51 -08002719/**
2720 * Device operations part of the API to the USB controller hardware,
2721 * which don't involve endpoints (or i/o)
2722 * Check "usb_gadget.h" for details
2723 */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302724static const struct usb_gadget_ops usb_gadget_ops = {
2725 .vbus_session = ci13xxx_vbus_session,
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302726 .wakeup = ci13xxx_wakeup,
Pavankumar Kondetid8608522011-05-04 10:19:47 +05302727 .vbus_draw = ci13xxx_vbus_draw,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002728 .pullup = ci13xxx_pullup,
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302729};
David Lopoaa69a802008-11-17 14:14:51 -08002730
2731/**
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002732 * usb_gadget_probe_driver: register a gadget driver
2733 * @driver: the driver being registered
2734 * @bind: the driver's bind callback
David Lopoaa69a802008-11-17 14:14:51 -08002735 *
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002736 * Check usb_gadget_probe_driver() at <linux/usb/gadget.h> for details.
2737 * Interrupts are enabled here.
David Lopoaa69a802008-11-17 14:14:51 -08002738 */
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002739int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
2740 int (*bind)(struct usb_gadget *))
David Lopoaa69a802008-11-17 14:14:51 -08002741{
2742 struct ci13xxx *udc = _udc;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302743 unsigned long flags;
2744 int i, j;
David Lopoaa69a802008-11-17 14:14:51 -08002745 int retval = -ENOMEM;
2746
2747 trace("%p", driver);
2748
2749 if (driver == NULL ||
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002750 bind == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002751 driver->setup == NULL ||
2752 driver->disconnect == NULL ||
2753 driver->suspend == NULL ||
2754 driver->resume == NULL)
2755 return -EINVAL;
2756 else if (udc == NULL)
2757 return -ENODEV;
2758 else if (udc->driver != NULL)
2759 return -EBUSY;
2760
2761 /* alloc resources */
2762 udc->qh_pool = dma_pool_create("ci13xxx_qh", &udc->gadget.dev,
2763 sizeof(struct ci13xxx_qh),
Artem Leonenko0a313c42010-12-14 23:47:06 -08002764 64, CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002765 if (udc->qh_pool == NULL)
2766 return -ENOMEM;
2767
2768 udc->td_pool = dma_pool_create("ci13xxx_td", &udc->gadget.dev,
2769 sizeof(struct ci13xxx_td),
Artem Leonenko0a313c42010-12-14 23:47:06 -08002770 64, CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002771 if (udc->td_pool == NULL) {
2772 dma_pool_destroy(udc->qh_pool);
2773 udc->qh_pool = NULL;
2774 return -ENOMEM;
2775 }
2776
2777 spin_lock_irqsave(udc->lock, flags);
2778
2779 info("hw_ep_max = %d", hw_ep_max);
2780
David Lopoaa69a802008-11-17 14:14:51 -08002781 udc->gadget.dev.driver = NULL;
2782
2783 retval = 0;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302784 for (i = 0; i < hw_ep_max/2; i++) {
2785 for (j = RX; j <= TX; j++) {
2786 int k = i + j * hw_ep_max/2;
2787 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[k];
David Lopoaa69a802008-11-17 14:14:51 -08002788
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302789 scnprintf(mEp->name, sizeof(mEp->name), "ep%i%s", i,
2790 (j == TX) ? "in" : "out");
David Lopoaa69a802008-11-17 14:14:51 -08002791
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302792 mEp->lock = udc->lock;
2793 mEp->device = &udc->gadget.dev;
2794 mEp->td_pool = udc->td_pool;
David Lopoaa69a802008-11-17 14:14:51 -08002795
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302796 mEp->ep.name = mEp->name;
2797 mEp->ep.ops = &usb_ep_ops;
2798 mEp->ep.maxpacket = CTRL_PAYLOAD_MAX;
David Lopoaa69a802008-11-17 14:14:51 -08002799
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302800 INIT_LIST_HEAD(&mEp->qh.queue);
Pavankumar Kondeti0a91efa2010-12-07 17:54:00 +05302801 spin_unlock_irqrestore(udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302802 mEp->qh.ptr = dma_pool_alloc(udc->qh_pool, GFP_KERNEL,
2803 &mEp->qh.dma);
Pavankumar Kondeti0a91efa2010-12-07 17:54:00 +05302804 spin_lock_irqsave(udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302805 if (mEp->qh.ptr == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002806 retval = -ENOMEM;
2807 else
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302808 memset(mEp->qh.ptr, 0, sizeof(*mEp->qh.ptr));
2809
2810 /* skip ep0 out and in endpoints */
2811 if (i == 0)
2812 continue;
2813
David Lopoaa69a802008-11-17 14:14:51 -08002814 list_add_tail(&mEp->ep.ep_list, &udc->gadget.ep_list);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302815 }
David Lopoaa69a802008-11-17 14:14:51 -08002816 }
2817 if (retval)
2818 goto done;
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302819 spin_unlock_irqrestore(udc->lock, flags);
2820 retval = usb_ep_enable(&udc->ep0out.ep, &ctrl_endpt_out_desc);
2821 if (retval)
2822 return retval;
2823 retval = usb_ep_enable(&udc->ep0in.ep, &ctrl_endpt_in_desc);
2824 if (retval)
2825 return retval;
2826 spin_lock_irqsave(udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002827
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302828 udc->gadget.ep0 = &udc->ep0in.ep;
David Lopoaa69a802008-11-17 14:14:51 -08002829 /* bind gadget */
2830 driver->driver.bus = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002831 udc->gadget.dev.driver = &driver->driver;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002832 udc->softconnect = 1;
David Lopoaa69a802008-11-17 14:14:51 -08002833
2834 spin_unlock_irqrestore(udc->lock, flags);
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002835 retval = bind(&udc->gadget); /* MAY SLEEP */
David Lopoaa69a802008-11-17 14:14:51 -08002836 spin_lock_irqsave(udc->lock, flags);
2837
2838 if (retval) {
David Lopoaa69a802008-11-17 14:14:51 -08002839 udc->gadget.dev.driver = NULL;
2840 goto done;
2841 }
2842
Pavankumar Kondeti49d3df52011-01-11 09:19:21 +05302843 udc->driver = driver;
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302844 pm_runtime_get_sync(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302845 if (udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) {
2846 if (udc->vbus_active) {
2847 if (udc->udc_driver->flags & CI13XXX_REGS_SHARED)
2848 hw_device_reset(udc);
2849 } else {
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302850 pm_runtime_put_sync(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302851 goto done;
2852 }
2853 }
2854
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002855 if (!udc->softconnect)
2856 goto done;
2857
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302858 retval = hw_device_state(udc->ep0out.qh.dma);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302859 if (retval)
2860 pm_runtime_put_sync(&udc->gadget.dev);
David Lopoaa69a802008-11-17 14:14:51 -08002861
2862 done:
2863 spin_unlock_irqrestore(udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002864 return retval;
2865}
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002866EXPORT_SYMBOL(usb_gadget_probe_driver);
David Lopoaa69a802008-11-17 14:14:51 -08002867
2868/**
2869 * usb_gadget_unregister_driver: unregister a gadget driver
2870 *
2871 * Check usb_gadget_unregister_driver() at "usb_gadget.h" for details
2872 */
2873int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
2874{
2875 struct ci13xxx *udc = _udc;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302876 unsigned long i, flags;
David Lopoaa69a802008-11-17 14:14:51 -08002877
2878 trace("%p", driver);
2879
2880 if (driver == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002881 driver->unbind == NULL ||
2882 driver->setup == NULL ||
2883 driver->disconnect == NULL ||
2884 driver->suspend == NULL ||
2885 driver->resume == NULL ||
2886 driver != udc->driver)
2887 return -EINVAL;
2888
2889 spin_lock_irqsave(udc->lock, flags);
2890
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302891 if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) ||
2892 udc->vbus_active) {
2893 hw_device_state(0);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302894 _gadget_stop_activity(&udc->gadget);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302895 pm_runtime_put(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302896 }
David Lopoaa69a802008-11-17 14:14:51 -08002897
2898 /* unbind gadget */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302899 spin_unlock_irqrestore(udc->lock, flags);
2900 driver->unbind(&udc->gadget); /* MAY SLEEP */
2901 spin_lock_irqsave(udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002902
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302903 udc->gadget.dev.driver = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002904
2905 /* free resources */
2906 for (i = 0; i < hw_ep_max; i++) {
2907 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
2908
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302909 if (!list_empty(&mEp->ep.ep_list))
David Lopoaa69a802008-11-17 14:14:51 -08002910 list_del_init(&mEp->ep.ep_list);
2911
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302912 if (mEp->qh.ptr != NULL)
2913 dma_pool_free(udc->qh_pool, mEp->qh.ptr, mEp->qh.dma);
David Lopoaa69a802008-11-17 14:14:51 -08002914 }
2915
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302916 udc->gadget.ep0 = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002917 udc->driver = NULL;
2918
2919 spin_unlock_irqrestore(udc->lock, flags);
2920
2921 if (udc->td_pool != NULL) {
2922 dma_pool_destroy(udc->td_pool);
2923 udc->td_pool = NULL;
2924 }
2925 if (udc->qh_pool != NULL) {
2926 dma_pool_destroy(udc->qh_pool);
2927 udc->qh_pool = NULL;
2928 }
2929
2930 return 0;
2931}
2932EXPORT_SYMBOL(usb_gadget_unregister_driver);
2933
2934/******************************************************************************
2935 * BUS block
2936 *****************************************************************************/
2937/**
2938 * udc_irq: global interrupt handler
2939 *
2940 * This function returns IRQ_HANDLED if the IRQ has been handled
2941 * It locks access to registers
2942 */
2943static irqreturn_t udc_irq(void)
2944{
2945 struct ci13xxx *udc = _udc;
2946 irqreturn_t retval;
2947 u32 intr;
2948
2949 trace();
2950
2951 if (udc == NULL) {
2952 err("ENODEV");
2953 return IRQ_HANDLED;
2954 }
2955
2956 spin_lock(udc->lock);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302957
2958 if (udc->udc_driver->flags & CI13XXX_REGS_SHARED) {
2959 if (hw_cread(CAP_USBMODE, USBMODE_CM) !=
2960 USBMODE_CM_DEVICE) {
2961 spin_unlock(udc->lock);
2962 return IRQ_NONE;
2963 }
2964 }
David Lopoaa69a802008-11-17 14:14:51 -08002965 intr = hw_test_and_clear_intr_active();
2966 if (intr) {
2967 isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intr;
2968 isr_statistics.hndl.idx &= ISR_MASK;
2969 isr_statistics.hndl.cnt++;
2970
2971 /* order defines priority - do NOT change it */
2972 if (USBi_URI & intr) {
2973 isr_statistics.uri++;
2974 isr_reset_handler(udc);
2975 }
2976 if (USBi_PCI & intr) {
2977 isr_statistics.pci++;
2978 udc->gadget.speed = hw_port_is_high_speed() ?
2979 USB_SPEED_HIGH : USB_SPEED_FULL;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302980 if (udc->suspended) {
2981 spin_unlock(udc->lock);
2982 udc->driver->resume(&udc->gadget);
2983 spin_lock(udc->lock);
2984 udc->suspended = 0;
2985 }
David Lopoaa69a802008-11-17 14:14:51 -08002986 }
2987 if (USBi_UEI & intr)
2988 isr_statistics.uei++;
2989 if (USBi_UI & intr) {
2990 isr_statistics.ui++;
2991 isr_tr_complete_handler(udc);
2992 }
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302993 if (USBi_SLI & intr) {
2994 if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
2995 udc->suspended = 1;
2996 spin_unlock(udc->lock);
2997 udc->driver->suspend(&udc->gadget);
2998 spin_lock(udc->lock);
2999 }
David Lopoaa69a802008-11-17 14:14:51 -08003000 isr_statistics.sli++;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05303001 }
David Lopoaa69a802008-11-17 14:14:51 -08003002 retval = IRQ_HANDLED;
3003 } else {
3004 isr_statistics.none++;
3005 retval = IRQ_NONE;
3006 }
3007 spin_unlock(udc->lock);
3008
3009 return retval;
3010}
3011
3012/**
3013 * udc_release: driver release function
3014 * @dev: device
3015 *
3016 * Currently does nothing
3017 */
3018static void udc_release(struct device *dev)
3019{
3020 trace("%p", dev);
3021
3022 if (dev == NULL)
3023 err("EINVAL");
3024}
3025
3026/**
3027 * udc_probe: parent probe must call this to initialize UDC
3028 * @dev: parent device
3029 * @regs: registers base address
3030 * @name: driver name
3031 *
3032 * This function returns an error code
3033 * No interrupts active, the IRQ has not been requested yet
3034 * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask
3035 */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05303036static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev,
3037 void __iomem *regs)
David Lopoaa69a802008-11-17 14:14:51 -08003038{
3039 struct ci13xxx *udc;
3040 int retval = 0;
3041
3042 trace("%p, %p, %p", dev, regs, name);
3043
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05303044 if (dev == NULL || regs == NULL || driver == NULL ||
3045 driver->name == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08003046 return -EINVAL;
3047
3048 udc = kzalloc(sizeof(struct ci13xxx), GFP_KERNEL);
3049 if (udc == NULL)
3050 return -ENOMEM;
3051
3052 udc->lock = &udc_lock;
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05303053 udc->regs = regs;
3054 udc->udc_driver = driver;
David Lopoaa69a802008-11-17 14:14:51 -08003055
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05303056 udc->gadget.ops = &usb_gadget_ops;
David Lopoaa69a802008-11-17 14:14:51 -08003057 udc->gadget.speed = USB_SPEED_UNKNOWN;
3058 udc->gadget.is_dualspeed = 1;
3059 udc->gadget.is_otg = 0;
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05303060 udc->gadget.name = driver->name;
David Lopoaa69a802008-11-17 14:14:51 -08003061
3062 INIT_LIST_HEAD(&udc->gadget.ep_list);
3063 udc->gadget.ep0 = NULL;
3064
Kay Sievers5df58522009-03-24 16:38:23 -07003065 dev_set_name(&udc->gadget.dev, "gadget");
David Lopoaa69a802008-11-17 14:14:51 -08003066 udc->gadget.dev.dma_mask = dev->dma_mask;
Pavankumar Kondeti61948ee2010-12-07 17:54:01 +05303067 udc->gadget.dev.coherent_dma_mask = dev->coherent_dma_mask;
David Lopoaa69a802008-11-17 14:14:51 -08003068 udc->gadget.dev.parent = dev;
3069 udc->gadget.dev.release = udc_release;
3070
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05303071 retval = hw_device_init(regs);
3072 if (retval < 0)
3073 goto free_udc;
3074
3075 udc->transceiver = otg_get_transceiver();
3076
3077 if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) {
3078 if (udc->transceiver == NULL) {
3079 retval = -ENODEV;
3080 goto free_udc;
3081 }
3082 }
3083
3084 if (!(udc->udc_driver->flags & CI13XXX_REGS_SHARED)) {
3085 retval = hw_device_reset(udc);
3086 if (retval)
3087 goto put_transceiver;
3088 }
3089
David Lopoaa69a802008-11-17 14:14:51 -08003090 retval = device_register(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05303091 if (retval) {
3092 put_device(&udc->gadget.dev);
3093 goto put_transceiver;
3094 }
David Lopoaa69a802008-11-17 14:14:51 -08003095
3096#ifdef CONFIG_USB_GADGET_DEBUG_FILES
3097 retval = dbg_create_files(&udc->gadget.dev);
3098#endif
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05303099 if (retval)
3100 goto unreg_device;
3101
3102 if (udc->transceiver) {
3103 retval = otg_set_peripheral(udc->transceiver, &udc->gadget);
3104 if (retval)
3105 goto remove_dbg;
David Lopoaa69a802008-11-17 14:14:51 -08003106 }
Pavankumar Kondetic0360192010-12-07 17:54:04 +05303107 pm_runtime_no_callbacks(&udc->gadget.dev);
3108 pm_runtime_enable(&udc->gadget.dev);
David Lopoaa69a802008-11-17 14:14:51 -08003109
3110 _udc = udc;
3111 return retval;
3112
David Lopoaa69a802008-11-17 14:14:51 -08003113 err("error = %i", retval);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05303114remove_dbg:
3115#ifdef CONFIG_USB_GADGET_DEBUG_FILES
3116 dbg_remove_files(&udc->gadget.dev);
3117#endif
3118unreg_device:
3119 device_unregister(&udc->gadget.dev);
3120put_transceiver:
3121 if (udc->transceiver)
3122 otg_put_transceiver(udc->transceiver);
3123free_udc:
David Lopoaa69a802008-11-17 14:14:51 -08003124 kfree(udc);
3125 _udc = NULL;
3126 return retval;
3127}
3128
3129/**
3130 * udc_remove: parent remove must call this to remove UDC
3131 *
3132 * No interrupts active, the IRQ has been released
3133 */
3134static void udc_remove(void)
3135{
3136 struct ci13xxx *udc = _udc;
3137
3138 if (udc == NULL) {
3139 err("EINVAL");
3140 return;
3141 }
3142
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05303143 if (udc->transceiver) {
3144 otg_set_peripheral(udc->transceiver, &udc->gadget);
3145 otg_put_transceiver(udc->transceiver);
3146 }
David Lopoaa69a802008-11-17 14:14:51 -08003147#ifdef CONFIG_USB_GADGET_DEBUG_FILES
3148 dbg_remove_files(&udc->gadget.dev);
3149#endif
3150 device_unregister(&udc->gadget.dev);
3151
3152 kfree(udc);
3153 _udc = NULL;
3154}