1 From f12c49e8bf1ac056946bc3098c6c361d51891916 Mon Sep 17 00:00:00 2001
2 From: Henry Yuan <hang.yuan@intel.com>
3 Date: Thu, 6 May 2010 19:30:00 +0800
4 Subject: [PATCH] Moorestown USB-OTG drivers full patch 0.2 for MeeGo
6 This is a consolidated full patch against K2.6.33. It
7 includes USB-OTG client controller driver, transceiver
8 driver, still image gadget driver and fixing for sighting
9 3469616: OTG driver hangs in suspend function.
11 OTG host, client functions and role switch per cable
13 Known issue: HNP/SRP have problem.
16 CONFIG_USB_LANGWELL_OTG = y
17 CONFIG_USB_OTG_WHITELIST = n
19 CONFIG_USB_GADGET_LANGWELL = y
21 CONFIG_USB_STILL_IMAGE = y
22 or select other gadget driver as needed.
24 Signed-off-by: Henry Yuan <hang.yuan@intel.com>
25 Patch-mainline: 2.6.34
27 drivers/usb/gadget/Kconfig | 8 +
28 drivers/usb/gadget/Makefile | 2 +
29 drivers/usb/gadget/f_ecm.c | 22 +
30 drivers/usb/gadget/f_subset.c | 22 +
31 drivers/usb/gadget/langwell_udc.c | 582 ++++--
32 drivers/usb/gadget/langwell_udc.h | 13 +-
33 drivers/usb/gadget/still_image.c | 4566 +++++++++++++++++++++++++++++++++++++
34 drivers/usb/otg/Kconfig | 14 +
35 drivers/usb/otg/Makefile | 1 +
36 drivers/usb/otg/langwell_otg.c | 2260 ++++++++++++++++++
37 include/linux/usb/langwell_otg.h | 201 ++
38 include/linux/usb/langwell_udc.h | 13 +
39 12 files changed, 7516 insertions(+), 188 deletions(-)
40 create mode 100644 drivers/usb/gadget/still_image.c
41 create mode 100644 drivers/usb/otg/langwell_otg.c
42 create mode 100644 include/linux/usb/langwell_otg.h
44 diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
45 index ee41120..94cc94f 100644
46 --- a/drivers/usb/gadget/Kconfig
47 +++ b/drivers/usb/gadget/Kconfig
48 @@ -853,6 +853,14 @@ config USB_G_MULTI_CDC
52 +config USB_STILL_IMAGE
53 + tristate "Lite Still Image Gadget"
55 + The Lite Still Image Gadget implements object transfer based on
56 + spec PIMA 15740:2000.
58 + Say "y" to link the driver statically, or "m" to build a dynamically
59 + linked module called "g_still_image".
61 # put drivers that need isochronous transfer support (for audio
62 # or video class gadget drivers), or specific hardware, here.
63 diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
64 index 2e2c047..7ef974e 100644
65 --- a/drivers/usb/gadget/Makefile
66 +++ b/drivers/usb/gadget/Makefile
67 @@ -43,6 +43,7 @@ g_mass_storage-objs := mass_storage.o
68 g_printer-objs := printer.o
70 g_multi-objs := multi.o
71 +g_still_image-objs := still_image.o
73 obj-$(CONFIG_USB_ZERO) += g_zero.o
74 obj-$(CONFIG_USB_AUDIO) += g_audio.o
75 @@ -55,4 +56,5 @@ obj-$(CONFIG_USB_G_PRINTER) += g_printer.o
76 obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o
77 obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o
78 obj-$(CONFIG_USB_G_MULTI) += g_multi.o
79 +obj-$(CONFIG_USB_STILL_IMAGE) += g_still_image.o
81 diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
82 index ecf5bdd..d004328 100644
83 --- a/drivers/usb/gadget/f_ecm.c
84 +++ b/drivers/usb/gadget/f_ecm.c
85 @@ -753,6 +753,26 @@ ecm_unbind(struct usb_configuration *c, struct usb_function *f)
90 +ecm_suspend(struct usb_function *f)
92 + struct f_ecm *ecm = func_to_ecm(f);
93 + struct eth_dev *dev = ecm->port.ioport;
96 + gether_disconnect(&ecm->port);
100 +ecm_resume(struct usb_function *f)
102 + struct f_ecm *ecm = func_to_ecm(f);
103 + struct eth_dev *dev = ecm->port.ioport;
106 + gether_connect(&ecm->port);
110 * ecm_bind_config - add CDC Ethernet network link to a configuration
111 * @c: the configuration to support the network link
112 @@ -821,6 +841,8 @@ int __init ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
113 ecm->port.func.get_alt = ecm_get_alt;
114 ecm->port.func.setup = ecm_setup;
115 ecm->port.func.disable = ecm_disable;
116 + ecm->port.func.suspend = ecm_suspend;
117 + ecm->port.func.resume = ecm_resume;
119 status = usb_add_function(c, &ecm->port.func);
121 diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
122 index a9c98fd..893816d 100644
123 --- a/drivers/usb/gadget/f_subset.c
124 +++ b/drivers/usb/gadget/f_subset.c
125 @@ -353,6 +353,26 @@ geth_unbind(struct usb_configuration *c, struct usb_function *f)
126 kfree(func_to_geth(f));
130 +geth_suspend(struct usb_function *f)
132 + struct f_gether *geth = func_to_geth(f);
133 + struct eth_dev *dev = geth->port.ioport;
136 + gether_disconnect(&geth->port);
140 +geth_resume(struct usb_function *f)
142 + struct f_gether *geth = func_to_geth(f);
143 + struct eth_dev *dev = geth->port.ioport;
146 + gether_connect(&geth->port);
150 * geth_bind_config - add CDC Subset network link to a configuration
151 * @c: the configuration to support the network link
152 @@ -411,6 +431,8 @@ int __init geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
153 geth->port.func.unbind = geth_unbind;
154 geth->port.func.set_alt = geth_set_alt;
155 geth->port.func.disable = geth_disable;
156 + geth->port.func.resume = geth_resume;
157 + geth->port.func.suspend = geth_suspend;
159 status = usb_add_function(c, &geth->port.func);
161 diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c
162 index a391351..eb0e185 100644
163 --- a/drivers/usb/gadget/langwell_udc.c
164 +++ b/drivers/usb/gadget/langwell_udc.c
168 #define DRIVER_DESC "Intel Langwell USB Device Controller driver"
169 -#define DRIVER_VERSION "16 May 2009"
170 +#define DRIVER_VERSION "Apr 30, 2010"
172 static const char driver_name[] = "langwell_udc";
173 static const char driver_desc[] = DRIVER_DESC;
174 @@ -73,7 +73,6 @@ langwell_ep0_desc = {
175 .wMaxPacketSize = EP0_MAX_PKT_SIZE,
179 /*-------------------------------------------------------------------------*/
182 @@ -114,104 +113,76 @@ static inline void print_all_registers(struct langwell_udc *dev)
185 /* Capability Registers */
186 - printk(KERN_DEBUG "Capability Registers (offset: "
187 - "0x%04x, length: 0x%08x)\n",
189 - (u32)sizeof(struct langwell_cap_regs));
190 - printk(KERN_DEBUG "caplength=0x%02x\n",
191 - readb(&dev->cap_regs->caplength));
192 - printk(KERN_DEBUG "hciversion=0x%04x\n",
193 - readw(&dev->cap_regs->hciversion));
194 - printk(KERN_DEBUG "hcsparams=0x%08x\n",
195 - readl(&dev->cap_regs->hcsparams));
196 - printk(KERN_DEBUG "hccparams=0x%08x\n",
197 - readl(&dev->cap_regs->hccparams));
198 - printk(KERN_DEBUG "dciversion=0x%04x\n",
199 - readw(&dev->cap_regs->dciversion));
200 - printk(KERN_DEBUG "dccparams=0x%08x\n",
201 - readl(&dev->cap_regs->dccparams));
202 + DBG(dev, "Capability Registers (offset: 0x%04x, length: 0x%08x)\n",
203 + CAP_REG_OFFSET, (u32)sizeof(struct langwell_cap_regs));
204 + DBG(dev, "caplength=0x%02x\n", readb(&dev->cap_regs->caplength));
205 + DBG(dev, "hciversion=0x%04x\n", readw(&dev->cap_regs->hciversion));
206 + DBG(dev, "hcsparams=0x%08x\n", readl(&dev->cap_regs->hcsparams));
207 + DBG(dev, "hccparams=0x%08x\n", readl(&dev->cap_regs->hccparams));
208 + DBG(dev, "dciversion=0x%04x\n", readw(&dev->cap_regs->dciversion));
209 + DBG(dev, "dccparams=0x%08x\n", readl(&dev->cap_regs->dccparams));
211 /* Operational Registers */
212 - printk(KERN_DEBUG "Operational Registers (offset: "
213 - "0x%04x, length: 0x%08x)\n",
215 - (u32)sizeof(struct langwell_op_regs));
216 - printk(KERN_DEBUG "extsts=0x%08x\n",
217 - readl(&dev->op_regs->extsts));
218 - printk(KERN_DEBUG "extintr=0x%08x\n",
219 - readl(&dev->op_regs->extintr));
220 - printk(KERN_DEBUG "usbcmd=0x%08x\n",
221 - readl(&dev->op_regs->usbcmd));
222 - printk(KERN_DEBUG "usbsts=0x%08x\n",
223 - readl(&dev->op_regs->usbsts));
224 - printk(KERN_DEBUG "usbintr=0x%08x\n",
225 - readl(&dev->op_regs->usbintr));
226 - printk(KERN_DEBUG "frindex=0x%08x\n",
227 - readl(&dev->op_regs->frindex));
228 - printk(KERN_DEBUG "ctrldssegment=0x%08x\n",
229 + DBG(dev, "Operational Registers (offset: 0x%04x, length: 0x%08x)\n",
230 + OP_REG_OFFSET, (u32)sizeof(struct langwell_op_regs));
231 + DBG(dev, "extsts=0x%08x\n", readl(&dev->op_regs->extsts));
232 + DBG(dev, "extintr=0x%08x\n", readl(&dev->op_regs->extintr));
233 + DBG(dev, "usbcmd=0x%08x\n", readl(&dev->op_regs->usbcmd));
234 + DBG(dev, "usbsts=0x%08x\n", readl(&dev->op_regs->usbsts));
235 + DBG(dev, "usbintr=0x%08x\n", readl(&dev->op_regs->usbintr));
236 + DBG(dev, "frindex=0x%08x\n", readl(&dev->op_regs->frindex));
237 + DBG(dev, "ctrldssegment=0x%08x\n",
238 readl(&dev->op_regs->ctrldssegment));
239 - printk(KERN_DEBUG "deviceaddr=0x%08x\n",
240 - readl(&dev->op_regs->deviceaddr));
241 - printk(KERN_DEBUG "endpointlistaddr=0x%08x\n",
242 + DBG(dev, "deviceaddr=0x%08x\n", readl(&dev->op_regs->deviceaddr));
243 + DBG(dev, "endpointlistaddr=0x%08x\n",
244 readl(&dev->op_regs->endpointlistaddr));
245 - printk(KERN_DEBUG "ttctrl=0x%08x\n",
246 - readl(&dev->op_regs->ttctrl));
247 - printk(KERN_DEBUG "burstsize=0x%08x\n",
248 - readl(&dev->op_regs->burstsize));
249 - printk(KERN_DEBUG "txfilltuning=0x%08x\n",
250 - readl(&dev->op_regs->txfilltuning));
251 - printk(KERN_DEBUG "txttfilltuning=0x%08x\n",
252 + DBG(dev, "ttctrl=0x%08x\n", readl(&dev->op_regs->ttctrl));
253 + DBG(dev, "burstsize=0x%08x\n", readl(&dev->op_regs->burstsize));
254 + DBG(dev, "txfilltuning=0x%08x\n", readl(&dev->op_regs->txfilltuning));
255 + DBG(dev, "txttfilltuning=0x%08x\n",
256 readl(&dev->op_regs->txttfilltuning));
257 - printk(KERN_DEBUG "ic_usb=0x%08x\n",
258 - readl(&dev->op_regs->ic_usb));
259 - printk(KERN_DEBUG "ulpi_viewport=0x%08x\n",
260 + DBG(dev, "ic_usb=0x%08x\n", readl(&dev->op_regs->ic_usb));
261 + DBG(dev, "ulpi_viewport=0x%08x\n",
262 readl(&dev->op_regs->ulpi_viewport));
263 - printk(KERN_DEBUG "configflag=0x%08x\n",
264 - readl(&dev->op_regs->configflag));
265 - printk(KERN_DEBUG "portsc1=0x%08x\n",
266 - readl(&dev->op_regs->portsc1));
267 - printk(KERN_DEBUG "devlc=0x%08x\n",
268 - readl(&dev->op_regs->devlc));
269 - printk(KERN_DEBUG "otgsc=0x%08x\n",
270 - readl(&dev->op_regs->otgsc));
271 - printk(KERN_DEBUG "usbmode=0x%08x\n",
272 - readl(&dev->op_regs->usbmode));
273 - printk(KERN_DEBUG "endptnak=0x%08x\n",
274 - readl(&dev->op_regs->endptnak));
275 - printk(KERN_DEBUG "endptnaken=0x%08x\n",
276 - readl(&dev->op_regs->endptnaken));
277 - printk(KERN_DEBUG "endptsetupstat=0x%08x\n",
278 + DBG(dev, "configflag=0x%08x\n", readl(&dev->op_regs->configflag));
279 + DBG(dev, "portsc1=0x%08x\n", readl(&dev->op_regs->portsc1));
280 + DBG(dev, "devlc=0x%08x\n", readl(&dev->op_regs->devlc));
281 + DBG(dev, "otgsc=0x%08x\n", readl(&dev->op_regs->otgsc));
282 + DBG(dev, "usbmode=0x%08x\n", readl(&dev->op_regs->usbmode));
283 + DBG(dev, "endptnak=0x%08x\n", readl(&dev->op_regs->endptnak));
284 + DBG(dev, "endptnaken=0x%08x\n", readl(&dev->op_regs->endptnaken));
285 + DBG(dev, "endptsetupstat=0x%08x\n",
286 readl(&dev->op_regs->endptsetupstat));
287 - printk(KERN_DEBUG "endptprime=0x%08x\n",
288 - readl(&dev->op_regs->endptprime));
289 - printk(KERN_DEBUG "endptflush=0x%08x\n",
290 - readl(&dev->op_regs->endptflush));
291 - printk(KERN_DEBUG "endptstat=0x%08x\n",
292 - readl(&dev->op_regs->endptstat));
293 - printk(KERN_DEBUG "endptcomplete=0x%08x\n",
294 + DBG(dev, "endptprime=0x%08x\n", readl(&dev->op_regs->endptprime));
295 + DBG(dev, "endptflush=0x%08x\n", readl(&dev->op_regs->endptflush));
296 + DBG(dev, "endptstat=0x%08x\n", readl(&dev->op_regs->endptstat));
297 + DBG(dev, "endptcomplete=0x%08x\n",
298 readl(&dev->op_regs->endptcomplete));
300 for (i = 0; i < dev->ep_max / 2; i++) {
301 - printk(KERN_DEBUG "endptctrl[%d]=0x%08x\n",
302 + DBG(dev, "endptctrl[%d]=0x%08x\n",
303 i, readl(&dev->op_regs->endptctrl[i]));
308 +#define print_all_registers(dev) do { } while (0)
313 /*-------------------------------------------------------------------------*/
315 -#define DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out")
316 +#define is_in(ep) (((ep)->ep_num == 0) ? ((ep)->dev->ep0_dir == \
317 + USB_DIR_IN) : (usb_endpoint_dir_in((ep)->desc)))
319 -#define is_in(ep) (((ep)->ep_num == 0) ? ((ep)->dev->ep0_dir == \
320 - USB_DIR_IN) : ((ep)->desc->bEndpointAddress \
321 - & USB_DIR_IN) == USB_DIR_IN)
322 +#define DIR_STRING(ep) (is_in(ep) ? "in" : "out")
326 -static char *type_string(u8 bmAttributes)
327 +static char *type_string(const struct usb_endpoint_descriptor *desc)
329 - switch ((bmAttributes) & USB_ENDPOINT_XFERTYPE_MASK) {
330 + switch (usb_endpoint_type(desc)) {
331 case USB_ENDPOINT_XFER_BULK:
333 case USB_ENDPOINT_XFER_ISOC:
334 @@ -274,11 +245,13 @@ static void ep0_reset(struct langwell_udc *dev)
335 ep->dqh->dqh_ios = 1;
336 ep->dqh->dqh_mpl = EP0_MAX_PKT_SIZE;
338 - /* FIXME: enable ep0-in HW zero length termination select */
339 + /* enable ep0-in HW zero length termination select */
341 ep->dqh->dqh_zlt = 0;
342 ep->dqh->dqh_mult = 0;
344 + ep->dqh->dtd_next = DTD_TERM;
346 /* configure ep0 control registers */
347 ep_reset(&dev->ep[0], 0, i, USB_ENDPOINT_XFER_CONTROL);
349 @@ -300,7 +273,7 @@ static int langwell_ep_enable(struct usb_ep *_ep,
350 struct langwell_ep *ep;
355 unsigned char zlt, ios = 0, mult = 0;
357 ep = container_of(_ep, struct langwell_ep, ep);
358 @@ -326,7 +299,7 @@ static int langwell_ep_enable(struct usb_ep *_ep,
359 * sanity check type, direction, address, and then
360 * initialize the endpoint capabilities fields in dQH
362 - switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
363 + switch (usb_endpoint_type(desc)) {
364 case USB_ENDPOINT_XFER_CONTROL:
367 @@ -386,28 +359,31 @@ static int langwell_ep_enable(struct usb_ep *_ep,
369 spin_lock_irqsave(&dev->lock, flags);
371 - /* configure endpoint capabilities in dQH */
372 - ep->dqh->dqh_ios = ios;
373 - ep->dqh->dqh_mpl = cpu_to_le16(max);
374 - ep->dqh->dqh_zlt = zlt;
375 - ep->dqh->dqh_mult = mult;
377 ep->ep.maxpacket = max;
380 - ep->ep_num = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
381 + ep->ep_num = usb_endpoint_num(desc);
384 - ep->ep_type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
385 + ep->ep_type = usb_endpoint_type(desc);
387 /* configure endpoint control registers */
388 ep_reset(ep, ep->ep_num, is_in(ep), ep->ep_type);
390 + /* configure endpoint capabilities in dQH */
391 + i = ep->ep_num * 2 + is_in(ep);
392 + ep->dqh = &dev->ep_dqh[i];
393 + ep->dqh->dqh_ios = ios;
394 + ep->dqh->dqh_mpl = cpu_to_le16(max);
395 + ep->dqh->dqh_zlt = zlt;
396 + ep->dqh->dqh_mult = mult;
397 + ep->dqh->dtd_next = DTD_TERM;
399 DBG(dev, "enabled %s (ep%d%s-%s), max %04x\n",
402 - DIR_STRING(desc->bEndpointAddress),
403 - type_string(desc->bmAttributes),
408 spin_unlock_irqrestore(&dev->lock, flags);
409 @@ -617,7 +593,7 @@ static int queue_dtd(struct langwell_ep *ep, struct langwell_request *req)
410 VDBG(dev, "%s\n", ep->name);
413 - VDBG(dev, "%s-%s\n", ep->name, is_in(ep) ? "in" : "out");
414 + VDBG(dev, "%s-%s\n", ep->name, DIR_STRING(ep));
416 VDBG(dev, "ep_dqh[%d] addr: 0x%08x\n", i, (u32)&(dev->ep_dqh[i]));
418 @@ -667,6 +643,9 @@ static int queue_dtd(struct langwell_ep *ep, struct langwell_request *req)
419 dqh->dtd_status &= dtd_status;
420 VDBG(dev, "dqh->dtd_status = 0x%x\n", dqh->dtd_status);
422 + /* ensure that updates to the dQH will occure before priming */
425 /* write 1 to endptprime register to PRIME endpoint */
426 bit_mask = is_in(ep) ? (1 << (ep->ep_num + 16)) : (1 << ep->ep_num);
427 VDBG(dev, "endprime bit_mask = 0x%08x\n", bit_mask);
428 @@ -805,7 +784,7 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
430 VDBG(dev, "---> %s()\n", __func__);
432 - if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
433 + if (usb_endpoint_xfer_isoc(ep->desc)) {
434 if (req->req.length > ep->ep.maxpacket)
437 @@ -844,7 +823,7 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
439 DBG(dev, "%s queue req %p, len %u, buf %p, dma 0x%08x\n",
441 - _req, _req->length, _req->buf, _req->dma);
442 + _req, _req->length, _req->buf, (int)_req->dma);
444 _req->status = -EINPROGRESS;
446 @@ -1024,8 +1003,7 @@ static int langwell_ep_set_halt(struct usb_ep *_ep, int value)
447 if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
450 - if (ep->desc && (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
451 - == USB_ENDPOINT_XFER_ISOC)
452 + if (usb_endpoint_xfer_isoc(ep->desc))
455 spin_lock_irqsave(&dev->lock, flags);
456 @@ -1094,7 +1072,7 @@ static void langwell_ep_fifo_flush(struct usb_ep *_ep)
460 - VDBG(dev, "%s-%s fifo flush\n", _ep->name, is_in(ep) ? "in" : "out");
461 + VDBG(dev, "%s-%s fifo flush\n", _ep->name, DIR_STRING(ep));
463 /* flush endpoint buffer */
465 @@ -1181,6 +1159,7 @@ static int langwell_wakeup(struct usb_gadget *_gadget)
467 struct langwell_udc *dev;
473 @@ -1189,9 +1168,11 @@ static int langwell_wakeup(struct usb_gadget *_gadget)
474 dev = container_of(_gadget, struct langwell_udc, gadget);
475 VDBG(dev, "---> %s()\n", __func__);
477 - /* Remote Wakeup feature not enabled by host */
478 - if (!dev->remote_wakeup)
479 + /* remote wakeup feature not enabled by host */
480 + if (!dev->remote_wakeup) {
481 + INFO(dev, "remote wakeup is disabled\n");
485 spin_lock_irqsave(&dev->lock, flags);
487 @@ -1201,23 +1182,25 @@ static int langwell_wakeup(struct usb_gadget *_gadget)
491 - /* LPM L1 to L0, remote wakeup */
492 - if (dev->lpm && dev->lpm_state == LPM_L1) {
493 - portsc1 |= PORTS_SLP;
494 - writel(portsc1, &dev->op_regs->portsc1);
497 - /* force port resume */
498 - if (dev->usb_state == USB_STATE_SUSPENDED) {
499 - portsc1 |= PORTS_FPR;
500 - writel(portsc1, &dev->op_regs->portsc1);
502 + /* LPM L1 to L0 or legacy remote wakeup */
503 + if (dev->lpm && dev->lpm_state == LPM_L1)
504 + INFO(dev, "LPM L1 to L0 remote wakeup\n");
506 + INFO(dev, "device remote wakeup\n");
508 /* exit PHY low power suspend */
509 devlc = readl(&dev->op_regs->devlc);
510 VDBG(dev, "devlc = 0x%08x\n", devlc);
512 - writel(devlc, &dev->op_regs->devlc);
513 + /* FIXME: workaround for Langwell A1/A2/A3 sighting */
514 + devlc_byte2 = (devlc >> 16) & 0xff;
515 + writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
516 + devlc = readl(&dev->op_regs->devlc);
517 + VDBG(dev, "exit PHY low power suspend, devlc = 0x%08x\n", devlc);
519 + /* force port resume */
520 + portsc1 |= PORTS_FPR;
521 + writel(portsc1, &dev->op_regs->portsc1);
523 spin_unlock_irqrestore(&dev->lock, flags);
525 @@ -1346,6 +1329,7 @@ static const struct usb_gadget_ops langwell_ops = {
526 static int langwell_udc_reset(struct langwell_udc *dev)
528 u32 usbcmd, usbmode, devlc, endpointlistaddr;
529 + u8 devlc_byte0, devlc_byte2;
530 unsigned long timeout;
533 @@ -1390,9 +1374,16 @@ static int langwell_udc_reset(struct langwell_udc *dev)
534 /* if support USB LPM, ACK all LPM token */
536 devlc = readl(&dev->op_regs->devlc);
537 + VDBG(dev, "devlc = 0x%08x\n", devlc);
538 + /* FIXME: workaround for Langwell A1/A2/A3 sighting */
539 devlc &= ~LPM_STL; /* don't STALL LPM token */
540 devlc &= ~LPM_NYT_ACK; /* ACK LPM token */
541 - writel(devlc, &dev->op_regs->devlc);
542 + devlc_byte0 = devlc & 0xff;
543 + devlc_byte2 = (devlc >> 16) & 0xff;
544 + writeb(devlc_byte0, (u8 *)&dev->op_regs->devlc);
545 + writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
546 + devlc = readl(&dev->op_regs->devlc);
547 + VDBG(dev, "ACK LPM token, devlc = 0x%08x\n", devlc);
550 /* fill endpointlistaddr register */
551 @@ -1449,8 +1440,6 @@ static int eps_reinit(struct langwell_udc *dev)
553 INIT_LIST_HEAD(&ep->queue);
554 list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list);
556 - ep->dqh = &dev->ep_dqh[i];
559 VDBG(dev, "<--- %s()\n", __func__);
560 @@ -1539,21 +1528,6 @@ static void stop_activity(struct langwell_udc *dev,
562 /*-------------------------------------------------------------------------*/
564 -/* device "function" sysfs attribute file */
565 -static ssize_t show_function(struct device *_dev,
566 - struct device_attribute *attr, char *buf)
568 - struct langwell_udc *dev = the_controller;
570 - if (!dev->driver || !dev->driver->function
571 - || strlen(dev->driver->function) > PAGE_SIZE)
574 - return scnprintf(buf, PAGE_SIZE, "%s\n", dev->driver->function);
576 -static DEVICE_ATTR(function, S_IRUGO, show_function, NULL);
579 /* device "langwell_udc" sysfs attribute file */
580 static ssize_t show_langwell_udc(struct device *_dev,
581 struct device_attribute *attr, char *buf)
582 @@ -1659,13 +1633,15 @@ static ssize_t show_langwell_udc(struct device *_dev,
583 "Over-current Change: %s\n"
584 "Port Enable/Disable Change: %s\n"
585 "Port Enabled/Disabled: %s\n"
586 - "Current Connect Status: %s\n\n",
587 + "Current Connect Status: %s\n"
588 + "LPM Suspend Status: %s\n\n",
589 (tmp_reg & PORTS_PR) ? "Reset" : "Not Reset",
590 (tmp_reg & PORTS_SUSP) ? "Suspend " : "Not Suspend",
591 (tmp_reg & PORTS_OCC) ? "Detected" : "No",
592 (tmp_reg & PORTS_PEC) ? "Changed" : "Not Changed",
593 (tmp_reg & PORTS_PE) ? "Enable" : "Not Correct",
594 - (tmp_reg & PORTS_CCS) ? "Attached" : "Not Attached");
595 + (tmp_reg & PORTS_CCS) ? "Attached" : "Not Attached",
596 + (tmp_reg & PORTS_SLP) ? "LPM L1" : "LPM L0");
600 @@ -1676,7 +1652,7 @@ static ssize_t show_langwell_udc(struct device *_dev,
601 "Serial Transceiver : %d\n"
603 "Port Force Full Speed Connenct: %s\n"
604 - "PHY Low Power Suspend Clock Disable: %s\n"
605 + "PHY Low Power Suspend Clock: %s\n"
606 "BmAttributes: %d\n\n",
608 (tmp_reg & LPM_STS) ? 1 : 0,
609 @@ -1797,6 +1773,40 @@ static ssize_t show_langwell_udc(struct device *_dev,
610 static DEVICE_ATTR(langwell_udc, S_IRUGO, show_langwell_udc, NULL);
613 +/* device "remote_wakeup" sysfs attribute file */
614 +static ssize_t store_remote_wakeup(struct device *_dev,
615 + struct device_attribute *attr, const char *buf, size_t count)
617 + struct langwell_udc *dev = the_controller;
618 +#if defined(CONFIG_USB_DEBUG)
619 + unsigned long flags;
621 + ssize_t rc = count;
626 + if (count > 0 && buf[count-1] == '\n')
627 + ((char *) buf)[count-1] = 0;
632 +#if defined(CONFIG_USB_DEBUG)
633 + /* force remote wakeup enabled in case gadget driver doesn't support */
634 + spin_lock_irqsave(&dev->lock, flags);
635 + dev->remote_wakeup = 1;
636 + dev->dev_status |= (1 << USB_DEVICE_REMOTE_WAKEUP);
637 + spin_unlock_irqrestore(&dev->lock, flags);
640 + langwell_wakeup(&dev->gadget);
644 +static DEVICE_ATTR(remote_wakeup, S_IWUSR, NULL, store_remote_wakeup);
647 /*-------------------------------------------------------------------------*/
650 @@ -1818,6 +1828,9 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
652 DBG(dev, "---> %s()\n", __func__);
654 + if (unlikely(!driver || !driver->bind))
660 @@ -1839,34 +1852,24 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
664 - retval = device_create_file(&dev->pdev->dev, &dev_attr_function);
668 dev->usb_state = USB_STATE_ATTACHED;
669 dev->ep0_state = WAIT_FOR_SETUP;
670 dev->ep0_dir = USB_DIR_OUT;
672 + /* bind OTG transceiver */
673 + if (dev->transceiver)
674 + (void)otg_set_peripheral(dev->transceiver, &dev->gadget);
676 /* enable interrupt and set controller to run state */
678 langwell_udc_start(dev);
680 VDBG(dev, "After langwell_udc_start(), print all registers:\n");
682 print_all_registers(dev);
685 INFO(dev, "register driver: %s\n", driver->driver.name);
686 - VDBG(dev, "<--- %s()\n", __func__);
690 - driver->unbind(&dev->gadget);
691 - dev->gadget.dev.driver = NULL;
692 - dev->driver = NULL;
694 DBG(dev, "<--- %s()\n", __func__);
698 EXPORT_SYMBOL(usb_gadget_register_driver);
700 @@ -1876,15 +1879,27 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
702 struct langwell_udc *dev = the_controller;
710 DBG(dev, "---> %s()\n", __func__);
712 - if (unlikely(!driver || !driver->bind || !driver->unbind))
713 + if (unlikely(!driver || !driver->unbind || !driver->disconnect))
716 + /* exit PHY low power suspend */
717 + devlc = readl(&dev->op_regs->devlc);
718 + VDBG(dev, "devlc = 0x%08x\n", devlc);
719 + devlc &= ~LPM_PHCD;
720 + /* FIXME: workaround for Langwell A1/A2/A3 sighting */
721 + devlc_byte2 = (devlc >> 16) & 0xff;
722 + writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
723 + devlc = readl(&dev->op_regs->devlc);
724 + VDBG(dev, "exit PHY low power suspend, devlc = 0x%08x\n", devlc);
726 /* unbind OTG transceiver */
727 if (dev->transceiver)
728 (void)otg_set_peripheral(dev->transceiver, 0);
729 @@ -1908,8 +1923,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
730 dev->gadget.dev.driver = NULL;
733 - device_remove_file(&dev->pdev->dev, &dev_attr_function);
735 INFO(dev, "unregistered driver '%s'\n", driver->driver.name);
736 DBG(dev, "<--- %s()\n", __func__);
738 @@ -1917,6 +1930,55 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
739 EXPORT_SYMBOL(usb_gadget_unregister_driver);
742 +/* gets the maximum power consumption */
743 +int langwell_udc_maxpower(int *mA)
745 + struct langwell_udc *dev = the_controller;
746 + u32 usbmode, portsc1, usbcmd;
754 + DBG(dev, "---> %s()\n", __func__);
756 + /* contrller is not in device mode */
757 + usbmode = readl(&dev->op_regs->usbmode);
758 + if (MODE_CM(usbmode) != MODE_DEVICE) {
760 + return -EOTGNODEVICE;
763 + /* can't get maximum power */
764 + usbcmd = readl(&dev->op_regs->usbcmd);
765 + if (!(usbcmd & CMD_RUNSTOP)) {
767 + return -EOTGCHARGER;
770 + /* disconnect to USB host */
771 + portsc1 = readl(&dev->op_regs->portsc1);
772 + if (!(portsc1 & PORTS_CCS)) {
774 + return -EOTGDISCONN;
777 + /* set max power capability */
778 + *mA = CONFIG_USB_GADGET_VBUS_DRAW;
780 + if ((*mA < 8) || (*mA > 500)) {
785 + DBG(dev, "<--- %s()\n", __func__);
788 +EXPORT_SYMBOL(langwell_udc_maxpower);
791 /*-------------------------------------------------------------------------*/
794 @@ -2113,8 +2175,7 @@ static void get_status(struct langwell_udc *dev, u8 request_type, u16 value,
796 if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
797 /* get device status */
798 - status_data = 1 << USB_DEVICE_SELF_POWERED;
799 - status_data |= dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP;
800 + status_data = dev->dev_status;
801 } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) {
802 /* get interface status */
804 @@ -2129,6 +2190,8 @@ static void get_status(struct langwell_udc *dev, u8 request_type, u16 value,
805 status_data = ep_is_stall(epn) << USB_ENDPOINT_HALT;
808 + DBG(dev, "get status data: 0x%04x\n", status_data);
810 dev->ep0_dir = USB_DIR_IN;
812 /* borrow the per device status_req */
813 @@ -2247,22 +2310,37 @@ static void handle_setup_packet(struct langwell_udc *dev,
814 } else if ((setup->bRequestType & (USB_RECIP_MASK
815 | USB_TYPE_MASK)) == (USB_RECIP_DEVICE
816 | USB_TYPE_STANDARD)) {
817 - if (!gadget_is_otg(&dev->gadget))
820 + case USB_DEVICE_REMOTE_WAKEUP:
821 + if (setup->bRequest == USB_REQ_SET_FEATURE) {
822 + dev->remote_wakeup = 1;
823 + dev->dev_status |= (1 << wValue);
825 + dev->remote_wakeup = 0;
826 + dev->dev_status &= ~(1 << wValue);
829 - else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) {
830 + case USB_DEVICE_B_HNP_ENABLE:
831 dev->gadget.b_hnp_enable = 1;
832 #ifdef OTG_TRANSCEIVER
833 if (!dev->lotg->otg.default_a)
834 dev->lotg->hsm.b_hnp_enable = 1;
836 - } else if (setup->bRequest == USB_DEVICE_A_HNP_SUPPORT)
837 + dev->dev_status |= (1 << wValue);
839 + case USB_DEVICE_A_HNP_SUPPORT:
840 dev->gadget.a_hnp_support = 1;
841 - else if (setup->bRequest ==
842 - USB_DEVICE_A_ALT_HNP_SUPPORT)
843 + dev->dev_status |= (1 << wValue);
845 + case USB_DEVICE_A_ALT_HNP_SUPPORT:
846 dev->gadget.a_alt_hnp_support = 1;
848 + dev->dev_status |= (1 << wValue);
858 @@ -2387,7 +2465,7 @@ static int process_ep_req(struct langwell_udc *dev, int index,
860 /* transfers completed with errors */
861 if (dtd_status & DTD_STS_ACTIVE) {
862 - DBG(dev, "request not completed\n");
863 + DBG(dev, "dTD status ACTIVE dQH[%d]\n", index);
866 } else if (dtd_status & DTD_STS_HALTED) {
867 @@ -2586,18 +2664,14 @@ static void handle_port_change(struct langwell_udc *dev)
869 if (dev->lpm && dev->lpm_state == LPM_L0)
870 if (portsc1 & PORTS_SUSP && portsc1 & PORTS_SLP) {
871 - INFO(dev, "LPM L0 to L1\n");
872 - dev->lpm_state = LPM_L1;
873 + INFO(dev, "LPM L0 to L1\n");
874 + dev->lpm_state = LPM_L1;
877 /* LPM L1 to L0, force resume or remote wakeup finished */
878 if (dev->lpm && dev->lpm_state == LPM_L1)
879 if (!(portsc1 & PORTS_SUSP)) {
880 - if (portsc1 & PORTS_SLP)
881 - INFO(dev, "LPM L1 to L0, force resume\n");
883 - INFO(dev, "LPM L1 to L0, remote wakeup\n");
885 + INFO(dev, "LPM L1 to L0\n");
886 dev->lpm_state = LPM_L0;
889 @@ -2634,7 +2708,10 @@ static void handle_usb_reset(struct langwell_udc *dev)
891 dev->ep0_dir = USB_DIR_OUT;
892 dev->ep0_state = WAIT_FOR_SETUP;
893 - dev->remote_wakeup = 0; /* default to 0 on reset */
895 + /* remote wakeup reset to 0 when the device is reset */
896 + dev->remote_wakeup = 0;
897 + dev->dev_status = 1 << USB_DEVICE_SELF_POWERED;
898 dev->gadget.b_hnp_enable = 0;
899 dev->gadget.a_hnp_support = 0;
900 dev->gadget.a_alt_hnp_support = 0;
901 @@ -2699,6 +2776,7 @@ static void handle_usb_reset(struct langwell_udc *dev)
902 static void handle_bus_suspend(struct langwell_udc *dev)
906 DBG(dev, "---> %s()\n", __func__);
908 dev->resume_state = dev->usb_state;
909 @@ -2706,7 +2784,8 @@ static void handle_bus_suspend(struct langwell_udc *dev)
911 #ifdef OTG_TRANSCEIVER
912 if (dev->lotg->otg.default_a) {
913 - if (dev->lotg->hsm.b_bus_suspend_vld == 1) {
914 + /* ignore host LPM capability checking during enumeration */
915 + if (dev->lotg->hsm.b_bus_suspend_vld == 2) {
916 dev->lotg->hsm.b_bus_suspend = 1;
917 /* notify transceiver the state changes */
918 if (spin_trylock(&dev->lotg->wq_lock)) {
919 @@ -2741,7 +2820,11 @@ static void handle_bus_suspend(struct langwell_udc *dev)
920 devlc = readl(&dev->op_regs->devlc);
921 VDBG(dev, "devlc = 0x%08x\n", devlc);
923 - writel(devlc, &dev->op_regs->devlc);
924 + /* FIXME: workaround for Langwell A1/A2/A3 sighting */
925 + devlc_byte2 = (devlc >> 16) & 0xff;
926 + writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
927 + devlc = readl(&dev->op_regs->devlc);
928 + VDBG(dev, "enter PHY low power suspend, devlc = 0x%08x\n", devlc);
930 DBG(dev, "<--- %s()\n", __func__);
932 @@ -2750,6 +2833,7 @@ static void handle_bus_suspend(struct langwell_udc *dev)
933 static void handle_bus_resume(struct langwell_udc *dev)
937 DBG(dev, "---> %s()\n", __func__);
939 dev->usb_state = dev->resume_state;
940 @@ -2759,7 +2843,11 @@ static void handle_bus_resume(struct langwell_udc *dev)
941 devlc = readl(&dev->op_regs->devlc);
942 VDBG(dev, "devlc = 0x%08x\n", devlc);
944 - writel(devlc, &dev->op_regs->devlc);
945 + /* FIXME: workaround for Langwell A1/A2/A3 sighting */
946 + devlc_byte2 = (devlc >> 16) & 0xff;
947 + writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
948 + devlc = readl(&dev->op_regs->devlc);
949 + VDBG(dev, "exit PHY low power suspend, devlc = 0x%08x\n", devlc);
951 #ifdef OTG_TRANSCEIVER
952 if (dev->lotg->otg.default_a == 0)
953 @@ -2898,6 +2986,50 @@ static void gadget_release(struct device *_dev)
957 +/* enable SRAM caching if SRAM detected */
958 +static void sram_init(struct langwell_udc *dev)
960 + struct pci_dev *pdev = dev->pdev;
962 + DBG(dev, "---> %s()\n", __func__);
964 + dev->sram_addr = pci_resource_start(pdev, 1);
965 + dev->sram_size = pci_resource_len(pdev, 1);
966 + INFO(dev, "Found private SRAM at %x size:%x\n",
967 + dev->sram_addr, dev->sram_size);
970 + if (pci_request_region(pdev, 1, kobject_name(&pdev->dev.kobj))) {
971 + WARNING(dev, "SRAM request failed\n");
973 + } else if (!dma_declare_coherent_memory(&pdev->dev, dev->sram_addr,
974 + dev->sram_addr, dev->sram_size, DMA_MEMORY_MAP)) {
975 + WARNING(dev, "SRAM DMA declare failed\n");
976 + pci_release_region(pdev, 1);
980 + DBG(dev, "<--- %s()\n", __func__);
984 +/* release SRAM caching */
985 +static void sram_deinit(struct langwell_udc *dev)
987 + struct pci_dev *pdev = dev->pdev;
989 + DBG(dev, "---> %s()\n", __func__);
991 + dma_release_declared_memory(&pdev->dev);
992 + pci_release_region(pdev, 1);
996 + INFO(dev, "release SRAM caching\n");
997 + DBG(dev, "<--- %s()\n", __func__);
1001 /* tear down the binding between this driver and the pci device */
1002 static void langwell_udc_remove(struct pci_dev *pdev)
1004 @@ -2910,19 +3042,25 @@ static void langwell_udc_remove(struct pci_dev *pdev)
1008 - /* free memory allocated in probe */
1009 +#ifndef OTG_TRANSCEIVER
1010 + /* free dTD dma_pool and dQH */
1012 dma_pool_destroy(dev->dtd_pool);
1015 + dma_free_coherent(&pdev->dev, dev->ep_dqh_size,
1016 + dev->ep_dqh, dev->ep_dqh_dma);
1018 + /* release SRAM caching */
1019 + if (dev->has_sram && dev->got_sram)
1023 if (dev->status_req) {
1024 kfree(dev->status_req->req.buf);
1025 kfree(dev->status_req);
1029 - dma_free_coherent(&pdev->dev, dev->ep_dqh_size,
1030 - dev->ep_dqh, dev->ep_dqh_dma);
1034 /* diable IRQ handler */
1035 @@ -2954,6 +3092,7 @@ static void langwell_udc_remove(struct pci_dev *pdev)
1037 device_unregister(&dev->gadget.dev);
1038 device_remove_file(&pdev->dev, &dev_attr_langwell_udc);
1039 + device_remove_file(&pdev->dev, &dev_attr_remote_wakeup);
1041 #ifndef OTG_TRANSCEIVER
1042 pci_set_drvdata(pdev, NULL);
1043 @@ -2976,9 +3115,9 @@ static int langwell_udc_probe(struct pci_dev *pdev,
1044 struct langwell_udc *dev;
1045 #ifndef OTG_TRANSCEIVER
1046 unsigned long resource, len;
1049 void __iomem *base = NULL;
1053 if (the_controller) {
1054 @@ -3049,7 +3188,15 @@ static int langwell_udc_probe(struct pci_dev *pdev,
1058 + dev->has_sram = 1;
1059 + dev->got_sram = 0;
1060 + VDBG(dev, "dev->has_sram: %d\n", dev->has_sram);
1062 #ifndef OTG_TRANSCEIVER
1063 + /* enable SRAM caching if detected */
1064 + if (dev->has_sram && !dev->got_sram)
1067 INFO(dev, "irq %d, io mem: 0x%08lx, len: 0x%08lx, pci mem 0x%p\n",
1068 pdev->irq, resource, len, base);
1069 /* enables bus-mastering for device dev */
1070 @@ -3094,6 +3241,7 @@ static int langwell_udc_probe(struct pci_dev *pdev,
1074 +#ifndef OTG_TRANSCEIVER
1075 /* allocate device dQH memory */
1076 size = dev->ep_max * sizeof(struct langwell_dqh);
1077 VDBG(dev, "orig size = %d\n", size);
1078 @@ -3112,6 +3260,7 @@ static int langwell_udc_probe(struct pci_dev *pdev,
1080 dev->ep_dqh_size = size;
1081 VDBG(dev, "ep_dqh_size = %d\n", dev->ep_dqh_size);
1084 /* initialize ep0 status request structure */
1085 dev->status_req = kzalloc(sizeof(struct langwell_request), GFP_KERNEL);
1086 @@ -3129,7 +3278,10 @@ static int langwell_udc_probe(struct pci_dev *pdev,
1087 dev->resume_state = USB_STATE_NOTATTACHED;
1088 dev->usb_state = USB_STATE_POWERED;
1089 dev->ep0_dir = USB_DIR_OUT;
1090 - dev->remote_wakeup = 0; /* default to 0 on reset */
1092 + /* remote wakeup reset to 0 when the device is reset */
1093 + dev->remote_wakeup = 0;
1094 + dev->dev_status = 1 << USB_DEVICE_SELF_POWERED;
1096 #ifndef OTG_TRANSCEIVER
1097 /* reset device controller */
1098 @@ -3159,7 +3311,6 @@ static int langwell_udc_probe(struct pci_dev *pdev,
1099 #ifndef OTG_TRANSCEIVER
1100 /* reset ep0 dQH and endptctrl */
1104 /* create dTD dma_pool resource */
1105 dev->dtd_pool = dma_pool_create("langwell_dtd",
1106 @@ -3172,6 +3323,7 @@ static int langwell_udc_probe(struct pci_dev *pdev,
1113 INFO(dev, "%s\n", driver_desc);
1114 @@ -3183,9 +3335,7 @@ static int langwell_udc_probe(struct pci_dev *pdev,
1115 INFO(dev, "Support USB LPM: %s\n", dev->lpm ? "Yes" : "No");
1117 VDBG(dev, "After langwell_udc_probe(), print all registers:\n");
1119 print_all_registers(dev);
1122 the_controller = dev;
1124 @@ -3197,9 +3347,15 @@ static int langwell_udc_probe(struct pci_dev *pdev,
1128 + retval = device_create_file(&pdev->dev, &dev_attr_remote_wakeup);
1132 VDBG(dev, "<--- %s()\n", __func__);
1136 + device_remove_file(&pdev->dev, &dev_attr_langwell_udc);
1139 DBG(dev, "<--- %s()\n", __func__);
1140 @@ -3215,6 +3371,7 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
1142 struct langwell_udc *dev = the_controller;
1146 DBG(dev, "---> %s()\n", __func__);
1148 @@ -3226,10 +3383,21 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
1149 free_irq(pdev->irq, dev);
1153 /* save PCI state */
1154 pci_save_state(pdev);
1156 + /* free dTD dma_pool and dQH */
1157 + if (dev->dtd_pool)
1158 + dma_pool_destroy(dev->dtd_pool);
1161 + dma_free_coherent(&pdev->dev, dev->ep_dqh_size,
1162 + dev->ep_dqh, dev->ep_dqh_dma);
1164 + /* release SRAM caching */
1165 + if (dev->has_sram && dev->got_sram)
1168 /* set device power state */
1169 pci_set_power_state(pdev, PCI_D3hot);
1171 @@ -3237,7 +3405,11 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
1172 devlc = readl(&dev->op_regs->devlc);
1173 VDBG(dev, "devlc = 0x%08x\n", devlc);
1175 - writel(devlc, &dev->op_regs->devlc);
1176 + /* FIXME: workaround for Langwell A1/A2/A3 sighting */
1177 + devlc_byte2 = (devlc >> 16) & 0xff;
1178 + writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
1179 + devlc = readl(&dev->op_regs->devlc);
1180 + VDBG(dev, "enter PHY low power suspend, devlc = 0x%08x\n", devlc);
1182 DBG(dev, "<--- %s()\n", __func__);
1184 @@ -3249,6 +3421,8 @@ static int langwell_udc_resume(struct pci_dev *pdev)
1186 struct langwell_udc *dev = the_controller;
1191 DBG(dev, "---> %s()\n", __func__);
1193 @@ -3256,19 +3430,55 @@ static int langwell_udc_resume(struct pci_dev *pdev)
1194 devlc = readl(&dev->op_regs->devlc);
1195 VDBG(dev, "devlc = 0x%08x\n", devlc);
1197 - writel(devlc, &dev->op_regs->devlc);
1198 + /* FIXME: workaround for Langwell A1/A2/A3 sighting */
1199 + devlc_byte2 = (devlc >> 16) & 0xff;
1200 + writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
1201 + devlc = readl(&dev->op_regs->devlc);
1202 + VDBG(dev, "exit PHY low power suspend, devlc = 0x%08x\n", devlc);
1204 /* set device D0 power state */
1205 pci_set_power_state(pdev, PCI_D0);
1207 + /* enable SRAM caching if detected */
1208 + if (dev->has_sram && !dev->got_sram)
1211 + /* allocate device dQH memory */
1212 + size = dev->ep_max * sizeof(struct langwell_dqh);
1213 + VDBG(dev, "orig size = %d\n", size);
1214 + if (size < DQH_ALIGNMENT)
1215 + size = DQH_ALIGNMENT;
1216 + else if ((size % DQH_ALIGNMENT) != 0) {
1217 + size += DQH_ALIGNMENT + 1;
1218 + size &= ~(DQH_ALIGNMENT - 1);
1220 + dev->ep_dqh = dma_alloc_coherent(&pdev->dev, size,
1221 + &dev->ep_dqh_dma, GFP_KERNEL);
1222 + if (!dev->ep_dqh) {
1223 + ERROR(dev, "allocate dQH memory failed\n");
1226 + dev->ep_dqh_size = size;
1227 + VDBG(dev, "ep_dqh_size = %d\n", dev->ep_dqh_size);
1229 + /* create dTD dma_pool resource */
1230 + dev->dtd_pool = dma_pool_create("langwell_dtd",
1232 + sizeof(struct langwell_dtd),
1236 + if (!dev->dtd_pool)
1239 /* restore PCI state */
1240 pci_restore_state(pdev);
1242 /* enable IRQ handler */
1243 - if (request_irq(pdev->irq, langwell_irq, IRQF_SHARED, driver_name, dev)
1245 + if (request_irq(pdev->irq, langwell_irq, IRQF_SHARED,
1246 + driver_name, dev) != 0) {
1247 ERROR(dev, "request interrupt %d failed\n", pdev->irq);
1253 diff --git a/drivers/usb/gadget/langwell_udc.h b/drivers/usb/gadget/langwell_udc.h
1254 index 9719934..323c574 100644
1255 --- a/drivers/usb/gadget/langwell_udc.h
1256 +++ b/drivers/usb/gadget/langwell_udc.h
1257 @@ -174,7 +174,7 @@ enum lpm_state {
1258 struct langwell_udc {
1259 /* each pci device provides one gadget, several endpoints */
1260 struct usb_gadget gadget;
1261 - spinlock_t lock; /* device lock */
1262 + spinlock_t lock; /* device lock */
1263 struct langwell_ep *ep;
1264 struct usb_gadget_driver *driver;
1265 struct otg_transceiver *transceiver;
1266 @@ -199,7 +199,9 @@ struct langwell_udc {
1270 - lpm:1; /* LPM capability */
1271 + lpm:1, /* LPM capability */
1272 + has_sram:1, /* SRAM caching */
1275 /* pci state used to access those endpoints */
1276 struct pci_dev *pdev;
1277 @@ -224,5 +226,12 @@ struct langwell_udc {
1279 /* make sure release() is done */
1280 struct completion *done;
1282 + /* for private SRAM caching */
1283 + unsigned int sram_addr;
1284 + unsigned int sram_size;
1286 + /* device status data for get_status request */
1290 diff --git a/drivers/usb/gadget/still_image.c b/drivers/usb/gadget/still_image.c
1291 new file mode 100644
1292 index 0000000..94c17ce
1294 +++ b/drivers/usb/gadget/still_image.c
1297 + * still_image.c -- Lite USB Still Image Capture Gadget, for USB development
1298 + * Copyright (C) 2009, Intel Corporation.
1300 + * This program is free software; you can redistribute it and/or modify it
1301 + * under the terms and conditions of the GNU General Public License,
1302 + * version 2, as published by the Free Software Foundation.
1304 + * This program is distributed in the hope it will be useful, but WITHOUT
1305 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1306 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
1309 + * You should have received a copy of the GNU General Public License along with
1310 + * this program; if not, write to the Free Software Foundation, Inc.,
1311 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
1317 + * This code is partly based on:
1318 + * File-backed USB Storage Gadget driver, Copyright (C) 2003-2008 Alan Stern
1321 + * Refer to the USB Device Class Definition for Still Image Capture Device:
1322 + * http://www.usb.org/developers/devclass_docs/usb_still_img10.zip
1325 + * Supported PIMA 15740/PTP operations:
1330 + * - GetStorageInfo
1332 + * - GetObjectHandles
1336 + * - SendObjectInfo
1341 + * Supported object formats:
1342 + * - EXIF/JPEG, JFIF
1344 + * - TIFF, TIFF/IT, TIFF/EP
1347 + * - Unknown image object
1348 + * - Undefined non-image object
1350 + * Supported PIMA 15740/PTP events:
1353 + * Storage filesystem type:
1354 + * - Generic hierarchical
1358 + * folder=foldername Default NULL, name of the backing folder
1359 + * vendor=0xVVVV Default 0x8087 (Intel), USB Vendor ID
1360 + * product=0xPPPP Default 0x811e, USB Product ID
1361 + * release=0xRRRR Override the USB release number (bcdDevice)
1362 + * buflen=N Default N=16384, buffer size used (will be
1363 + * rounded down to a multiple of
1364 + * PAGE_CACHE_SIZE)
1366 + * Sysfs attribute file:
1367 + * folder read/write the name of the backing folder
1372 +#define VERBOSE_DEBUG
1374 +#include <linux/blkdev.h>
1375 +#include <linux/completion.h>
1376 +#include <linux/dcache.h>
1377 +#include <linux/delay.h>
1378 +#include <linux/device.h>
1379 +#include <linux/fcntl.h>
1380 +#include <linux/file.h>
1381 +#include <linux/fs.h>
1382 +#include <linux/vfs.h>
1383 +#include <linux/namei.h>
1384 +#include <linux/kref.h>
1385 +#include <linux/kthread.h>
1386 +#include <linux/limits.h>
1387 +#include <linux/rwsem.h>
1388 +#include <linux/slab.h>
1389 +#include <linux/spinlock.h>
1390 +#include <linux/string.h>
1391 +#include <linux/freezer.h>
1392 +#include <linux/utsname.h>
1393 +#include <linux/sort.h>
1395 +#include <linux/usb/ch9.h>
1396 +#include <linux/usb/gadget.h>
1398 +#include "gadget_chips.h"
1400 +#include "usbstring.c"
1401 +#include "config.c"
1402 +#include "epautoconf.c"
1405 +/*-------------------------------------------------------------------------*/
1407 +#define DRIVER_DESC "Still Image Gadget"
1408 +#define DRIVER_NAME "g_still_image"
1409 +#define DRIVER_VERSION "Apr 30, 2010"
1412 +static const char longname[] = DRIVER_DESC;
1413 +static const char shortname[] = DRIVER_NAME;
1416 +MODULE_DESCRIPTION(DRIVER_DESC);
1417 +MODULE_AUTHOR("Xiaochen Shen <xiaochen.shen@intel.com>; "
1418 + "Hang Yuan <hang.yuan@intel.com>");
1419 +MODULE_VERSION(DRIVER_VERSION);
1420 +MODULE_LICENSE("GPL");
1424 + * Intel Corporation donates this product ID.
1426 + * DO NOT REUSE THESE IDs with any other driver
1427 + * instead: allocate your own, using normal USB-IF procedures.
1429 +#define DRIVER_VENDOR_ID 0x8087
1430 +#define DRIVER_PRODUCT_ID 0x811e
1433 +/*-------------------------------------------------------------------------*/
1435 +#define MDBG(fmt, args...) \
1436 + pr_debug(DRIVER_NAME ": " fmt, ## args)
1437 +#define MINFO(fmt, args...) \
1438 + pr_info(DRIVER_NAME ": " fmt, ## args)
1441 +#define DBG(d, fmt, args...) \
1442 + dev_dbg(&(d)->gadget->dev, fmt, ## args)
1444 +#define DBG(dev, fmt, args...) \
1450 +#undef VERBOSE_DEBUG
1451 +#endif /* !DEBUG */
1453 +#ifdef VERBOSE_DEBUG
1456 +#define VDBG(sti, fmt, args...) \
1458 +#endif /* VERBOSE_DEBUG */
1460 +#define ERROR(d, fmt, args...) \
1461 + dev_err(&(d)->gadget->dev, fmt, ## args)
1462 +#define WARNING(d, fmt, args...) \
1463 + dev_warn(&(d)->gadget->dev, fmt, ## args)
1464 +#define INFO(d, fmt, args...) \
1465 + dev_info(&(d)->gadget->dev, fmt, ## args)
1468 +/*-------------------------------------------------------------------------*/
1470 +/* encapsulate the module parameter settings */
1474 + unsigned short vendor;
1475 + unsigned short product;
1476 + unsigned short release;
1477 + unsigned int buflen;
1478 +} mod_data = { /* default values */
1479 + .vendor = DRIVER_VENDOR_ID,
1480 + .product = DRIVER_PRODUCT_ID,
1481 + .release = 0xffff, /* use controller chip type */
1486 +module_param_named(folder, mod_data.folder, charp, S_IRUGO);
1487 +MODULE_PARM_DESC(folder, "name of the backing folder");
1489 +module_param_named(vendor, mod_data.vendor, ushort, S_IRUGO);
1490 +MODULE_PARM_DESC(vendor, "USB Vendor ID");
1492 +module_param_named(product, mod_data.product, ushort, S_IRUGO);
1493 +MODULE_PARM_DESC(product, "USB Product ID");
1495 +module_param_named(release, mod_data.release, ushort, S_IRUGO);
1496 +MODULE_PARM_DESC(release, "USB release number");
1498 +module_param_named(buflen, mod_data.buflen, uint, S_IRUGO);
1499 +MODULE_PARM_DESC(buflen, "I/O buffer size");
1502 +/*-------------------------------------------------------------------------*/
1505 + * DESCRIPTORS ... most are static, but strings and (full) configuration
1506 + * descriptors are built on demand. Also the (static) config and interface
1507 + * descriptors are adjusted during sti_bind().
1509 +#define STRING_MANUFACTURER 1
1510 +#define STRING_PRODUCT 2
1511 +#define STRING_SERIAL 3
1512 +#define STRING_CONFIG 4
1513 +#define STRING_INTERFACE 5
1516 +/* only one configuration */
1517 +#define CONFIG_VALUE 1
1519 +static struct usb_device_descriptor
1521 + .bLength = sizeof device_desc,
1522 + .bDescriptorType = USB_DT_DEVICE,
1524 + .bcdUSB = cpu_to_le16(0x0200),
1525 + .bDeviceClass = USB_CLASS_PER_INTERFACE,
1527 + /* the next three values can be overridden by module parameters */
1528 + .idVendor = cpu_to_le16(DRIVER_VENDOR_ID),
1529 + .idProduct = cpu_to_le16(DRIVER_PRODUCT_ID),
1530 + .bcdDevice = cpu_to_le16(0xffff),
1532 + .iManufacturer = STRING_MANUFACTURER,
1533 + .iProduct = STRING_PRODUCT,
1534 + .iSerialNumber = STRING_SERIAL,
1535 + .bNumConfigurations = 1,
1538 +static struct usb_config_descriptor
1540 + .bLength = sizeof config_desc,
1541 + .bDescriptorType = USB_DT_CONFIG,
1543 + /* wTotalLength computed by usb_gadget_config_buf() */
1544 + .bNumInterfaces = 1,
1545 + .bConfigurationValue = CONFIG_VALUE,
1546 + .iConfiguration = STRING_CONFIG,
1547 + .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
1548 + .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2,
1551 +static struct usb_otg_descriptor
1553 + .bLength = sizeof(otg_desc),
1554 + .bDescriptorType = USB_DT_OTG,
1556 + .bmAttributes = USB_OTG_SRP,
1560 +/* one interface */
1561 +static struct usb_interface_descriptor
1563 + .bLength = sizeof intf_desc,
1564 + .bDescriptorType = USB_DT_INTERFACE,
1566 + .bNumEndpoints = 3, /* adjusted during sti_bind() */
1567 + .bInterfaceClass = USB_CLASS_STILL_IMAGE,
1568 + .bInterfaceSubClass = 0x01, /* Still Image Capture device */
1569 + .bInterfaceProtocol = 0x01, /* Bulk-only protocol */
1570 + .iInterface = STRING_INTERFACE,
1574 +/* two full-speed endpoint descriptors: bulk-in, bulk-out */
1576 +static struct usb_endpoint_descriptor
1577 +fs_bulk_in_desc = {
1578 + .bLength = USB_DT_ENDPOINT_SIZE,
1579 + .bDescriptorType = USB_DT_ENDPOINT,
1581 + .bEndpointAddress = USB_DIR_IN,
1582 + .bmAttributes = USB_ENDPOINT_XFER_BULK,
1583 + /* wMaxPacketSize set by autoconfiguration */
1586 +static struct usb_endpoint_descriptor
1587 +fs_bulk_out_desc = {
1588 + .bLength = USB_DT_ENDPOINT_SIZE,
1589 + .bDescriptorType = USB_DT_ENDPOINT,
1591 + .bEndpointAddress = USB_DIR_OUT,
1592 + .bmAttributes = USB_ENDPOINT_XFER_BULK,
1593 + /* wMaxPacketSize set by autoconfiguration */
1596 +static struct usb_endpoint_descriptor
1597 +fs_intr_in_desc = {
1598 + .bLength = USB_DT_ENDPOINT_SIZE,
1599 + .bDescriptorType = USB_DT_ENDPOINT,
1601 + .bEndpointAddress = USB_DIR_IN,
1602 + .bmAttributes = USB_ENDPOINT_XFER_INT,
1603 + .wMaxPacketSize = cpu_to_le16(2),
1604 + .bInterval = 32, /* frames -> 32 ms */
1607 +static const struct usb_descriptor_header *fs_function[] = {
1608 + (struct usb_descriptor_header *) &otg_desc,
1609 + (struct usb_descriptor_header *) &intf_desc,
1610 + (struct usb_descriptor_header *) &fs_bulk_in_desc,
1611 + (struct usb_descriptor_header *) &fs_bulk_out_desc,
1612 + (struct usb_descriptor_header *) &fs_intr_in_desc,
1616 +#define FS_FUNCTION_PRE_EP_ENTRIES 2
1620 + * USB 2.0 devices need to expose both high speed and full speed
1621 + * descriptors, unless they only run at full speed.
1623 + * That means alternate endpoint descriptors (bigger packets)
1624 + * and a "device qualifier" ... plus more construction options
1625 + * for the config descriptor.
1627 +static struct usb_qualifier_descriptor
1629 + .bLength = sizeof dev_qualifier,
1630 + .bDescriptorType = USB_DT_DEVICE_QUALIFIER,
1632 + .bcdUSB = cpu_to_le16(0x0200),
1633 + .bDeviceClass = USB_CLASS_PER_INTERFACE,
1635 + .bNumConfigurations = 1,
1638 +static struct usb_endpoint_descriptor
1639 +hs_bulk_in_desc = {
1640 + .bLength = USB_DT_ENDPOINT_SIZE,
1641 + .bDescriptorType = USB_DT_ENDPOINT,
1643 + /* bEndpointAddress copied from fs_bulk_in_desc during sti_bind() */
1644 + .bmAttributes = USB_ENDPOINT_XFER_BULK,
1645 + .wMaxPacketSize = cpu_to_le16(512),
1648 +static struct usb_endpoint_descriptor
1649 +hs_bulk_out_desc = {
1650 + .bLength = USB_DT_ENDPOINT_SIZE,
1651 + .bDescriptorType = USB_DT_ENDPOINT,
1653 + /* bEndpointAddress copied from fs_bulk_out_desc during sti_bind() */
1654 + .bmAttributes = USB_ENDPOINT_XFER_BULK,
1655 + .wMaxPacketSize = cpu_to_le16(512),
1656 + .bInterval = 1, /* NAK every 1 uframe */
1659 +static struct usb_endpoint_descriptor
1660 +hs_intr_in_desc = {
1661 + .bLength = USB_DT_ENDPOINT_SIZE,
1662 + .bDescriptorType = USB_DT_ENDPOINT,
1664 + /* bEndpointAddress copied from fs_intr_in_desc during sti_bind() */
1665 + .bmAttributes = USB_ENDPOINT_XFER_INT,
1666 + .wMaxPacketSize = cpu_to_le16(2),
1667 + .bInterval = 9, /* 2**(9-1) = 256 uframes -> 32 ms */
1670 +static const struct usb_descriptor_header *hs_function[] = {
1671 + (struct usb_descriptor_header *) &otg_desc,
1672 + (struct usb_descriptor_header *) &intf_desc,
1673 + (struct usb_descriptor_header *) &hs_bulk_in_desc,
1674 + (struct usb_descriptor_header *) &hs_bulk_out_desc,
1675 + (struct usb_descriptor_header *) &hs_intr_in_desc,
1679 +#define HS_FUNCTION_PRE_EP_ENTRIES 2
1682 +/* maxpacket and other transfer characteristics vary by speed. */
1683 +static struct usb_endpoint_descriptor *
1684 +ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
1685 + struct usb_endpoint_descriptor *hs)
1687 + if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
1693 +static char manufacturer[64];
1694 +static char serial[13];
1696 +/* static strings, in UTF-8 (for simplicity we use only ASCII characters) */
1697 +static struct usb_string strings[] = {
1698 + {STRING_MANUFACTURER, manufacturer},
1699 + {STRING_PRODUCT, longname},
1700 + {STRING_SERIAL, serial},
1701 + {STRING_CONFIG, "Self-powered"},
1702 + {STRING_INTERFACE, "Still Image"},
1706 +static struct usb_gadget_strings stringtab = {
1707 + .language = 0x0409, /* en-us */
1708 + .strings = strings,
1712 +/*-------------------------------------------------------------------------*/
1714 +/* protocol, driver and device data structures */
1716 +/* big enough to hold the biggest descriptor */
1717 +#define EP0_BUFSIZE 256
1719 +#define DELAYED_STATUS (EP0_BUFSIZE + 999)
1721 +/* number of buffers we will use. 2 is enough for double-buffering */
1722 +#define NUM_BUFFERS 2
1724 +/* PIMA 15740, operation and response datasets have at most 5 parameters */
1725 +#define PARAM_NUM_MAX 5
1727 +/* PIMA 15740 generic container head length */
1728 +#define PIMA15740_CONTAINER_LEN 12
1730 +/* storage id, description */
1731 +#define STORAGE_ID 0x00010001
1732 +#define STORAGE_DESCRIPTION "Built-in Storage"
1734 +/* Still Image class-specific requests */
1735 +#define STI_CANCEL_REQUEST 0x64
1736 +#define STI_GET_EXTENDED_EVENT_DATA 0x65
1737 +#define STI_DEVICE_RESET_REQUEST 0x66
1738 +#define STI_GET_DEVICE_STATUS 0x67
1740 +#define STI_CANCEL_REQUEST_LENGTH 0x0006
1741 +#define STI_CANCEL_REQUEST_CODE 0x4001
1743 +/* supported PIMA 15740 operations */
1744 +#define PIMA15740_OP_GET_DEVICE_INFO 0x1001
1745 +#define PIMA15740_OP_OPEN_SESSION 0x1002
1746 +#define PIMA15740_OP_CLOSE_SESSION 0x1003
1747 +#define PIMA15740_OP_GET_STORAGE_IDS 0x1004
1748 +#define PIMA15740_OP_GET_STORAGE_INFO 0x1005
1749 +#define PIMA15740_OP_GET_NUM_OBJECTS 0x1006
1750 +#define PIMA15740_OP_GET_OBJECT_HANDLES 0x1007
1751 +#define PIMA15740_OP_GET_OBJECT_INFO 0x1008
1752 +#define PIMA15740_OP_GET_OBJECT 0x1009
1753 +#define PIMA15740_OP_DELETE_OBJECT 0x100b
1754 +#define PIMA15740_OP_SEND_OBJECT_INFO 0x100c
1755 +#define PIMA15740_OP_SEND_OBJECT 0x100d
1756 +#define PIMA15740_OP_MOVE_OBJECT 0x1019
1757 +#define PIMA15740_OP_COPY_OBJECT 0x101a
1759 +/* PIMA 15740 responses definition */
1760 +#define PIMA15740_RES_UNDEFINED 0x2000
1761 +#define PIMA15740_RES_OK 0x2001
1762 +#define PIMA15740_RES_GENERAL_ERROR 0x2002
1763 +#define PIMA15740_RES_SESSION_NOT_OPEN 0x2003
1764 +#define PIMA15740_RES_INVALID_TRANS_ID 0x2004
1765 +#define PIMA15740_RES_OPERATION_NOT_SUPPORTED 0x2005
1766 +#define PIMA15740_RES_PARAMETER_NOT_SUPPORTED 0x2006
1767 +#define PIMA15740_RES_INCOMPLETE_TRANSFER 0x2007
1768 +#define PIMA15740_RES_INVALID_STORAGE_ID 0x2008
1769 +#define PIMA15740_RES_INVALID_OBJECT_HANDLE 0x2009
1770 +#define PIMA15740_RES_DEVICE_PROP_NOT_SUPPORTED 0x200a
1771 +#define PIMA15740_RES_INVALID_OBJECT_FORMAT 0x200b
1772 +#define PIMA15740_RES_STORE_FULL 0x200c
1773 +#define PIMA15740_RES_OBJECT_WRITE_PROTECTED 0x200d
1774 +#define PIMA15740_RES_STORE_READ_ONLY 0x200e
1775 +#define PIMA15740_RES_ACCESS_DENIED 0x200f
1776 +#define PIMA15740_RES_NO_THUMBNAIL_PRESENT 0x2010
1777 +#define PIMA15740_RES_SELF_TEST_FAILED 0x2011
1778 +#define PIMA15740_RES_PARTIAL_DELETION 0x2012
1779 +#define PIMA15740_RES_STORE_NOT_AVAILABLE 0x2013
1780 +#define PIMA15740_RES_SPEC_BY_FORMAT_UNSUP 0x2014
1781 +#define PIMA15740_RES_NO_VALID_OBJECT_INFO 0x2015
1782 +#define PIMA15740_RES_INVALID_CODE_FORMAT 0x2016
1783 +#define PIMA15740_RES_UNKNOWN_VENDOR_CODE 0x2017
1784 +#define PIMA15740_RES_CAPTURE_ALREADY_TERM 0x2018
1785 +#define PIMA15740_RES_DEVICE_BUSY 0x2019
1786 +#define PIMA15740_RES_INVALID_PARENT_OBJECT 0x201a
1787 +#define PIMA15740_RES_INVALID_DEV_PROP_FORMAT 0x201b
1788 +#define PIMA15740_RES_INVALID_DEV_PROP_VALUE 0x201c
1789 +#define PIMA15740_RES_INVALID_PARAMETER 0x201d
1790 +#define PIMA15740_RES_SESSION_ALREADY_OPEN 0x201e
1791 +#define PIMA15740_RES_TRANSACTION_CANCELLED 0x201f
1792 +#define PIMA15740_RES_SPEC_OF_DESTINATION_UNSUP 0x2020
1794 +/* PIMA 15740 functional mode */
1795 +#define PIMA15740_STANDARD_MODE 0x0000
1796 +#define PIMA15740_SLEEP_STATE_MODE 0x0001
1798 +/* PIMA 15740 storage type */
1799 +#define PIMA15740_STOR_UNDEFINED 0x0000
1800 +#define PIMA15740_STOR_FIXED_ROM 0x0001
1801 +#define PIMA15740_STOR_REMOVABLE_ROM 0x0002
1802 +#define PIMA15740_STOR_FIXED_RAM 0x0003
1803 +#define PIMA15740_STOR_REMOVABLE_RAM 0x0004
1805 +/* PIMA 15740 filesystem type */
1806 +#define PIMA15740_FS_UNDEFINED 0x0000
1807 +#define PIMA15740_FS_GENERIC_FLAT 0x0001
1808 +#define PIMA15740_FS_HIERARCHICAL 0x0002
1809 +#define PIMA15740_FS_DCF 0x0003
1811 +/* PIMA 15740 access capability */
1812 +#define PIMA15740_ACCESS_CAP_RW 0x0000
1813 +#define PIMA15740_ACCESS_CAP_RO_WO_DELITION 0x0001
1814 +#define PIMA15740_ACCESS_CAP_RO_W_DELITION 0x0002
1816 +/* PIMA 15740 object format codes */
1817 +#define PIMA15740_FMT_A_UNDEFINED 0x3000
1818 +#define PIMA15740_FMT_A_ASSOCIATION 0x3001
1819 +#define PIMA15740_FMT_I_UNDEFINED 0x3800
1820 +#define PIMA15740_FMT_I_EXIF_JPEG 0x3801
1821 +#define PIMA15740_FMT_I_TIFF_EP 0x3802
1822 +#define PIMA15740_FMT_I_FLASHPIX 0x3803
1823 +#define PIMA15740_FMT_I_BMP 0x3804
1824 +#define PIMA15740_FMT_I_CIFF 0x3805
1825 +#define PIMA15740_FMT_I_GIF 0x3807
1826 +#define PIMA15740_FMT_I_JFIF 0x3808
1827 +#define PIMA15740_FMT_I_PCD 0x3809
1828 +#define PIMA15740_FMT_I_PICT 0x380a
1829 +#define PIMA15740_FMT_I_PNG 0x380b
1830 +#define PIMA15740_FMT_I_TIFF 0x380d
1831 +#define PIMA15740_FMT_I_TIFF_IT 0x380e
1832 +#define PIMA15740_FMT_I_JP2 0x380f
1833 +#define PIMA15740_FMT_I_JPX 0x3810
1835 +/* PIMA 15740 object protection status */
1836 +#define PIMA15740_OBJECT_NO_PROTECTION 0x0000
1837 +#define PIMA15740_OBJECT_READ_ONLY 0x0001
1839 +/* PIMA 15740 object association type */
1840 +#define PIMA15740_AS_UNDEFINED 0x0000
1841 +#define PIMA15740_AS_GENERIC_FOLDER 0x0001
1844 +static const char storage_desc[] = STORAGE_DESCRIPTION;
1845 +static const char device_version[] = DRIVER_VERSION;
1848 +/*-------------------------------------------------------------------------*/
1850 +/* PIMA 15740 data structure */
1852 +enum pima15740_container_type {
1853 + TYPE_UNDEFINED = 0,
1854 + TYPE_COMMAND_BLOCK = 1,
1855 + TYPE_DATA_BLOCK = 2,
1856 + TYPE_RESPONSE_BLOCK = 3,
1857 + TYPE_EVENT_BLOCK = 4,
1860 +/* PIMA15740 generic container structure, little endian */
1861 +struct pima15740_container {
1862 + __le32 container_len;
1863 + __le16 container_type;
1865 + __le32 transaction_id;
1866 +} __attribute__ ((packed));
1868 +/* data stage of Get Extended Event Data */
1869 +struct sti_ext_event {
1871 + u32 transaction_id;
1873 +} __attribute__ ((packed));
1875 +/* data stage of Get Device Status Data */
1876 +struct sti_dev_status {
1879 +} __attribute__ ((packed));
1882 +/* DeviceInfo Dataset */
1883 +struct pima15740_device_info {
1884 + u16 standard_version;
1885 + u32 vendor_extension_id;
1886 + u16 vendor_extension_version;
1887 + u8 vendor_extension_desc_len;
1888 + u8 vendor_extension_desc[0];
1889 + u16 functional_mode;
1890 + u32 operations_supported_count;
1891 + u16 operations_supported[14];
1892 + u32 events_supported_count;
1893 + u16 events_supported[0];
1894 + u32 device_properties_count;
1895 + u16 device_properties_supported[0];
1896 + u32 capture_formats_count;
1897 + u16 capture_formats[0];
1898 + u32 image_formats_count;
1899 + u16 image_formats[10];
1900 + u8 manufacturer_len;
1901 + u8 manufacturer[sizeof(manufacturer) * 2];
1903 + u8 model[sizeof(longname) * 2];
1904 + u8 device_version_len;
1905 + u8 device_version[sizeof(device_version) * 2];
1906 + u8 serial_number_len;
1907 + u8 serial_number[sizeof(serial) * 2];
1908 +} __attribute__ ((packed));
1910 +static struct pima15740_device_info sti_device_info = {
1911 + .standard_version = 100,
1912 + .vendor_extension_id = 0,
1913 + .vendor_extension_version = 0,
1914 + .vendor_extension_desc_len = 0,
1915 + .functional_mode = PIMA15740_STANDARD_MODE,
1916 + .operations_supported_count = 14,
1917 + .operations_supported = {
1918 + cpu_to_le16(PIMA15740_OP_GET_DEVICE_INFO),
1919 + cpu_to_le16(PIMA15740_OP_OPEN_SESSION),
1920 + cpu_to_le16(PIMA15740_OP_CLOSE_SESSION),
1921 + cpu_to_le16(PIMA15740_OP_GET_STORAGE_IDS),
1922 + cpu_to_le16(PIMA15740_OP_GET_STORAGE_INFO),
1923 + cpu_to_le16(PIMA15740_OP_GET_NUM_OBJECTS),
1924 + cpu_to_le16(PIMA15740_OP_GET_OBJECT_HANDLES),
1925 + cpu_to_le16(PIMA15740_OP_GET_OBJECT_INFO),
1926 + cpu_to_le16(PIMA15740_OP_GET_OBJECT),
1927 + cpu_to_le16(PIMA15740_OP_DELETE_OBJECT),
1928 + cpu_to_le16(PIMA15740_OP_SEND_OBJECT_INFO),
1929 + cpu_to_le16(PIMA15740_OP_SEND_OBJECT),
1930 + cpu_to_le16(PIMA15740_OP_COPY_OBJECT),
1931 + cpu_to_le16(PIMA15740_OP_MOVE_OBJECT)
1933 + .events_supported_count = 0,
1934 + .device_properties_count = 0,
1935 + .capture_formats_count = 0,
1936 + .image_formats_count = 10,
1937 + .image_formats = {
1938 + cpu_to_le16(PIMA15740_FMT_I_EXIF_JPEG),
1939 + cpu_to_le16(PIMA15740_FMT_I_JFIF),
1940 + cpu_to_le16(PIMA15740_FMT_I_PNG),
1941 + cpu_to_le16(PIMA15740_FMT_I_TIFF),
1942 + cpu_to_le16(PIMA15740_FMT_I_TIFF_EP),
1943 + cpu_to_le16(PIMA15740_FMT_I_TIFF_IT),
1944 + cpu_to_le16(PIMA15740_FMT_I_BMP),
1945 + cpu_to_le16(PIMA15740_FMT_I_GIF),
1946 + cpu_to_le16(PIMA15740_FMT_I_UNDEFINED),
1947 + cpu_to_le16(PIMA15740_FMT_A_UNDEFINED)
1949 + /* others will be filled in sti_bind() */
1953 +/* StorageInfo Dataset */
1954 +struct pima15740_storage_info {
1956 + u16 filesystem_type;
1957 + u16 access_capability;
1959 + u64 free_space_in_bytes;
1960 + u32 free_space_in_images;
1961 + u8 storage_desc_len;
1962 + u8 storage_desc[sizeof(storage_desc) * 2];
1963 + u8 volume_label_len;
1964 + u8 volume_label[0];
1965 +} __attribute__ ((packed));
1967 +static struct pima15740_storage_info sti_storage_info = {
1968 + .storage_type = cpu_to_le16(PIMA15740_STOR_FIXED_RAM),
1969 + .filesystem_type = cpu_to_le16(PIMA15740_FS_HIERARCHICAL),
1970 + .access_capability = cpu_to_le16(PIMA15740_ACCESS_CAP_RW),
1971 + .storage_desc_len = sizeof(storage_desc),
1972 + .volume_label_len = 0,
1973 + /* others will be filled later */
1977 +/* ObjectInfo Dataset */
1978 +struct pima15740_object_info {
1980 + u16 object_format;
1981 + u16 protection_status;
1982 + u32 object_compressed_size;
1984 + u32 thumb_compressed_size;
1985 + u32 thumb_pix_width;
1986 + u32 thumb_pix_height;
1987 + u32 image_pix_width;
1988 + u32 image_pix_height;
1989 + u32 image_bit_depth;
1990 + u32 parent_object;
1991 + u16 association_type;
1992 + u32 association_desc;
1993 + u32 sequence_number;
1994 + /* filename, capture date, modification date, keywords */
1995 + u8 obj_strings[]; /* size will be fixed later */
1996 +} __attribute__ ((packed));
1998 +/* object list element with object info data */
1999 +struct sti_object {
2000 + struct list_head list;
2002 + u32 parent_object;
2006 + size_t obj_info_size;
2007 + char filename[NAME_MAX];
2008 + char full_path[PATH_MAX];
2009 + struct pima15740_object_info obj_info;
2013 +/*-------------------------------------------------------------------------*/
2015 +/* device data structure */
2017 +enum sti_buffer_state {
2018 + BUF_STATE_EMPTY = 0,
2023 +struct sti_buffhd {
2025 + enum sti_buffer_state state;
2026 + struct sti_buffhd *next;
2027 + unsigned int bulk_out_intended_length;
2028 + struct usb_request *inreq;
2030 + struct usb_request *outreq;
2035 + STI_STATE_COMMAND_PHASE = -10, /* this one isn't used anywhere */
2036 + STI_STATE_DATA_PHASE,
2037 + STI_STATE_STATUS_PHASE,
2039 + STI_STATE_IDLE = 0,
2040 + STI_STATE_ABORT_BULK_OUT,
2043 + STI_STATE_INTERFACE_CHANGE,
2044 + STI_STATE_CONFIG_CHANGE,
2045 + STI_STATE_DISCONNECT,
2047 + STI_STATE_TERMINATED
2050 +enum data_direction {
2051 + DATA_DIR_UNKNOWN = 0,
2052 + DATA_DIR_FROM_HOST,
2058 + /* lock protects: device, req, endpoints states */
2061 + /* filesem protects: backing folder in use */
2062 + struct rw_semaphore filesem;
2064 + struct usb_gadget *gadget;
2066 + /* reference counting: wait until released */
2069 + /* handy copy of gadget->ep0 */
2070 + struct usb_ep *ep0;
2072 + /* for control responses */
2073 + struct usb_request *ep0req;
2074 + unsigned int ep0_req_tag;
2075 + const char *ep0req_name;
2077 + /* for interrupt responses */
2078 + struct usb_request *intreq;
2080 + struct sti_buffhd *intr_buffhd;
2082 + /* for exception handling */
2083 + enum sti_state state;
2084 + unsigned int exception_req_tag;
2086 + unsigned int bulk_out_maxpacket;
2087 + u8 config, new_config;
2089 + unsigned int running:1;
2090 + unsigned int bulk_in_enabled:1;
2091 + unsigned int bulk_out_enabled:1;
2092 + unsigned int intr_in_enabled:1;
2093 + unsigned int registered:1;
2094 + unsigned int session_open:1;
2096 + unsigned long atomic_bitflags;
2097 +#define REGISTERED 0
2098 +#define CLEAR_BULK_HALTS 1
2099 +#define SUSPENDED 2
2101 + struct usb_ep *bulk_in;
2102 + struct usb_ep *bulk_out;
2103 + struct usb_ep *intr_in;
2105 + struct sti_buffhd *next_buffhd_to_fill;
2106 + struct sti_buffhd *next_buffhd_to_drain;
2107 + struct sti_buffhd buffhds[NUM_BUFFERS];
2109 + int thread_wakeup_needed;
2110 + struct completion thread_notifier;
2111 + struct task_struct *thread_task;
2113 + __le32 container_len;
2114 + __le16 container_type;
2116 + __le32 transaction_id;
2118 + __le16 response_code;
2120 + u32 ops_params[PARAM_NUM_MAX];
2124 + u32 sub_object_num;
2126 + char root_path[PATH_MAX];
2127 + struct file *root_filp;
2128 + struct list_head obj_list;
2129 + struct list_head tmp_obj_list;
2131 + struct sti_ext_event ext_event_data;
2132 + struct sti_dev_status status_data;
2134 + struct device dev;
2138 +/*-------------------------------------------------------------------------*/
2140 +#define backing_folder_is_open(sti) ((sti)->root_filp != NULL)
2143 +typedef void (*sti_routine_t)(struct sti_dev *);
2145 +static int exception_in_progress(struct sti_dev *sti)
2147 + return (sti->state > STI_STATE_IDLE);
2150 +/* make bulk-out requests be divisible by the maxpacket size */
2151 +static void set_bulk_out_req_length(struct sti_dev *sti,
2152 + struct sti_buffhd *bh, unsigned int length)
2155 + VDBG(sti, "---> %s()\n", __func__);
2157 + bh->bulk_out_intended_length = length;
2158 + rem = length % sti->bulk_out_maxpacket;
2160 + length += sti->bulk_out_maxpacket - rem;
2161 + bh->outreq->length = length;
2163 + VDBG(sti, "<--- %s()\n", __func__);
2167 +/* global variables */
2168 +static struct sti_dev *the_sti;
2169 +static struct usb_gadget_driver sti_driver;
2171 +static void close_backing_folder(struct sti_dev *sti);
2174 +/*-------------------------------------------------------------------------*/
2176 +#ifdef VERBOSE_DEBUG
2178 +static void dump_msg(struct sti_dev *sti, const char *label,
2179 + const u8 *buf, unsigned int length)
2181 + if (length < 512) {
2182 + DBG(sti, "%s, length %u:\n", label, length);
2183 + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,
2184 + 16, 1, buf, length, 0);
2188 +static void dump_cb(struct sti_dev *sti)
2190 + print_hex_dump(KERN_DEBUG, "PIMA15740 Command Block: ",
2191 + DUMP_PREFIX_NONE, 16, 1, &sti->container_len,
2192 + PIMA15740_CONTAINER_LEN, 0);
2195 +static void dump_device_info(struct sti_dev *sti)
2199 + VDBG(sti, "DeviceInfo Dataset:\n");
2200 + VDBG(sti, "\tstandard_version: %u\n",
2201 + sti_device_info.standard_version);
2202 + VDBG(sti, "\tvendor_extension_id: %u\n",
2203 + sti_device_info.vendor_extension_id);
2204 + VDBG(sti, "\tvendor_extension_version: %u\n",
2205 + sti_device_info.vendor_extension_version);
2206 + VDBG(sti, "\tvendor_extension_desc_len: %u\n",
2207 + sti_device_info.vendor_extension_desc_len);
2208 + VDBG(sti, "\tfunctional_mode: 0x%04x\n",
2209 + sti_device_info.functional_mode);
2210 + VDBG(sti, "\toperations_supported_count: %u\n",
2211 + sti_device_info.operations_supported_count);
2212 + VDBG(sti, "\toperations_supported:\n");
2213 + for (i = 0; i < sti_device_info.operations_supported_count; i++)
2214 + VDBG(sti, "\t\t0x%04x\n",
2215 + sti_device_info.operations_supported[i]);
2216 + VDBG(sti, "\tevents_supported_count: %u\n",
2217 + sti_device_info.events_supported_count);
2218 + VDBG(sti, "\tdevice_properties_count: %u\n",
2219 + sti_device_info.device_properties_count);
2220 + VDBG(sti, "\tcapture_formats_count: %u\n",
2221 + sti_device_info.capture_formats_count);
2222 + VDBG(sti, "\timage_formats_count: %u\n",
2223 + sti_device_info.image_formats_count);
2224 + VDBG(sti, "\tmanufacturer_len: %u\n",
2225 + sti_device_info.manufacturer_len);
2226 + VDBG(sti, "\tmanufacturer: %s\n", manufacturer);
2227 + VDBG(sti, "\tmodel_len: %u\n",
2228 + sti_device_info.model_len);
2229 + VDBG(sti, "\tmodel: %s\n", longname);
2230 + VDBG(sti, "\tdevice_version_len: %u\n",
2231 + sti_device_info.device_version_len);
2232 + VDBG(sti, "\tdevice_version: %s\n", device_version);
2233 + VDBG(sti, "\tserial_number_len: %u\n",
2234 + sti_device_info.serial_number_len);
2235 + VDBG(sti, "\tserial_number: %s\n", serial);
2238 +static void dump_storage_info(struct sti_dev *sti)
2240 + VDBG(sti, "StorageInfo Dataset:\n");
2241 + VDBG(sti, "\tstorage_type: 0x%04x\n", sti_storage_info.storage_type);
2242 + VDBG(sti, "\tfilesystem_type: 0x%04x\n",
2243 + sti_storage_info.filesystem_type);
2244 + VDBG(sti, "\taccess_capability: 0x%04x\n",
2245 + sti_storage_info.access_capability);
2246 + VDBG(sti, "\tmax_capacity: %llu\n", sti_storage_info.max_capacity);
2247 + VDBG(sti, "\tfree_space_in_bytes: %llu\n",
2248 + sti_storage_info.free_space_in_bytes);
2249 + VDBG(sti, "\tfree_space_in_images: %u\n",
2250 + sti_storage_info.free_space_in_images);
2251 + VDBG(sti, "\tstorage_desc_len: %u\n",
2252 + sti_storage_info.storage_desc_len);
2253 + VDBG(sti, "\tstorage_desc: %s\n", storage_desc);
2254 + VDBG(sti, "\tvolume_label_len: %u\n",
2255 + sti_storage_info.volume_label_len);
2258 +static void dump_object_info(struct sti_dev *sti, struct sti_object *obj)
2262 + VDBG(sti, "ObjectInfo Dataset:\n");
2263 + VDBG(sti, "\tstorage_id: 0x%08x\n", obj->obj_info.storage_id);
2264 + VDBG(sti, "\tobject_format: 0x%04x\n", obj->obj_info.object_format);
2265 + VDBG(sti, "\tprotection_status: 0x%04x\n",
2266 + obj->obj_info.protection_status);
2267 + VDBG(sti, "\tobject_compressed_size: %u\n",
2268 + obj->obj_info.object_compressed_size);
2269 + VDBG(sti, "\tthumb_format: %u\n", obj->obj_info.thumb_format);
2270 + VDBG(sti, "\tthumb_compressed_size: %u\n",
2271 + obj->obj_info.thumb_compressed_size);
2272 + VDBG(sti, "\tthumb_pix_width: %u\n",
2273 + obj->obj_info.thumb_pix_width);
2274 + VDBG(sti, "\tthumb_pix_height: %u\n",
2275 + obj->obj_info.thumb_pix_height);
2276 + VDBG(sti, "\timage_pix_width: %u\n",
2277 + obj->obj_info.image_pix_width);
2278 + VDBG(sti, "\timage_pix_height: %u\n",
2279 + obj->obj_info.image_pix_height);
2280 + VDBG(sti, "\timage_bit_depth: %u\n",
2281 + obj->obj_info.image_bit_depth);
2282 + VDBG(sti, "\tparent_object: 0x%08x\n",
2283 + obj->obj_info.parent_object);
2284 + VDBG(sti, "\tassociation_type: 0x%04x\n",
2285 + obj->obj_info.association_type);
2286 + VDBG(sti, "\tassociation_desc: 0x%08x\n",
2287 + obj->obj_info.association_desc);
2288 + VDBG(sti, "\tsequence_number: 0x%08x\n",
2289 + obj->obj_info.sequence_number);
2290 + VDBG(sti, "\tfilename_len: %u\n", obj->obj_info.obj_strings[0]);
2291 + filename_len = obj->obj_info.obj_strings[0];
2292 + VDBG(sti, "\tfilename: %s\n", obj->filename);
2293 + VDBG(sti, "\tcapture_date_len: %u\n",
2294 + obj->obj_info.obj_strings[filename_len * 2 + 1]);
2295 + VDBG(sti, "\tmodification_date_len: %u\n",
2296 + obj->obj_info.obj_strings[filename_len * 2 + 2]);
2297 + VDBG(sti, "\tkeywords_len: %u\n",
2298 + obj->obj_info.obj_strings[filename_len * 2 + 3]);
2303 +static void dump_msg(struct sti_dev *sti, const char *label,
2304 + const u8 *buf, unsigned int length)
2307 +static void dump_cb(struct sti_dev *sti)
2310 +static void dump_device_info(struct sti_dev *sti)
2313 +static void dump_storage_info(struct sti_dev *sti)
2316 +static void dump_object_info(struct sti_dev *sti, struct sti_object *obj)
2319 +#endif /* VERBOSE_DEBUG */
2322 +/*-------------------------------------------------------------------------*/
2327 + * Config descriptors must agree with the code that sets configurations
2328 + * and with code managing interfaces and their altsettings. They must
2329 + * also handle different speeds and other-speed requests.
2331 +static int populate_config_buf(struct usb_gadget *gadget,
2332 + u8 *buf, u8 type, unsigned index)
2334 + enum usb_device_speed speed = gadget->speed;
2336 + const struct usb_descriptor_header **function;
2341 + if (gadget_is_dualspeed(gadget) && type == USB_DT_OTHER_SPEED_CONFIG)
2342 + speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed;
2343 + if (gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH)
2344 + function = hs_function;
2346 + function = fs_function;
2348 + /* for now, don't advertise srp-only devices */
2349 + if (!gadget_is_otg(gadget))
2352 + len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function);
2353 + ((struct usb_config_descriptor *) buf)->bDescriptorType = type;
2359 +/*-------------------------------------------------------------------------*/
2361 +/* these routines may be called in process context or in_irq */
2363 +/* caller must hold sti->lock */
2364 +static void wakeup_thread(struct sti_dev *sti)
2366 + VDBG(sti, "---> %s()\n", __func__);
2368 + /* tell the main thread that something has happened */
2369 + sti->thread_wakeup_needed = 1;
2370 + if (sti->thread_task)
2371 + wake_up_process(sti->thread_task);
2373 + VDBG(sti, "<--- %s()\n", __func__);
2377 +static void raise_exception(struct sti_dev *sti, enum sti_state new_state)
2379 + unsigned long flags;
2380 + VDBG(sti, "---> %s()\n", __func__);
2383 + * Do nothing if a higher-priority exception is already in progress.
2384 + * If a lower-or-equal priority exception is in progress, preempt it
2385 + * and notify the main thread by sending it a signal.
2387 + spin_lock_irqsave(&sti->lock, flags);
2388 + if (sti->state <= new_state) {
2389 + sti->exception_req_tag = sti->ep0_req_tag;
2390 + sti->state = new_state;
2391 + if (sti->thread_task)
2392 + send_sig_info(SIGUSR1, SEND_SIG_FORCED,
2393 + sti->thread_task);
2395 + spin_unlock_irqrestore(&sti->lock, flags);
2397 + VDBG(sti, "<--- %s()\n", __func__);
2401 +/*-------------------------------------------------------------------------*/
2404 + * The disconnect callback and ep0 routines. These always run in_irq,
2405 + * except that ep0_queue() is called in the main thread to acknowledge
2406 + * completion of various requests: set config, set interface, and
2407 + * Bulk-only device reset.
2410 +static void sti_disconnect(struct usb_gadget *gadget)
2412 + struct sti_dev *sti = get_gadget_data(gadget);
2413 + VDBG(sti, "---> %s()\n", __func__);
2415 + DBG(sti, "disconnect or port reset\n");
2416 + raise_exception(sti, STI_STATE_DISCONNECT);
2418 + VDBG(sti, "<--- %s()\n", __func__);
2421 +static int ep0_queue(struct sti_dev *sti)
2424 + VDBG(sti, "---> %s()\n", __func__);
2426 + rc = usb_ep_queue(sti->ep0, sti->ep0req, GFP_ATOMIC);
2427 + if (rc != 0 && rc != -ESHUTDOWN) {
2428 + /* we can't do much more than wait for a reset */
2429 + WARNING(sti, "error in submission: %s --> %d\n",
2430 + sti->ep0->name, rc);
2433 + VDBG(sti, "<--- %s()\n", __func__);
2437 +static void ep0_complete(struct usb_ep *ep, struct usb_request *req)
2439 + struct sti_dev *sti = ep->driver_data;
2440 + VDBG(sti, "---> %s()\n", __func__);
2442 + if (req->actual > 0)
2443 + dump_msg(sti, sti->ep0req_name, req->buf, req->actual);
2445 + if (req->status || req->actual != req->length)
2446 + VDBG(sti, "%s --> %d, %u/%u\n", __func__,
2447 + req->status, req->actual, req->length);
2449 + /* request was cancelled */
2450 + if (req->status == -ECONNRESET)
2451 + usb_ep_fifo_flush(ep);
2453 + if (req->status == 0 && req->context)
2454 + ((sti_routine_t) (req->context))(sti);
2456 + VDBG(sti, "<--- %s()\n", __func__);
2460 +/*-------------------------------------------------------------------------*/
2462 +/* endpoint completion handlers, always run in_irq */
2464 +static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req)
2466 + struct sti_dev *sti = ep->driver_data;
2467 + struct sti_buffhd *bh = req->context;
2468 + VDBG(sti, "---> %s()\n", __func__);
2470 + if (req->status || req->actual != req->length)
2471 + VDBG(sti, "%s --> %d, %u/%u\n", __func__,
2472 + req->status, req->actual, req->length);
2473 + /* request was cancelled */
2474 + if (req->status == -ECONNRESET)
2475 + usb_ep_fifo_flush(ep);
2477 + /* hold the lock while we update the request and buffer states */
2479 + spin_lock(&sti->lock);
2480 + bh->inreq_busy = 0;
2481 + bh->state = BUF_STATE_EMPTY;
2482 + wakeup_thread(sti);
2483 + spin_unlock(&sti->lock);
2485 + VDBG(sti, "<--- %s()\n", __func__);
2488 +static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
2490 + struct sti_dev *sti = ep->driver_data;
2491 + struct sti_buffhd *bh = req->context;
2492 + VDBG(sti, "---> %s()\n", __func__);
2494 + dump_msg(sti, "bulk-out", req->buf, req->actual);
2495 + if (req->status || req->actual != bh->bulk_out_intended_length)
2496 + VDBG(sti, "%s --> %d, %u/%u\n", __func__,
2497 + req->status, req->actual,
2498 + bh->bulk_out_intended_length);
2500 + /* request was cancelled */
2501 + if (req->status == -ECONNRESET)
2502 + usb_ep_fifo_flush(ep);
2504 + /* hold the lock while we update the request and buffer states */
2506 + spin_lock(&sti->lock);
2507 + bh->outreq_busy = 0;
2508 + bh->state = BUF_STATE_FULL;
2509 + wakeup_thread(sti);
2510 + spin_unlock(&sti->lock);
2512 + VDBG(sti, "<--- %s()\n", __func__);
2516 +/*-------------------------------------------------------------------------*/
2518 +static int sti_set_halt(struct sti_dev *sti, struct usb_ep *ep)
2521 + VDBG(sti, "---> %s()\n", __func__);
2523 + if (ep == sti->bulk_in)
2525 + else if (ep == sti->bulk_out)
2526 + name = "bulk-out";
2530 + DBG(sti, "%s set halt\n", name);
2531 + VDBG(sti, "<--- %s()\n", __func__);
2533 + return usb_ep_set_halt(ep);
2537 +static void received_cancel_request(struct sti_dev *sti)
2539 + struct usb_request *req = sti->ep0req;
2543 + VDBG(sti, "---> %s()\n", __func__);
2545 + /* error in command transfer */
2546 + if (req->status || req->length != req->actual) {
2547 + /* wait for reset */
2548 + sti_set_halt(sti, sti->ep0);
2552 + VDBG(sti, "receive cancel request\n");
2557 + cancel_code = get_unaligned_le16(req->buf);
2558 + if (cancel_code != cpu_to_le16(STI_CANCEL_REQUEST_CODE)) {
2559 + VDBG(sti, "invalid cancel_code: 0x%04x\n", cancel_code);
2563 + trans_id = get_unaligned_le32(req->buf + 2);
2564 + if (trans_id != sti->transaction_id) {
2565 + VDBG(sti, "invalid trans_id:0x%04x\n", trans_id);
2569 + /* stall bulk endpoints */
2570 + sti_set_halt(sti, sti->bulk_out);
2572 + rc = sti_set_halt(sti, sti->bulk_in);
2573 + if (rc == -EAGAIN)
2574 + VDBG(sti, "delayed bulk-in endpoint halt\n");
2576 + sti->response_code = PIMA15740_RES_DEVICE_BUSY;
2578 + raise_exception(sti, STI_STATE_CANCEL);
2580 + VDBG(sti, "<--- %s()\n", __func__);
2584 +/* ep0 class-specific request handlers, always run in_irq */
2585 +static int class_setup_req(struct sti_dev *sti,
2586 + const struct usb_ctrlrequest *ctrl)
2588 + struct usb_request *req = sti->ep0req;
2589 + int value = -EOPNOTSUPP;
2590 + u16 w_index = le16_to_cpu(ctrl->wIndex);
2591 + u16 w_value = le16_to_cpu(ctrl->wValue);
2592 + u16 w_length = le16_to_cpu(ctrl->wLength);
2593 + VDBG(sti, "---> %s()\n", __func__);
2598 + /* handle class-specific requests */
2599 + switch (ctrl->bRequest) {
2601 + case STI_CANCEL_REQUEST:
2602 + if (ctrl->bRequestType != (USB_DIR_OUT |
2603 + USB_TYPE_CLASS | USB_RECIP_INTERFACE))
2605 + if (w_index != 0 || w_value != 0 || w_length != 6) {
2610 + DBG(sti, "cancel request\n");
2613 + sti->ep0req->context = received_cancel_request;
2616 + case STI_GET_EXTENDED_EVENT_DATA:
2617 + /* asynchronous events by interrupt endpoint */
2618 + if (ctrl->bRequestType != (USB_DIR_IN |
2619 + USB_TYPE_CLASS | USB_RECIP_INTERFACE))
2621 + if (w_index != 0 || w_value != 0) {
2626 + DBG(sti, "get extended event data\n");
2628 + sti->ext_event_data.event_code = PIMA15740_RES_OK;
2629 + sti->ext_event_data.transaction_id = sti->transaction_id;
2630 + sti->ext_event_data.param_num = 0;
2632 + value = min_t(unsigned, w_length,
2633 + sizeof(struct sti_ext_event));
2634 + memcpy(req->buf, &sti->ext_event_data, value);
2637 + case STI_DEVICE_RESET_REQUEST:
2638 + if (ctrl->bRequestType != (USB_DIR_OUT |
2639 + USB_TYPE_CLASS | USB_RECIP_INTERFACE))
2641 + if (w_index != 0 || w_value != 0 || w_length != 0) {
2646 + /* Raise an exception to stop the current operation
2647 + * and reinitialize our state. */
2648 + DBG(sti, "device reset request\n");
2650 + sti->response_code = PIMA15740_RES_OK;
2651 + sti->session_open = 1;
2653 + raise_exception(sti, STI_STATE_RESET);
2654 + value = DELAYED_STATUS;
2657 + case STI_GET_DEVICE_STATUS:
2658 + if (ctrl->bRequestType != (USB_DIR_IN |
2659 + USB_TYPE_CLASS | USB_RECIP_INTERFACE))
2661 + if (w_index != 0 || w_value != 0) {
2666 + DBG(sti, "get device status\n");
2667 + sti->status_data.wlength = 4;
2668 + sti->status_data.code = sti->response_code;
2670 + value = min_t(unsigned, w_length,
2671 + sizeof(struct sti_dev_status));
2672 + memcpy(req->buf, &sti->status_data, value);
2676 + DBG(sti, "unknown class-specific control req "
2677 + "%02x.%02x v%04x i%04x l%u\n",
2678 + ctrl->bRequestType, ctrl->bRequest,
2679 + le16_to_cpu(ctrl->wValue), w_index, w_length);
2683 + VDBG(sti, "<--- %s()\n", __func__);
2688 +/*-------------------------------------------------------------------------*/
2690 +/* ep0 standard request handlers, always run in_irq */
2692 +static int standard_setup_req(struct sti_dev *sti,
2693 + const struct usb_ctrlrequest *ctrl)
2695 + struct usb_request *req = sti->ep0req;
2696 + int value = -EOPNOTSUPP;
2697 + u16 w_index = le16_to_cpu(ctrl->wIndex);
2698 + u16 w_value = le16_to_cpu(ctrl->wValue);
2699 + VDBG(sti, "---> %s()\n", __func__);
2701 + /* usually this just stores reply data in the pre-allocated ep0 buffer,
2702 + * but config change events will also reconfigure hardware */
2703 + switch (ctrl->bRequest) {
2705 + case USB_REQ_GET_DESCRIPTOR:
2706 + if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
2707 + USB_RECIP_DEVICE))
2709 + switch (w_value >> 8) {
2711 + case USB_DT_DEVICE:
2712 + VDBG(sti, "get device descriptor\n");
2713 + value = sizeof device_desc;
2714 + memcpy(req->buf, &device_desc, value);
2716 + case USB_DT_DEVICE_QUALIFIER:
2717 + VDBG(sti, "get device qualifier\n");
2718 + if (!gadget_is_dualspeed(sti->gadget))
2720 + value = sizeof dev_qualifier;
2721 + memcpy(req->buf, &dev_qualifier, value);
2724 + case USB_DT_OTHER_SPEED_CONFIG:
2725 + VDBG(sti, "get other-speed config descriptor\n");
2726 + if (!gadget_is_dualspeed(sti->gadget))
2729 + case USB_DT_CONFIG:
2730 + VDBG(sti, "get configuration descriptor\n");
2732 + value = populate_config_buf(sti->gadget,
2738 + case USB_DT_STRING:
2739 + VDBG(sti, "get string descriptor\n");
2741 + /* wIndex == language code */
2742 + value = usb_gadget_get_string(&stringtab,
2743 + w_value & 0xff, req->buf);
2748 + /* one config, two speeds */
2749 + case USB_REQ_SET_CONFIGURATION:
2750 + if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD |
2751 + USB_RECIP_DEVICE))
2753 + VDBG(sti, "set configuration\n");
2754 + if (w_value == CONFIG_VALUE || w_value == 0) {
2755 + sti->new_config = w_value;
2757 + /* Raise an exception to wipe out previous transaction
2758 + * state (queued bufs, etc) and set the new config. */
2759 + raise_exception(sti, STI_STATE_CONFIG_CHANGE);
2760 + value = DELAYED_STATUS;
2764 + case USB_REQ_GET_CONFIGURATION:
2765 + if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
2766 + USB_RECIP_DEVICE))
2768 + VDBG(sti, "get configuration\n");
2769 + *(u8 *) req->buf = sti->config;
2773 + case USB_REQ_SET_INTERFACE:
2774 + if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD |
2775 + USB_RECIP_INTERFACE))
2777 + if (sti->config && w_index == 0) {
2779 + /* Raise an exception to wipe out previous transaction
2780 + * state (queued bufs, etc) and install the new
2781 + * interface altsetting. */
2782 + raise_exception(sti, STI_STATE_INTERFACE_CHANGE);
2783 + value = DELAYED_STATUS;
2787 + case USB_REQ_GET_INTERFACE:
2788 + if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
2789 + USB_RECIP_INTERFACE))
2793 + if (w_index != 0) {
2797 + VDBG(sti, "get interface\n");
2798 + *(u8 *) req->buf = 0;
2803 + VDBG(sti, "unknown control req %02x.%02x v%04x i%04x l%u\n",
2804 + ctrl->bRequestType, ctrl->bRequest,
2805 + w_value, w_index, le16_to_cpu(ctrl->wLength));
2808 + VDBG(sti, "<--- %s()\n", __func__);
2812 +static int sti_setup(struct usb_gadget *gadget,
2813 + const struct usb_ctrlrequest *ctrl)
2815 + struct sti_dev *sti = get_gadget_data(gadget);
2817 + int w_length = le16_to_cpu(ctrl->wLength);
2818 + VDBG(sti, "---> %s()\n", __func__);
2820 + /* record arrival of a new request */
2821 + ++sti->ep0_req_tag;
2822 + sti->ep0req->context = NULL;
2823 + sti->ep0req->length = 0;
2824 + dump_msg(sti, "ep0-setup", (u8 *) ctrl, sizeof(*ctrl));
2826 + if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS)
2827 + rc = class_setup_req(sti, ctrl);
2829 + rc = standard_setup_req(sti, ctrl);
2831 + /* respond with data/status or defer until later */
2832 + if (rc >= 0 && rc != DELAYED_STATUS) {
2833 + rc = min(rc, w_length);
2834 + sti->ep0req->length = rc;
2835 + sti->ep0req->zero = rc < w_length;
2836 + sti->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ?
2837 + "ep0-in" : "ep0-out");
2838 + rc = ep0_queue(sti);
2841 + VDBG(sti, "<--- %s()\n", __func__);
2842 + /* device either stalls (rc < 0) or reports success */
2847 +/*-------------------------------------------------------------------------*/
2849 +/* all the following routines run in process context */
2851 +/* use this for bulk or interrupt transfers, not ep0 */
2852 +static void start_transfer(struct sti_dev *sti, struct usb_ep *ep,
2853 + struct usb_request *req, int *pbusy,
2854 + enum sti_buffer_state *state)
2857 + VDBG(sti, "---> %s()\n", __func__);
2859 + if (ep == sti->bulk_in)
2860 + dump_msg(sti, "bulk-in", req->buf, req->length);
2861 + else if (ep == sti->intr_in)
2862 + dump_msg(sti, "intr-in", req->buf, req->length);
2864 + spin_lock_irq(&sti->lock);
2866 + *state = BUF_STATE_BUSY;
2867 + spin_unlock_irq(&sti->lock);
2869 + rc = usb_ep_queue(ep, req, GFP_KERNEL);
2870 + VDBG(sti, "start_transfer, rc: %d\n", rc);
2873 + *state = BUF_STATE_EMPTY;
2874 + if (rc != -ESHUTDOWN && !(rc == -EOPNOTSUPP &&
2875 + req->length == 0))
2876 + WARNING(sti, "error in submission: %s --> %d\n",
2880 + VDBG(sti, "<--- %s()\n", __func__);
2884 +static int sleep_thread(struct sti_dev *sti)
2887 + VDBG(sti, "---> %s()\n", __func__);
2889 + /* wait until a signal arrives or we are woken up */
2892 + set_current_state(TASK_INTERRUPTIBLE);
2893 + if (signal_pending(current)) {
2897 + if (sti->thread_wakeup_needed)
2903 + __set_current_state(TASK_RUNNING);
2904 + sti->thread_wakeup_needed = 0;
2906 + VDBG(sti, "<--- %s()\n", __func__);
2911 +/*-------------------------------------------------------------------------*/
2913 +static int fill_data_container(struct sti_buffhd *bh,
2914 + struct sti_dev *sti, unsigned int size)
2916 + struct pima15740_container *rb;
2917 + VDBG(sti, "---> %s()\n", __func__);
2921 + rb->container_len = size;
2922 + rb->container_type = TYPE_DATA_BLOCK;
2923 + rb->code = sti->code;
2924 + rb->transaction_id = sti->transaction_id;
2926 + bh->inreq->zero = 0;
2928 + VDBG(sti, "<--- %s()\n", __func__);
2933 +static int send_response(struct sti_dev *sti, unsigned int code)
2935 + struct sti_buffhd *bh;
2936 + struct pima15740_container *rb;
2938 + VDBG(sti, "---> %s()\n", __func__);
2940 + /* wait for the next buffer to become available */
2941 + bh = sti->next_buffhd_to_fill;
2942 + while (bh->state != BUF_STATE_EMPTY) {
2943 + rc = sleep_thread(sti);
2950 + rb->container_len = PIMA15740_CONTAINER_LEN;
2951 + rb->container_type = TYPE_RESPONSE_BLOCK;
2953 + rb->transaction_id = sti->transaction_id;
2955 + bh->inreq->length = PIMA15740_CONTAINER_LEN;
2956 + bh->state = BUF_STATE_FULL;
2957 + bh->inreq->zero = 0;
2959 + start_transfer(sti, sti->bulk_in, bh->inreq,
2960 + &bh->inreq_busy, &bh->state);
2962 + sti->next_buffhd_to_fill = bh->next;
2964 + VDBG(sti, "<--- %s()\n", __func__);
2969 +static int send_params_response(struct sti_dev *sti, unsigned int code,
2970 + u32 p1, u32 p2, u32 p3, unsigned p_num)
2972 + struct sti_buffhd *bh;
2973 + struct pima15740_container *rb;
2975 + VDBG(sti, "---> %s()\n", __func__);
2977 + /* wait for the next buffer to become available */
2978 + bh = sti->next_buffhd_to_fill;
2979 + while (bh->state != BUF_STATE_EMPTY) {
2980 + rc = sleep_thread(sti);
2987 + rb->container_len = PIMA15740_CONTAINER_LEN + p_num * 4;
2988 + rb->container_type = TYPE_RESPONSE_BLOCK;
2990 + rb->transaction_id = sti->transaction_id;
2994 + memcpy((u8 *)rb + PIMA15740_CONTAINER_LEN, &p1, 4);
2995 + memcpy((u8 *)rb + PIMA15740_CONTAINER_LEN + 4, &p2, 4);
2996 + memcpy((u8 *)rb + PIMA15740_CONTAINER_LEN + 8, &p3, 4);
2999 + memcpy((u8 *)rb + PIMA15740_CONTAINER_LEN, &p1, 4);
3000 + memcpy((u8 *)rb + PIMA15740_CONTAINER_LEN + 4, &p2, 4);
3003 + memcpy((u8 *)rb + PIMA15740_CONTAINER_LEN, &p1, 4);
3009 + bh->inreq->length = PIMA15740_CONTAINER_LEN + p_num * 4;
3010 + bh->state = BUF_STATE_FULL;
3011 + bh->inreq->zero = 0;
3013 + start_transfer(sti, sti->bulk_in, bh->inreq,
3014 + &bh->inreq_busy, &bh->state);
3016 + sti->next_buffhd_to_fill = bh->next;
3018 + VDBG(sti, "<--- %s()\n", __func__);
3022 +/* ISO-8859-1 to UTF-16LE */
3023 +static unsigned short str_to_uni16(const char *src, char *dest)
3027 + for (i = 0; i < strlen(src); i++) {
3028 + dest[i * 2] = src[i];
3029 + dest[i * 2 + 1] = '\0';
3032 + /* null-terminated string */
3033 + dest[i * 2] = dest[i * 2 + 1] = '\0';
3035 + return (i + 1) * 2;
3038 +/* UTF-16LE to ISO-8859-1 */
3039 +static void uni16_to_str(const char *src, char *dest, unsigned short len)
3043 + for (i = 0; i < len; i++)
3044 + dest[i] = src[i * 2];
3048 +static int do_get_device_info(struct sti_dev *sti, struct sti_buffhd *bh)
3052 + VDBG(sti, "---> %s()\n", __func__);
3054 + /* dump DeviceInfo Dataset */
3055 + dump_device_info(sti);
3057 + size = sizeof sti_device_info;
3058 + fill_data_container(bh, sti, PIMA15740_CONTAINER_LEN + size);
3060 + memcpy(bh->buf + PIMA15740_CONTAINER_LEN, &sti_device_info, size);
3062 + bh->inreq->length = PIMA15740_CONTAINER_LEN + size;
3063 + bh->state = BUF_STATE_FULL;
3064 + start_transfer(sti, sti->bulk_in, bh->inreq,
3065 + &bh->inreq_busy, &bh->state);
3066 + sti->next_buffhd_to_fill = bh->next;
3068 + /* send response */
3069 + rc = send_response(sti, PIMA15740_RES_OK);
3071 + VDBG(sti, "<--- %s()\n", __func__);
3076 +static int filldir_all(void *__buf, const char *name, int len,
3077 + loff_t pos, u64 ino, unsigned int d_type)
3079 + struct sti_dev *sti = __buf;
3080 + struct sti_object *obj;
3083 + char filename_utf16le[NAME_MAX * 2];
3085 + u16 object_format = PIMA15740_FMT_A_UNDEFINED;
3087 + VDBG(sti, "---> %s()\n", __func__);
3088 + VDBG(sti, "name: %s, len: %d, pos: %lu, ino: %llu, d_type: %u\n",
3089 + name, len, (unsigned long)pos, ino, d_type);
3091 + /* ignore "." and ".." directories */
3092 + if (!strcmp(name, ".") || !strcmp(name, ".."))
3095 + if (d_type != DT_DIR && d_type != DT_REG)
3098 + /* filename strings length */
3099 + filename_len = len + 1;
3100 + VDBG(sti, "filename_len: %u\n", filename_len);
3102 + /* sti_object size */
3103 + obj_size = sizeof(struct sti_object) + 2 * filename_len + 4;
3104 + VDBG(sti, "obj_size: %u\n", obj_size);
3105 + /* obj_size > sizeof(struct sti_object) */
3106 + obj = kzalloc(obj_size, GFP_KERNEL);
3112 + /* fill part of sti_object info */
3113 + obj->storage_id = STORAGE_ID;
3114 + obj->send_valid = 0;
3116 + /* ObjectInfo Dataset size */
3117 + obj->obj_info_size = sizeof(struct pima15740_object_info)
3118 + + 2 * filename_len + 4;
3119 + VDBG(sti, "obj_info_size: %u\n", obj->obj_info_size);
3122 + memset(obj->filename, 0, sizeof(obj->filename));
3123 + strncpy(obj->filename, name, len);
3125 + /* fill ObjectInfo Dataset */
3126 + obj->obj_info.storage_id = cpu_to_le32(STORAGE_ID);
3128 + if (d_type == DT_DIR) { /* association */
3129 + object_format = PIMA15740_FMT_A_ASSOCIATION;
3130 + obj->obj_info.association_type =
3131 + cpu_to_le16(PIMA15740_AS_GENERIC_FOLDER);
3133 + } else if (d_type == DT_REG) { /* regular file */
3134 + ext = strrchr(obj->filename, '.');
3136 + /* image object */
3137 + if (!strcasecmp(ext, ".jpg") ||
3138 + !strcasecmp(ext, ".jpeg") ||
3139 + !strcasecmp(ext, ".jpe"))
3140 + object_format = PIMA15740_FMT_I_EXIF_JPEG;
3141 + else if (!strcasecmp(ext, ".jfif"))
3142 + object_format = PIMA15740_FMT_I_JFIF;
3143 + else if (!strcasecmp(ext, ".tif") ||
3144 + !strcasecmp(ext, ".tiff"))
3145 + object_format = PIMA15740_FMT_I_TIFF;
3146 + else if (!strcasecmp(ext, ".png"))
3147 + object_format = PIMA15740_FMT_I_PNG;
3148 + else if (!strcasecmp(ext, ".bmp"))
3149 + object_format = PIMA15740_FMT_I_BMP;
3150 + else if (!strcasecmp(ext, ".gif"))
3151 + object_format = PIMA15740_FMT_I_GIF;
3152 + else /* undefined non-image object */
3153 + object_format = PIMA15740_FMT_A_UNDEFINED;
3154 + } else /* file without extension */
3155 + object_format = PIMA15740_FMT_A_UNDEFINED;
3156 + obj->obj_info.association_type =
3157 + cpu_to_le16(PIMA15740_AS_UNDEFINED);
3160 + obj->obj_info.object_format = cpu_to_le16(object_format);
3162 + /* protection_status, object_compressed_size will be filled later */
3163 + obj->obj_info.thumb_format = cpu_to_le16(0);
3164 + obj->obj_info.thumb_compressed_size = cpu_to_le32(0);
3165 + obj->obj_info.thumb_pix_width = cpu_to_le32(0);
3166 + obj->obj_info.thumb_pix_height = cpu_to_le32(0);
3167 + obj->obj_info.image_pix_width = cpu_to_le32(0);
3168 + obj->obj_info.image_pix_height = cpu_to_le32(0);
3169 + obj->obj_info.image_bit_depth = cpu_to_le32(0);
3171 + obj->obj_info.association_desc = cpu_to_le32(0);
3172 + obj->obj_info.sequence_number = cpu_to_le32(0);
3174 + /* filename_utf16le: UTF-16LE unicode string */
3175 + obj->obj_info.obj_strings[0] = filename_len;
3176 + memset(filename_utf16le, 0, sizeof(filename_utf16le));
3177 + str_to_uni16(obj->filename, filename_utf16le);
3178 + memcpy(obj->obj_info.obj_strings + 1, filename_utf16le,
3179 + filename_len * 2);
3181 + /* capture date */
3182 + obj->obj_info.obj_strings[filename_len * 2 + 1] = 0;
3184 + /* modification date */
3185 + obj->obj_info.obj_strings[filename_len * 2 + 2] = 0;
3188 + obj->obj_info.obj_strings[filename_len * 2 + 3] = 0;
3190 + /* increase object number */
3191 + sti->sub_object_num++;
3193 + /* add to temp object list */
3194 + list_add_tail(&obj->list, &sti->tmp_obj_list);
3196 + VDBG(sti, "<--- %s()\n", __func__);
3201 +/* alphabetic sort function */
3202 +static int alnumsort(const void *a, const void *b)
3204 + const struct sti_object *oa = *(const struct sti_object **)a;
3205 + const struct sti_object *ob = *(const struct sti_object **)b;
3206 + return strcmp(oa->filename, ob->filename);
3210 +/* descend through the hierarchical folder recursively */
3211 +static int list_objects(struct sti_dev *sti, const char *folder_name,
3212 + struct sti_object *folder_obj, bool recursive)
3214 + struct file *filp;
3215 + struct dentry *dentry;
3216 + struct sti_object *obj = NULL;
3217 + struct sti_object *tmp_obj;
3218 + struct sti_object **pobj, **temp_pobj = NULL;
3219 + struct kstat stat;
3220 + u32 parent_object;
3222 + VDBG(sti, "---> %s()\n", __func__);
3224 + /* root directory */
3225 + if (!strcmp(folder_name, sti->root_path)) {
3226 + filp = sti->root_filp;
3227 + parent_object = 0;
3228 + VDBG(sti, "root directory\n");
3229 + } else { /* subdirectory */
3230 + filp = filp_open(folder_name, O_RDONLY | O_DIRECTORY, 0);
3231 + if (IS_ERR(filp)) {
3232 + ERROR(sti, "unable to open folder: %s\n",
3234 + return PTR_ERR(filp);
3236 + VDBG(sti, "folder_name: %s\n", folder_name);
3237 + parent_object = folder_obj->obj_handle;
3239 + dentry = filp->f_dentry;
3241 + sti->sub_object_num = 0;
3243 + rc = vfs_readdir(filp, filldir_all, sti);
3245 + ERROR(sti, "vfs_readdir %s error: %d\n",
3247 + VDBG(sti, "%d objects in folder %s\n",
3248 + sti->sub_object_num, folder_name);
3250 + /* no file in the directory */
3251 + if (!sti->sub_object_num)
3254 + /* pre-allocated objects array */
3255 + pobj = kzalloc((sti->sub_object_num + 1) * sizeof(struct sti_object *),
3265 + list_for_each_entry_safe(obj, tmp_obj, &sti->tmp_obj_list, list) {
3267 + /* remove from temp object list */
3268 + list_del_init(&obj->list);
3271 + VDBG(sti, "i = %d\n", i);
3274 + /* sort the objects array */
3275 + sort(pobj, sti->sub_object_num, sizeof(struct sti_object *),
3279 + /* increase total object number */
3280 + sti->object_num++;
3282 + /* fill object handle */
3283 + (*pobj)->obj_handle = sti->object_num;
3285 + /* fill parent object */
3286 + (*pobj)->parent_object = cpu_to_le32(parent_object);
3287 + (*pobj)->obj_info.parent_object = cpu_to_le32(parent_object);
3289 + /* object full path */
3290 + memset((*pobj)->full_path, 0, sizeof((*pobj)->full_path));
3291 + snprintf((*pobj)->full_path, sizeof((*pobj)->full_path),
3292 + "%s/%s", folder_name, (*pobj)->filename);
3294 + VDBG(sti, "full_path: %s, obj_handle: 0x%08x, "
3295 + "parent_object: 0x%08x\n",
3296 + (*pobj)->full_path, (*pobj)->obj_handle,
3299 + /* get file statistics info */
3300 + rc = vfs_stat((char __user *)(*pobj)->full_path, &stat);
3302 + ERROR(sti, "vfs_stat error: %d\n", rc);
3306 + /* fill remained ObjectInfo Dataset */
3307 + if (stat.mode & S_IWUSR)
3308 + (*pobj)->obj_info.protection_status =
3309 + cpu_to_le16(PIMA15740_OBJECT_NO_PROTECTION);
3311 + (*pobj)->obj_info.protection_status =
3312 + cpu_to_le16(PIMA15740_OBJECT_READ_ONLY);
3314 + (*pobj)->obj_info.object_compressed_size =
3315 + cpu_to_le32((u32)stat.size);
3317 + /* add to object list */
3318 + list_add_tail(&(*pobj)->list, &sti->obj_list);
3320 + if ((*pobj)->is_dir && recursive)
3321 + list_objects(sti, (*pobj)->full_path, *pobj, true);
3327 + /* free pre-allocated objects array */
3330 + if (strcmp(folder_name, sti->root_path))
3331 + filp_close(filp, current->files);
3333 + VDBG(sti, "<--- %s()\n", __func__);
3338 +static int do_open_session(struct sti_dev *sti)
3340 + struct sti_object *obj;
3343 + VDBG(sti, "---> %s()\n", __func__);
3345 + if (sti->session_open) {
3346 + sti->response_code = PIMA15740_RES_SESSION_ALREADY_OPEN;
3350 + sti->session_id = sti->ops_params[0];
3351 + VDBG(sti, "session_id: 0x%08x\n", sti->session_id);
3352 + if (sti->session_id) {
3353 + sti->response_code = PIMA15740_RES_OK;
3354 + sti->session_open = 1;
3356 + sti->response_code = PIMA15740_RES_INVALID_PARAMETER;
3357 + sti->session_open = 0;
3361 + /* reset total object number */
3362 + sti->object_num = 0;
3364 + /* root object init */
3365 + filename_len = strlen(sti->root_filp->f_dentry->d_name.name) + 1;
3366 + VDBG(sti, "root object: %s\n", sti->root_path);
3367 + VDBG(sti, "filename_len: %u\n", filename_len);
3368 + obj = kzalloc(sizeof(*obj), GFP_KERNEL);
3370 + sti->response_code = PIMA15740_RES_DEVICE_BUSY;
3374 + spin_lock_irq(&sti->lock);
3376 + obj->obj_handle = 0;
3377 + obj->parent_object = 0;
3378 + obj->storage_id = STORAGE_ID;
3380 + obj->send_valid = 0;
3381 + obj->obj_info_size = sizeof(struct pima15740_object_info);
3383 + /* root object filename */
3384 + memset(obj->filename, 0, sizeof(obj->filename));
3385 + strncpy(obj->filename, sti->root_filp->f_dentry->d_name.name,
3386 + sizeof(obj->filename));
3387 + VDBG(sti, "root object filename: %s\n", obj->filename);
3389 + /* root object full path */
3390 + memset(obj->full_path, 0, sizeof(obj->full_path));
3391 + strncpy(obj->full_path, sti->root_path, sizeof(obj->full_path));
3392 + VDBG(sti, "root object full path: %s\n", obj->full_path);
3394 + /* add to object list */
3395 + list_add_tail(&obj->list, &sti->obj_list);
3397 + spin_unlock_irq(&sti->lock);
3399 + /* send response */
3400 + rc = send_response(sti, sti->response_code);
3402 + VDBG(sti, "<--- %s()\n", __func__);
3407 +static int do_close_session(struct sti_dev *sti)
3409 + struct sti_object *obj, *tmp_obj;
3411 + VDBG(sti, "---> %s()\n", __func__);
3413 + if (sti->session_open) {
3414 + sti->response_code = PIMA15740_RES_OK;
3415 + sti->session_open = 0;
3417 + sti->response_code = PIMA15740_RES_SESSION_NOT_OPEN;
3421 + spin_lock_irq(&sti->lock);
3423 + /* release object list */
3424 + list_for_each_entry_safe(obj, tmp_obj, &sti->obj_list, list) {
3425 + list_del_init(&obj->list);
3429 + spin_unlock_irq(&sti->lock);
3431 + DBG(sti, "release object list\n");
3433 + /* send response */
3434 + rc = send_response(sti, sti->response_code);
3436 + VDBG(sti, "<--- %s()\n", __func__);
3441 +static int do_get_storage_ids(struct sti_dev *sti, struct sti_buffhd *bh)
3446 + VDBG(sti, "---> %s()\n", __func__);
3448 + if (!sti->session_open) {
3449 + sti->response_code = PIMA15740_RES_SESSION_NOT_OPEN;
3453 + sti->storage_id = cpu_to_le32(STORAGE_ID);
3454 + DBG(sti, "storage_id: 0x%08x\n", sti->storage_id);
3456 + /* 4 bytes array number and 4 bytes storage id */
3458 + fill_data_container(bh, sti, PIMA15740_CONTAINER_LEN + size);
3460 + /* support one storage id */
3462 + memcpy(bh->buf + PIMA15740_CONTAINER_LEN, &i, 4);
3463 + memcpy(bh->buf + PIMA15740_CONTAINER_LEN + 4, &sti->storage_id, 4);
3465 + bh->inreq->length = PIMA15740_CONTAINER_LEN + size;
3466 + bh->state = BUF_STATE_FULL;
3467 + start_transfer(sti, sti->bulk_in, bh->inreq,
3468 + &bh->inreq_busy, &bh->state);
3469 + sti->next_buffhd_to_fill = bh->next;
3471 + sti->response_code = PIMA15740_RES_OK;
3473 + /* send response */
3474 + rc = send_response(sti, sti->response_code);
3476 + VDBG(sti, "<--- %s()\n", __func__);
3481 +static int do_get_storage_info(struct sti_dev *sti, struct sti_buffhd *bh)
3485 + u64 sbytes_max, sbytes_free;
3486 + struct kstatfs sbuf;
3488 + VDBG(sti, "---> %s()\n", __func__);
3490 + if (!sti->session_open) {
3491 + sti->response_code = PIMA15740_RES_SESSION_NOT_OPEN;
3496 + storage_id = sti->ops_params[0];
3497 + if (storage_id != sti->storage_id) {
3498 + WARNING(sti, "invalid storage id: 0x%08x\n", storage_id);
3499 + sti->response_code = PIMA15740_RES_INVALID_STORAGE_ID;
3503 + /* get filesystem statistics info */
3504 + rc = vfs_statfs(sti->root_filp->f_dentry, &sbuf);
3506 + sti->response_code = PIMA15740_RES_ACCESS_DENIED;
3510 + /* fill remained items in StorageInfo Dataset */
3511 + sbytes_max = (u64) sbuf.f_bsize * sbuf.f_blocks;
3512 + sbytes_free = (u64) sbuf.f_bsize * sbuf.f_bfree;
3513 + sti_storage_info.max_capacity = cpu_to_le64(sbytes_max);
3514 + sti_storage_info.free_space_in_bytes = cpu_to_le64(sbytes_free);
3515 + sti_storage_info.free_space_in_images = cpu_to_le32((u32)~0);
3516 + str_to_uni16(storage_desc, sti_storage_info.storage_desc);
3518 + /* dump StorageInfo Dataset */
3519 + dump_storage_info(sti);
3521 + memcpy(bh->buf + PIMA15740_CONTAINER_LEN, &sti_storage_info,
3522 + sizeof(sti_storage_info));
3524 + size = PIMA15740_CONTAINER_LEN + sizeof(sti_storage_info);
3525 + fill_data_container(bh, sti, size);
3527 + bh->inreq->length = size;
3528 + bh->state = BUF_STATE_FULL;
3529 + start_transfer(sti, sti->bulk_in, bh->inreq,
3530 + &bh->inreq_busy, &bh->state);
3531 + sti->next_buffhd_to_fill = bh->next;
3533 + sti->response_code = PIMA15740_RES_OK;
3535 + /* send response */
3536 + rc = send_response(sti, sti->response_code);
3538 + VDBG(sti, "<--- %s()\n", __func__);
3543 +static int do_get_num_objects(struct sti_dev *sti, struct sti_buffhd *bh)
3547 + VDBG(sti, "---> %s()\n", __func__);
3549 + if (!sti->session_open) {
3550 + sti->response_code = PIMA15740_RES_SESSION_NOT_OPEN;
3554 + for (i = 0; i < PARAM_NUM_MAX; i++)
3555 + VDBG(sti, "parameter[%u]: 0x%08x\n",
3556 + i + 1, sti->ops_params[i]);
3558 + if (!backing_folder_is_open(sti)) {
3559 + ERROR(sti, "backing folder is not open\n");
3560 + sti->response_code = PIMA15740_RES_STORE_NOT_AVAILABLE;
3564 + DBG(sti, "total object number: %u\n", sti->object_num);
3566 + sti->response_code = PIMA15740_RES_OK;
3568 + /* send response */
3569 + rc = send_params_response(sti, sti->response_code,
3570 + sti->object_num, 0, 0,
3573 + VDBG(sti, "<--- %s()\n", __func__);
3578 +static int do_get_object_handles(struct sti_dev *sti, struct sti_buffhd *bh)
3581 + u32 storage_id, obj_handle;
3582 + u32 new_obj_num, old_obj_num, tmp_obj_num;
3583 + char *cur_path = NULL;
3584 + struct sti_object *obj;
3587 + VDBG(sti, "---> %s()\n", __func__);
3589 + if (!sti->session_open) {
3590 + sti->response_code = PIMA15740_RES_SESSION_NOT_OPEN;
3594 + for (i = 0; i < PARAM_NUM_MAX; i++)
3595 + VDBG(sti, "parameter[%u]: 0x%08x\n",
3596 + i + 1, sti->ops_params[i]);
3598 + if (!backing_folder_is_open(sti)) {
3599 + ERROR(sti, "backing folder is not open\n");
3600 + sti->response_code = PIMA15740_RES_STORE_NOT_AVAILABLE;
3604 + storage_id = sti->ops_params[0];
3605 + obj_handle = sti->ops_params[2];
3606 + old_obj_num = sti->object_num;
3608 + if (storage_id == 0xffffffff) {
3609 + /* list all objects recursive */
3610 + rc = list_objects(sti, sti->root_path, NULL, true);
3611 + new_obj_num = sti->object_num;
3613 + /* list objects of current folder */
3614 + list_for_each_entry(obj, &sti->obj_list, list) {
3615 + if (obj->obj_handle == obj_handle)
3619 + if (obj_handle == 0xffffffff)
3620 + cur_path = sti->root_path;
3622 + cur_path = obj->full_path;
3623 + VDBG(sti, "current path: %s\n", cur_path);
3626 + rc = list_objects(sti, cur_path, obj, false);
3628 + sti->response_code = PIMA15740_RES_DEVICE_BUSY;
3632 + new_obj_num = sti->sub_object_num;
3636 + sti->response_code = PIMA15740_RES_DEVICE_BUSY;
3640 + /* 4 bytes array number plus object handles size */
3641 + size = 4 + new_obj_num * 4;
3642 + VDBG(sti, "object number: %u, payload size: %u\n",
3643 + new_obj_num, size);
3644 + fill_data_container(bh, sti, PIMA15740_CONTAINER_LEN + size);
3646 + /* fill object handles array */
3647 + memcpy(bh->buf + PIMA15740_CONTAINER_LEN, &new_obj_num, 4);
3648 + for (i = 1; i <= new_obj_num; i++) {
3649 + tmp_obj_num = old_obj_num + i;
3650 + memcpy(bh->buf + PIMA15740_CONTAINER_LEN + i * 4,
3654 + bh->inreq->length = PIMA15740_CONTAINER_LEN + size;
3655 + bh->state = BUF_STATE_FULL;
3656 + start_transfer(sti, sti->bulk_in, bh->inreq,
3657 + &bh->inreq_busy, &bh->state);
3658 + sti->next_buffhd_to_fill = bh->next;
3660 + sti->response_code = PIMA15740_RES_OK;
3662 + /* send response */
3663 + rc = send_response(sti, sti->response_code);
3665 + VDBG(sti, "<--- %s()\n", __func__);
3670 +static int do_get_object_info(struct sti_dev *sti, struct sti_buffhd *bh)
3674 + struct sti_object *obj;
3676 + VDBG(sti, "---> %s()\n", __func__);
3678 + if (!sti->session_open) {
3679 + sti->response_code = PIMA15740_RES_SESSION_NOT_OPEN;
3683 + obj_handle = sti->ops_params[0];
3684 + if (obj_handle == 0 || obj_handle > sti->object_num) {
3685 + WARNING(sti, "invalid object handle: 0x%08x\n", obj_handle);
3686 + sti->response_code = PIMA15740_RES_INVALID_OBJECT_HANDLE;
3690 + spin_lock_irq(&sti->lock);
3692 + /* find the object */
3693 + list_for_each_entry(obj, &sti->obj_list, list) {
3694 + if (obj->obj_handle == obj_handle)
3698 + memcpy(bh->buf + PIMA15740_CONTAINER_LEN, &obj->obj_info,
3699 + obj->obj_info_size);
3700 + size = PIMA15740_CONTAINER_LEN + obj->obj_info_size;
3701 + fill_data_container(bh, sti, size);
3703 + bh->inreq->length = size;
3704 + bh->state = BUF_STATE_FULL;
3706 + spin_unlock_irq(&sti->lock);
3708 + start_transfer(sti, sti->bulk_in, bh->inreq,
3709 + &bh->inreq_busy, &bh->state);
3710 + sti->next_buffhd_to_fill = bh->next;
3712 + DBG(sti, "get object info: %s\n", obj->full_path);
3713 + VDBG(sti, "obj_handle: 0x%08x\n", obj->obj_handle);
3715 + /* dump ObjectInfo Dataset */
3716 + dump_object_info(sti, obj);
3718 + sti->response_code = PIMA15740_RES_OK;
3720 + /* send response */
3721 + rc = send_response(sti, sti->response_code);
3723 + VDBG(sti, "<--- %s()\n", __func__);
3728 +static int do_get_object(struct sti_dev *sti, struct sti_buffhd *bh)
3731 + loff_t file_size, file_offset, file_offset_tmp;
3732 + unsigned int amount_left, amount;
3734 + struct sti_object *obj;
3735 + struct file *filp = NULL;
3736 + struct inode *inode = NULL;
3739 + VDBG(sti, "---> %s()\n", __func__);
3741 + if (!sti->session_open) {
3742 + sti->response_code = PIMA15740_RES_SESSION_NOT_OPEN;
3746 + obj_handle = sti->ops_params[0];
3747 + if (obj_handle == 0 || obj_handle > sti->object_num) {
3748 + WARNING(sti, "invalid object handle: 0x%08x\n", obj_handle);
3749 + sti->response_code = PIMA15740_RES_INVALID_OBJECT_HANDLE;
3753 + spin_lock_irq(&sti->lock);
3755 + /* find the object */
3756 + list_for_each_entry(obj, &sti->obj_list, list) {
3757 + if (obj->obj_handle == obj_handle)
3761 + spin_unlock_irq(&sti->lock);
3763 + /* open object file */
3764 + filp = filp_open(obj->full_path, O_RDONLY | O_LARGEFILE, 0);
3765 + if (IS_ERR(filp)) {
3766 + ERROR(sti, "unable to open file: %s. Err = %d\n",
3767 + obj->full_path, (int) PTR_ERR(filp));
3768 + sti->response_code = PIMA15740_RES_STORE_NOT_AVAILABLE;
3772 + /* figure out the size and read the remaining amount */
3773 + inode = filp->f_dentry->d_inode;
3774 + file_size = i_size_read(inode->i_mapping->host);
3775 + VDBG(sti, "object file size: %llu\n", (unsigned long long) file_size);
3776 + if (unlikely(file_size == 0)) {
3777 + sti->response_code = PIMA15740_RES_STORE_NOT_AVAILABLE;
3781 + DBG(sti, "get object: %s\n", obj->full_path);
3784 + amount_left = file_size;
3786 + while (amount_left > 0) {
3787 + bh = sti->next_buffhd_to_fill;
3788 + while (bh->state != BUF_STATE_EMPTY) {
3789 + rc = sleep_thread(sti);
3791 + filp_close(filp, current->files);
3796 + /* don't read more than the buffer size */
3797 + if (file_offset == 0) {
3798 + fill_data_container(bh, sti,
3799 + file_size + PIMA15740_CONTAINER_LEN);
3800 + buf = (char __user *) bh->buf +
3801 + PIMA15740_CONTAINER_LEN;
3802 + amount = min((unsigned int) amount_left,
3803 + mod_data.buflen - PIMA15740_CONTAINER_LEN);
3805 + buf = (char __user *) bh->buf;
3806 + amount = min((unsigned int) amount_left,
3810 + /* no more left to read */
3814 + /* perform the read */
3815 + file_offset_tmp = file_offset;
3816 + nread = vfs_read(filp, buf, amount, &file_offset_tmp);
3817 + VDBG(sti, "file read %u @ %llu -> %d\n", amount,
3818 + (unsigned long long) file_offset,
3821 + if (signal_pending(current)) {
3822 + filp_close(filp, current->files);
3827 + WARNING(sti, "error in file read: %d\n",
3830 + } else if (nread < amount) {
3831 + WARNING(sti, "partial file read: %d/%u\n",
3832 + (int) nread, amount);
3833 + /* round down to a block */
3834 + nread -= (nread & 511);
3838 + * PIMA 15740 generic container head resides in
3839 + * first data block payload
3841 + if (file_offset == 0)
3842 + bh->inreq->length = nread + PIMA15740_CONTAINER_LEN;
3844 + bh->inreq->length = nread;
3845 + bh->state = BUF_STATE_FULL;
3846 + bh->inreq->zero = 0;
3848 + file_offset += nread;
3849 + amount_left -= nread;
3851 + /* send this buffer and go read some more */
3852 + start_transfer(sti, sti->bulk_in, bh->inreq,
3853 + &bh->inreq_busy, &bh->state);
3854 + sti->next_buffhd_to_fill = bh->next;
3857 + sti->response_code = PIMA15740_RES_OK;
3859 + filp_close(filp, current->files);
3861 + /* send response */
3862 + rc = send_response(sti, sti->response_code);
3864 + VDBG(sti, "<--- %s()\n", __func__);
3869 +static int do_delete_object(struct sti_dev *sti, struct sti_buffhd *bh)
3872 + struct sti_object *obj, *tmp_obj;
3873 + struct nameidata nd;
3876 + VDBG(sti, "---> %s()\n", __func__);
3878 + if (!sti->session_open) {
3879 + sti->response_code = PIMA15740_RES_SESSION_NOT_OPEN;
3883 + for (i = 0; i < PARAM_NUM_MAX; i++)
3884 + VDBG(sti, "parameter[%u]: 0x%08x\n",
3885 + i + 1, sti->ops_params[i]);
3887 + obj_handle = sti->ops_params[0];
3888 + if (obj_handle == 0 || obj_handle > sti->object_num) {
3889 + WARNING(sti, "invalid object handle: 0x%08x\n", obj_handle);
3890 + sti->response_code = PIMA15740_RES_INVALID_OBJECT_HANDLE;
3894 + spin_lock_irq(&sti->lock);
3896 + /* find the object */
3897 + list_for_each_entry_safe(obj, tmp_obj, &sti->obj_list, list) {
3898 + if (obj->obj_handle == obj_handle) {
3899 + list_del_init(&obj->list);
3905 + spin_unlock_irq(&sti->lock);
3907 + /* lookup the object file */
3908 + rc = path_lookup(obj->full_path, 0, &nd);
3910 + ERROR(sti, "invalid object file path: %s\n", obj->full_path);
3911 + sti->response_code = PIMA15740_RES_STORE_NOT_AVAILABLE;
3915 + /* unlink the file */
3916 + rc = vfs_unlink(nd.path.dentry->d_parent->d_inode, nd.path.dentry);
3918 + ERROR(sti, "can't delete object\n");
3919 + sti->response_code = PIMA15740_RES_DEVICE_BUSY;
3923 + DBG(sti, "delete object: %s\n", obj->full_path);
3925 + sti->response_code = PIMA15740_RES_OK;
3927 + /* send response */
3928 + rc = send_response(sti, sti->response_code);
3930 + VDBG(sti, "<--- %s()\n", __func__);
3935 +static int do_send_object_info(struct sti_dev *sti, struct sti_buffhd *bh)
3939 + u32 parent_object = 0xffffffff;
3940 + unsigned int offset;
3941 + struct sti_object *obj, *parent_obj;
3945 + VDBG(sti, "---> %s()\n", __func__);
3947 + if (!sti->session_open) {
3948 + sti->response_code = PIMA15740_RES_SESSION_NOT_OPEN;
3952 + for (i = 0; i < PARAM_NUM_MAX; i++)
3953 + VDBG(sti, "parameter[%u]: 0x%08x\n",
3954 + i + 1, sti->ops_params[i]);
3956 + /* destination storage id */
3957 + storage_id = sti->ops_params[0];
3958 + if (storage_id != STORAGE_ID) {
3959 + WARNING(sti, "invalid storage id: 0x%08x\n", storage_id);
3960 + sti->response_code = PIMA15740_RES_INVALID_STORAGE_ID;
3964 + /* parent object handle where object should be placed */
3965 + parent_object = sti->ops_params[1];
3967 + /* if root directory, parent object is 0xffffffff */
3968 + if (parent_object == 0 || (parent_object > sti->object_num
3969 + && parent_object != 0xffffffff)) {
3970 + WARNING(sti, "invalid parent handle: 0x%08x\n",
3972 + sti->response_code = PIMA15740_RES_INVALID_PARENT_OBJECT;
3976 + /* queue a request to read ObjectInfo Dataset */
3977 + set_bulk_out_req_length(sti, bh, 512);
3978 + bh->outreq->short_not_ok = 1;
3979 + start_transfer(sti, sti->bulk_out, bh->outreq,
3980 + &bh->outreq_busy, &bh->state);
3982 + /* wait for the ObjectInfo Dataset to arrive */
3983 + while (bh->state != BUF_STATE_FULL) {
3984 + rc = sleep_thread(sti);
3989 + /* filename strings length */
3990 + offset = offsetof(struct pima15740_object_info, obj_strings[0]);
3991 + filename_len = *(u8 *)(bh->outreq->buf + PIMA15740_CONTAINER_LEN
3993 + VDBG(sti, "filename_len: %u\n", filename_len);
3995 + /* sti_object size */
3996 + obj_size = sizeof(*obj) + 2 * filename_len + 4;
3997 + VDBG(sti, "obj_size: %u\n", obj_size);
3998 + obj = kzalloc(obj_size, GFP_KERNEL);
4000 + sti->response_code = PIMA15740_RES_STORE_NOT_AVAILABLE;
4004 + spin_lock_irq(&sti->lock);
4006 + /* increase total object number */
4007 + sti->object_num++;
4009 + /* fill sti_object info */
4010 + obj->obj_handle = sti->object_num;
4011 + VDBG(sti, "obj_handle: 0x%08x\n", obj->obj_handle);
4013 + if (parent_object == 0xffffffff)
4014 + obj->parent_object = 0;
4016 + obj->parent_object = parent_object;
4017 + VDBG(sti, "parent_object: 0x%08x\n", obj->parent_object);
4019 + obj->storage_id = storage_id;
4021 + /* mark object ready to send */
4022 + obj->send_valid = 1;
4024 + /* ObjectInfo Dataset size */
4025 + obj->obj_info_size = sizeof(struct pima15740_object_info)
4026 + + 2 * filename_len + 4;
4027 + VDBG(sti, "obj_info_size: %u\n", obj->obj_info_size);
4030 + offset = offsetof(struct pima15740_object_info, obj_strings[1]);
4031 + uni16_to_str(bh->outreq->buf + PIMA15740_CONTAINER_LEN + offset,
4032 + obj->filename, filename_len);
4034 + /* object full path */
4035 + memset(obj->full_path, 0, sizeof(obj->full_path));
4036 + if (parent_object == 0xffffffff) {
4037 + snprintf(obj->full_path, sizeof(obj->full_path), "%s/%s",
4038 + sti->root_path, obj->filename);
4040 + /* find the parent object */
4041 + list_for_each_entry(parent_obj, &sti->obj_list, list) {
4042 + if (parent_obj->obj_handle == parent_object)
4045 + snprintf(obj->full_path, sizeof(obj->full_path), "%s/%s",
4046 + parent_obj->full_path, obj->filename);
4048 + VDBG(sti, "full_path: %s\n", obj->full_path);
4050 + /* fetch ObjectInfo Dataset from buffer */
4051 + memcpy(&obj->obj_info, bh->outreq->buf + PIMA15740_CONTAINER_LEN,
4052 + obj->obj_info_size);
4054 + /* root directory, modify parent object */
4055 + if (parent_object == 0xffffffff)
4056 + obj->obj_info.parent_object = cpu_to_le32(0);
4058 + obj->obj_info.parent_object = parent_object;
4060 + obj->obj_info.storage_id = storage_id;
4062 + /* capture date */
4063 + obj->obj_info.obj_strings[filename_len * 2 + 1] = 0;
4065 + /* modification date */
4066 + obj->obj_info.obj_strings[filename_len * 2 + 2] = 0;
4069 + obj->obj_info.obj_strings[filename_len * 2 + 3] = 0;
4071 + bh->state = BUF_STATE_EMPTY;
4073 + /* add to object list */
4074 + list_add_tail(&obj->list, &sti->obj_list);
4076 + spin_unlock_irq(&sti->lock);
4078 + DBG(sti, "send object info: %s\n", obj->filename);
4080 + /* dump ObjectInfo Dataset */
4081 + dump_object_info(sti, obj);
4083 + /* send response */
4084 + rc = send_params_response(sti, PIMA15740_RES_OK,
4085 + sti->storage_id, parent_object, sti->object_num,
4088 + VDBG(sti, "<--- %s()\n", __func__);
4093 +static int do_send_object(struct sti_dev *sti, struct sti_buffhd *bh)
4096 + int get_some_more;
4097 + u32 amount_left_to_req, amount_left_to_write;
4098 + loff_t file_size, file_offset, file_offset_tmp,
4100 + unsigned int amount;
4102 + struct sti_object *obj;
4103 + struct file *filp = NULL;
4105 + VDBG(sti, "---> %s()\n", __func__);
4107 + spin_lock_irq(&sti->lock);
4109 + /* find the object */
4110 + list_for_each_entry(obj, &sti->obj_list, list) {
4111 + if (obj->send_valid)
4115 + /* mark object already sent */
4116 + obj->send_valid = 0;
4118 + spin_unlock_irq(&sti->lock);
4120 + /* open object file */
4121 + filp = filp_open(obj->full_path, O_CREAT | O_RDWR | O_LARGEFILE, 0666);
4122 + if (IS_ERR(filp)) {
4123 + ERROR(sti, "unable to open file: %s. Err = %d\n",
4124 + obj->full_path, (int) PTR_ERR(filp));
4125 + sti->response_code = PIMA15740_RES_STORE_NOT_AVAILABLE;
4129 + file_size = obj->obj_info.object_compressed_size;
4130 + VDBG(sti, "object file size: %llu\n",
4131 + (unsigned long long) file_size);
4132 + if (unlikely(file_size == 0)) {
4133 + sti->response_code = PIMA15740_RES_STORE_NOT_AVAILABLE;
4137 + DBG(sti, "send object: %s\n", obj->full_path);
4139 + /* carry out the file writes */
4140 + get_some_more = 1;
4141 + file_offset = usb_offset = 0;
4143 + amount_left_to_req = file_size + PIMA15740_CONTAINER_LEN;
4144 + amount_left_to_write = file_size;
4145 + VDBG(sti, "in total: amount_left_to_req: %u\n",
4146 + amount_left_to_req);
4147 + VDBG(sti, "in total: amount_left_to_write: %u\n",
4148 + amount_left_to_write);
4150 + while (amount_left_to_write > 0) {
4151 + bh = sti->next_buffhd_to_fill;
4152 + if (bh->state == BUF_STATE_EMPTY && get_some_more) {
4153 + amount = min(amount_left_to_req, mod_data.buflen);
4154 + amount = min((loff_t) amount, file_size
4155 + + PIMA15740_CONTAINER_LEN - usb_offset);
4156 + VDBG(sti, "usb amount: %u\n", amount);
4158 + /* no left data request to transfer */
4159 + if (amount == 0) {
4160 + get_some_more = 0;
4164 + /* get the next buffer */
4165 + usb_offset += amount;
4166 + amount_left_to_req -= amount;
4168 + if (amount_left_to_req == 0)
4169 + get_some_more = 0;
4171 + /* amount is always divisible by bulk-out
4173 + bh->outreq->length = bh->bulk_out_intended_length =
4175 + bh->outreq->short_not_ok = 1;
4176 + start_transfer(sti, sti->bulk_out, bh->outreq,
4177 + &bh->outreq_busy, &bh->state);
4178 + sti->next_buffhd_to_fill = bh->next;
4182 + /* write the received data to the backing folder */
4183 + bh = sti->next_buffhd_to_drain;
4185 + /* host stopped early */
4186 + if (bh->state == BUF_STATE_EMPTY && !get_some_more) {
4187 + WARNING(sti, "host stops early, bh->state: %d\n",
4189 + sti->response_code = PIMA15740_RES_INCOMPLETE_TRANSFER;
4193 + if (bh->state == BUF_STATE_FULL) {
4195 + sti->next_buffhd_to_drain = bh->next;
4196 + bh->state = BUF_STATE_EMPTY;
4198 + /* something go wrong with the transfer */
4199 + if (bh->outreq->status != 0) {
4200 + sti->response_code =
4201 + PIMA15740_RES_INCOMPLETE_TRANSFER;
4206 + * PIMA 15740 generic container head resides in
4207 + * first data block payload
4209 + if (file_offset == 0) {
4210 + buf = (char __user *) bh->buf +
4211 + PIMA15740_CONTAINER_LEN;
4212 + amount = bh->outreq->actual -
4213 + PIMA15740_CONTAINER_LEN;
4215 + buf = (char __user *) bh->buf;
4216 + amount = bh->outreq->actual;
4218 + amount = min((loff_t) amount,
4219 + file_size - file_offset);
4221 + /* across page boundary, recalculate the length */
4222 + if (amount == 0) {
4223 + INFO(sti, "extra bulk out zlp packets\n");
4224 + usb_offset -= bh->outreq->length;
4225 + amount_left_to_req += bh->outreq->length;
4229 + /* perform the write */
4230 + file_offset_tmp = file_offset;
4231 + nwritten = vfs_write(filp, (char __user *) buf,
4232 + amount, &file_offset_tmp);
4233 + VDBG(sti, "file write %u @ %llu -> %d\n", amount,
4234 + (unsigned long long) file_offset,
4237 + if (signal_pending(current)) {
4238 + filp_close(filp, current->files);
4242 + if (nwritten < 0) {
4243 + VDBG(sti, "error in file write: %d\n",
4246 + } else if (nwritten < amount) {
4247 + VDBG(sti, "partial file write: %d/%u\n",
4248 + (int) nwritten, amount);
4249 + /* round down to a block */
4250 + nwritten -= (nwritten & 511);
4253 + file_offset += nwritten;
4254 + amount_left_to_write -= nwritten;
4256 + VDBG(sti, "file_offset: %llu, "
4257 + "amount_left_to_write: %u\n",
4258 + (unsigned long long) file_offset,
4259 + amount_left_to_write);
4261 + /* error occurred */
4262 + if (nwritten < amount) {
4263 + sti->response_code =
4264 + PIMA15740_RES_INCOMPLETE_TRANSFER;
4270 + /* wait for something to happen */
4271 + rc = sleep_thread(sti);
4273 + filp_close(filp, current->files);
4278 + /* fsync object file */
4279 + vfs_fsync(filp, filp->f_path.dentry, 1);
4281 + sti->response_code = PIMA15740_RES_OK;
4283 + filp_close(filp, current->files);
4285 + /* send response */
4286 + rc = send_response(sti, sti->response_code);
4288 + VDBG(sti, "<--- %s()\n", __func__);
4293 +static int do_copy_object(struct sti_dev *sti, struct sti_buffhd *bh)
4297 + unsigned int old_obj_handle, new_obj_parent_handle;
4298 + unsigned int new_storage_id, amount, amount_left;
4299 + struct sti_object *old_obj = NULL, *new_obj_parent = NULL;
4300 + struct sti_object *new_obj, *tmp_obj;
4301 + char *new_obj_fname;
4302 + struct file *old_fp, *new_fp;
4303 + struct inode *inode = NULL;
4305 + loff_t file_size, file_offset, file_offset_tmp;
4306 + ssize_t nread, nwritten;
4307 + VDBG(sti, "---> %s()\n", __func__);
4309 + if (!sti->session_open) {
4310 + sti->response_code = PIMA15740_RES_SESSION_NOT_OPEN;
4314 + old_obj_handle = sti->ops_params[0];
4315 + new_storage_id = sti->ops_params[1];
4316 + new_obj_parent_handle = sti->ops_params[2];
4318 + if ((old_obj_handle == 0) || (old_obj_handle > sti->object_num)) {
4319 + WARNING(sti, "invalid object handle: %u\n", old_obj_handle);
4320 + sti->response_code = PIMA15740_RES_INVALID_OBJECT_HANDLE;
4324 + if (new_storage_id != sti->storage_id) {
4325 + WARNING(sti, "invalid storage id: %u\n", new_storage_id);
4326 + sti->response_code = PIMA15740_RES_INVALID_STORAGE_ID;
4330 + if (new_obj_parent_handle > sti->object_num
4331 + && new_obj_parent_handle != 0xffffffff) {
4332 + WARNING(sti, "invalid parent object handle: %u\n",
4333 + new_obj_parent_handle);
4334 + sti->response_code = PIMA15740_RES_INVALID_PARENT_OBJECT;
4338 + spin_lock_irq(&sti->lock);
4340 + /* find the old object to be copied */
4342 + list_for_each_entry(tmp_obj, &sti->obj_list, list) {
4343 + if (tmp_obj->obj_handle == old_obj_handle) {
4345 + old_obj = tmp_obj;
4348 + if (tmp_obj->obj_handle == new_obj_parent_handle) {
4350 + new_obj_parent = tmp_obj;
4357 + spin_unlock_irq(&sti->lock);
4359 + if (i != 2 || !old_obj || !new_obj_parent) {
4360 + WARNING(sti, "invalid objects %u or %u\n",
4361 + old_obj_handle, new_obj_parent_handle);
4362 + sti->response_code = PIMA15740_RES_INVALID_PARENT_OBJECT;
4366 + size = strlen(new_obj_parent->full_path) +
4367 + strlen(old_obj->filename) + 2;
4368 + new_obj_fname = kzalloc(size, GFP_KERNEL);
4369 + if (!new_obj_fname) {
4370 + sti->response_code = PIMA15740_RES_DEVICE_BUSY;
4374 + strncpy(new_obj_fname, new_obj_parent->full_path, size);
4375 + strncat(new_obj_fname, "/", size);
4376 + strncat(new_obj_fname, old_obj->filename, size);
4378 + VDBG(sti, "copy object: from [%s] to [%s]\n",
4379 + old_obj->full_path, new_obj_fname);
4381 + old_fp = filp_open(old_obj->full_path, O_RDONLY | O_LARGEFILE, 0);
4382 + if (IS_ERR(old_fp)) {
4383 + ERROR(sti, "unable to open file: %s. Err = %d\n",
4384 + old_obj->full_path, (int) PTR_ERR(old_fp));
4385 + sti->response_code = PIMA15740_RES_DEVICE_BUSY;
4390 + new_fp = filp_open(new_obj_fname, O_CREAT | O_RDWR | O_LARGEFILE, 0666);
4391 + if (IS_ERR(new_fp)) {
4392 + ERROR(sti, "unable to create file: %s. Err = %d\n",
4393 + new_obj_fname, (int) PTR_ERR(new_fp));
4394 + sti->response_code = PIMA15740_RES_DEVICE_BUSY;
4399 + buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
4401 + sti->response_code = PIMA15740_RES_OPERATION_NOT_SUPPORTED;
4406 + inode = old_fp->f_dentry->d_inode;
4407 + file_size = i_size_read(inode->i_mapping->host);
4408 + VDBG(sti, "object file size: %llu\n", (unsigned long long) file_size);
4410 + if (unlikely(file_size == 0)) {
4411 + sti->response_code = PIMA15740_RES_STORE_NOT_AVAILABLE;
4417 + amount_left = file_size;
4419 + while (amount_left > 0) {
4420 + amount = min(amount_left, (unsigned int) PAGE_SIZE);
4424 + file_offset_tmp = file_offset;
4425 + nread = vfs_read(old_fp, buf, amount, &file_offset_tmp);
4427 + if (signal_pending(current)) {
4433 + DBG(sti, "error in file read: %d\n",
4436 + } else if (nread < amount) {
4437 + DBG(sti, "partial file read: %d/%u\n",
4438 + (int) nread, amount);
4439 + /* round down to a block */
4440 + nread -= (nread & 511);
4443 + amount = min(amount, (unsigned int) nread);
4444 + file_offset_tmp = file_offset;
4445 + nwritten = vfs_write(new_fp, buf, amount, &file_offset_tmp);
4447 + if (signal_pending(current)) {
4452 + if (nwritten < 0) {
4453 + VDBG(sti, "error in file write: %d\n",
4456 + } else if (nwritten < amount) {
4457 + VDBG(sti, "partial file write: %d/%u\n",
4458 + (int) nwritten, amount);
4459 + /* round down to a block */
4460 + nwritten -= (nwritten & 511);
4463 + amount = min(amount, (unsigned int) nwritten);
4464 + file_offset += amount;
4465 + amount_left -= amount;
4468 + size = sizeof(*old_obj);
4469 + new_obj = kzalloc(size, GFP_KERNEL);
4475 + spin_lock_irq(&sti->lock);
4477 + sti->object_num++;
4479 + /* change obj_handle */
4480 + new_obj->obj_handle = sti->object_num;
4482 + /* change parent object */
4483 + if (new_obj_parent_handle == 0xffffffff)
4484 + new_obj->parent_object = 0;
4486 + new_obj->parent_object = new_obj_parent_handle;
4488 + new_obj->storage_id = old_obj->storage_id;
4489 + new_obj->is_dir = old_obj->is_dir;
4490 + new_obj->send_valid = old_obj->send_valid;
4491 + new_obj->obj_info_size = old_obj->obj_info_size;
4492 + strncpy(new_obj->filename, old_obj->filename,
4493 + sizeof(new_obj->filename));
4495 + /* change full path name */
4496 + strncpy(new_obj->full_path, new_obj_fname, sizeof(new_obj->full_path));
4498 + /* copy object_info */
4499 + memcpy(&new_obj->obj_info, &old_obj->obj_info, old_obj->obj_info_size);
4501 + /* fill parent_object in object_info */
4502 + new_obj->obj_info.parent_object = new_obj->parent_object;
4504 + /* add to object list */
4505 + list_add_tail(&new_obj->list, &sti->obj_list);
4507 + spin_unlock_irq(&sti->lock);
4509 + sti->response_code = PIMA15740_RES_OK;
4513 + filp_close(new_fp, current->files);
4515 + filp_close(old_fp, current->files);
4517 + kfree(new_obj_fname);
4519 + /* send response */
4520 + rc = send_params_response(sti, sti->response_code,
4521 + sti->object_num, 0, 0,
4524 + VDBG(sti, "<--- %s()\n", __func__);
4529 +static int do_move_object(struct sti_dev *sti, struct sti_buffhd *bh)
4533 + unsigned int old_obj_handle, new_obj_parent_handle;
4534 + unsigned int new_storage_id;
4535 + char *new_obj_fname;
4536 + struct file *old_fp, *new_fp;
4537 + struct inode *old_dir, *new_dir;
4538 + struct dentry *old_dentry, *new_dentry;
4539 + struct sti_object *old_obj = NULL;
4540 + struct sti_object *new_obj = NULL;
4541 + struct sti_object *new_obj_parent = NULL;
4542 + struct sti_object *tmp_obj = NULL;
4543 + VDBG(sti, "---> %s()\n", __func__);
4545 + if (!sti->session_open) {
4546 + sti->response_code = PIMA15740_RES_SESSION_NOT_OPEN;
4550 + old_obj_handle = sti->ops_params[0];
4551 + new_storage_id = sti->ops_params[1];
4552 + new_obj_parent_handle = sti->ops_params[2];
4554 + if ((old_obj_handle == 0) || (old_obj_handle > sti->object_num)) {
4555 + WARNING(sti, "invalid object handle: %u\n", old_obj_handle);
4556 + sti->response_code = PIMA15740_RES_INVALID_OBJECT_HANDLE;
4560 + if (new_storage_id != sti->storage_id) {
4561 + WARNING(sti, "invalid storage id: %u\n", new_storage_id);
4562 + sti->response_code = PIMA15740_RES_INVALID_STORAGE_ID;
4566 + if (new_obj_parent_handle > sti->object_num
4567 + && new_obj_parent_handle != 0xffffffff) {
4568 + WARNING(sti, "invalid parent object handle: %u\n",
4569 + new_obj_parent_handle);
4570 + sti->response_code = PIMA15740_RES_INVALID_PARENT_OBJECT;
4574 + spin_lock_irq(&sti->lock);
4576 + /* find the old object to be moved */
4578 + list_for_each_entry(tmp_obj, &sti->obj_list, list) {
4579 + if (tmp_obj->obj_handle == old_obj_handle) {
4581 + old_obj = tmp_obj;
4584 + if (tmp_obj->obj_handle == new_obj_parent_handle) {
4586 + new_obj_parent = tmp_obj;
4593 + spin_unlock_irq(&sti->lock);
4595 + if (i != 2 || !old_obj || !new_obj_parent) {
4596 + WARNING(sti, "invalid objects %u or %u\n",
4597 + old_obj_handle, new_obj_parent_handle);
4598 + sti->response_code = PIMA15740_RES_INVALID_PARENT_OBJECT;
4602 + size = strlen(new_obj_parent->full_path) +
4603 + strlen(old_obj->filename) + 2;
4604 + new_obj_fname = kzalloc(size, GFP_KERNEL);
4605 + if (!new_obj_fname) {
4606 + sti->response_code = PIMA15740_RES_DEVICE_BUSY;
4610 + strncpy(new_obj_fname, new_obj_parent->full_path, size);
4611 + strncat(new_obj_fname, "/", size);
4612 + strncat(new_obj_fname, old_obj->filename, size);
4614 + VDBG(sti, "move object: from [%s] to [%s]\n",
4615 + old_obj->full_path, new_obj_fname);
4617 + old_fp = filp_open(old_obj->full_path, O_RDONLY | O_LARGEFILE, 0);
4618 + if (IS_ERR(old_fp)) {
4619 + ERROR(sti, "unable to open file: %s. Err = %d\n",
4620 + old_obj->full_path, (int) PTR_ERR(old_fp));
4621 + sti->response_code = PIMA15740_RES_DEVICE_BUSY;
4626 + new_fp = filp_open(new_obj_fname, O_CREAT | O_RDWR | O_LARGEFILE, 0666);
4627 + if (IS_ERR(new_fp)) {
4628 + ERROR(sti, "unable to create file: %s. Err = %d\n",
4629 + new_obj_fname, (int) PTR_ERR(new_fp));
4630 + sti->response_code = PIMA15740_RES_DEVICE_BUSY;
4635 + old_dir = old_fp->f_dentry->d_parent->d_inode;
4636 + new_dir = new_fp->f_dentry->d_parent->d_inode;
4637 + old_dentry = old_fp->f_dentry;
4638 + new_dentry = new_fp->f_dentry;
4640 + rc = vfs_rename(old_dir, old_dentry, new_dir, new_dentry);
4643 + sti->response_code = PIMA15740_RES_OPERATION_NOT_SUPPORTED;
4646 + sti->response_code = PIMA15740_RES_OK;
4648 + size = sizeof(*old_obj);
4649 + new_obj = kzalloc(size, GFP_KERNEL);
4655 + spin_lock_irq(&sti->lock);
4657 + /* change parent object */
4658 + if (new_obj_parent_handle == 0xffffffff)
4659 + new_obj->parent_object = 0;
4661 + new_obj->parent_object = new_obj_parent_handle;
4663 + new_obj->obj_handle = old_obj->obj_handle;
4664 + new_obj->storage_id = old_obj->storage_id;
4665 + new_obj->is_dir = old_obj->is_dir;
4666 + new_obj->send_valid = old_obj->send_valid;
4667 + new_obj->obj_info_size = old_obj->obj_info_size;
4668 + strncpy(new_obj->filename, old_obj->filename,
4669 + sizeof(new_obj->filename));
4671 + /* change full path name */
4672 + strncpy(new_obj->full_path, new_obj_fname, sizeof(new_obj->full_path));
4674 + /* copy object_info */
4675 + memcpy(&new_obj->obj_info, &old_obj->obj_info, old_obj->obj_info_size);
4677 + /* fill parent_object in object_info */
4678 + new_obj->obj_info.parent_object = new_obj->parent_object;
4680 + /* add to object list */
4681 + list_add_tail(&new_obj->list, &sti->obj_list);
4683 + /* remove from object list */
4684 + list_del_init(&old_obj->list);
4686 + spin_unlock_irq(&sti->lock);
4690 + filp_close(new_fp, current->files);
4692 + filp_close(old_fp, current->files);
4694 + kfree(new_obj_fname);
4696 + /* send response */
4697 + rc = send_response(sti, sti->response_code);
4699 + VDBG(sti, "<--- %s()\n", __func__);
4704 +/* TODO: PIMA 15740 Event handling via interrupt endpoint */
4705 +static int send_status(struct sti_dev *sti)
4707 + VDBG(sti, "---> %s()\n", __func__);
4708 + VDBG(sti, "<--- %s()\n", __func__);
4713 +/*-------------------------------------------------------------------------*/
4715 +/* handle supported PIMA 15740 operations */
4716 +static int do_still_image_command(struct sti_dev *sti)
4718 + struct sti_buffhd *bh;
4720 + int reply = -EINVAL;
4721 + VDBG(sti, "---> %s()\n", __func__);
4725 + if (!backing_folder_is_open(sti)) {
4726 + ERROR(sti, "backing folder is not open\n");
4730 + /* wait for the next buffer to become available for data or status */
4731 + bh = sti->next_buffhd_to_drain = sti->next_buffhd_to_fill;
4732 + while (bh->state != BUF_STATE_EMPTY) {
4733 + rc = sleep_thread(sti);
4738 + down_read(&sti->filesem);
4739 + switch (sti->code) {
4741 + case PIMA15740_OP_GET_DEVICE_INFO:
4742 + DBG(sti, "PIMA15740 OPS: get device info\n");
4743 + reply = do_get_device_info(sti, bh);
4746 + case PIMA15740_OP_OPEN_SESSION:
4747 + DBG(sti, "PIMA15740 OPS: open session\n");
4748 + reply = do_open_session(sti);
4751 + case PIMA15740_OP_CLOSE_SESSION:
4752 + DBG(sti, "PIMA15740 OPS: close session\n");
4753 + reply = do_close_session(sti);
4756 + case PIMA15740_OP_GET_STORAGE_IDS:
4757 + DBG(sti, "PIMA15740 OPS: get storage ids\n");
4758 + reply = do_get_storage_ids(sti, bh);
4761 + case PIMA15740_OP_GET_STORAGE_INFO:
4762 + DBG(sti, "PIMA15740 OPS: get storage info\n");
4763 + reply = do_get_storage_info(sti, bh);
4766 + case PIMA15740_OP_GET_NUM_OBJECTS:
4767 + DBG(sti, "PIMA15740 OPS: get num objects\n");
4768 + reply = do_get_num_objects(sti, bh);
4771 + case PIMA15740_OP_GET_OBJECT_HANDLES:
4772 + DBG(sti, "PIMA15740 OPS: get object handles\n");
4773 + reply = do_get_object_handles(sti, bh);
4776 + case PIMA15740_OP_GET_OBJECT_INFO:
4777 + DBG(sti, "PIMA15740 OPS: get object info\n");
4778 + reply = do_get_object_info(sti, bh);
4781 + case PIMA15740_OP_GET_OBJECT:
4782 + DBG(sti, "PIMA15740 OPS: get object\n");
4783 + reply = do_get_object(sti, bh);
4786 + case PIMA15740_OP_DELETE_OBJECT:
4787 + DBG(sti, "PIMA15740 OPS: delete object\n");
4788 + reply = do_delete_object(sti, bh);
4791 + case PIMA15740_OP_SEND_OBJECT_INFO:
4792 + DBG(sti, "PIMA15740 OPS: send object info\n");
4793 + reply = do_send_object_info(sti, bh);
4796 + case PIMA15740_OP_SEND_OBJECT:
4797 + DBG(sti, "PIMA15740 OPS: send object\n");
4798 + reply = do_send_object(sti, bh);
4801 + case PIMA15740_OP_COPY_OBJECT:
4802 + DBG(sti, "PIMA15740 OPS: copy object\n");
4803 + reply = do_copy_object(sti, bh);
4806 + case PIMA15740_OP_MOVE_OBJECT:
4807 + DBG(sti, "PIMA15740 OPS: move object\n");
4808 + reply = do_move_object(sti, bh);
4812 + WARNING(sti, "unknown PIMA15740 OPS 0x%04x\n", sti->code);
4815 + up_read(&sti->filesem);
4817 + if (reply == -EINTR || signal_pending(current))
4820 + if (reply == -EINVAL)
4823 + VDBG(sti, "<--- %s()\n", __func__);
4828 +/*-------------------------------------------------------------------------*/
4830 +/* received PIMA 15740 Command Blocks */
4831 +static int received_cb(struct sti_dev *sti, struct sti_buffhd *bh)
4833 + struct usb_request *req = bh->outreq;
4834 + struct pima15740_container *cb = req->buf;
4836 + VDBG(sti, "---> %s()\n", __func__);
4838 + /* this is not a real packet */
4842 + /* save the command for later */
4843 + sti->container_len = cb->container_len;
4844 + sti->container_type = cb->container_type;
4845 + sti->code = cb->code;
4846 + sti->transaction_id = cb->transaction_id;
4848 + /* get Command Block Parameters 1..N */
4849 + n = sti->container_len - PIMA15740_CONTAINER_LEN;
4851 + memcpy(sti->ops_params, cb + 1, n);
4853 + VDBG(sti, "Command Block: len=%u, type=0x%04x, "
4854 + "code=0x%04x, trans_id=0x%08x\n",
4855 + sti->container_len, sti->container_type,
4856 + sti->code, sti->transaction_id);
4858 + VDBG(sti, "<--- %s()\n", __func__);
4863 +static int get_next_command(struct sti_dev *sti)
4865 + struct sti_buffhd *bh;
4867 + VDBG(sti, "---> %s()\n", __func__);
4869 + /* wait for the next buffer to become available */
4870 + bh = sti->next_buffhd_to_fill;
4871 + while (bh->state != BUF_STATE_EMPTY) {
4872 + rc = sleep_thread(sti);
4877 + /* queue a request to read a Bulk-only Command Block */
4878 + set_bulk_out_req_length(sti, bh, 512);
4879 + bh->outreq->short_not_ok = 1;
4880 + start_transfer(sti, sti->bulk_out, bh->outreq,
4881 + &bh->outreq_busy, &bh->state);
4883 + /* we will drain the buffer in software, which means we
4884 + * can reuse it for the next filling. No need to advance
4885 + * next_buffhd_to_fill. */
4887 + /* wait for the Command Block to arrive */
4888 + while (bh->state != BUF_STATE_FULL) {
4889 + rc = sleep_thread(sti);
4894 + rc = received_cb(sti, bh);
4895 + bh->state = BUF_STATE_EMPTY;
4897 + VDBG(sti, "<--- %s()\n", __func__);
4902 +/*-------------------------------------------------------------------------*/
4904 +static int enable_endpoint(struct sti_dev *sti, struct usb_ep *ep,
4905 + const struct usb_endpoint_descriptor *d)
4908 + VDBG(sti, "---> %s()\n", __func__);
4910 + ep->driver_data = sti;
4911 + rc = usb_ep_enable(ep, d);
4913 + ERROR(sti, "can't enable %s, result %d\n", ep->name, rc);
4915 + VDBG(sti, "<--- %s()\n", __func__);
4919 +static int alloc_request(struct sti_dev *sti, struct usb_ep *ep,
4920 + struct usb_request **preq)
4922 + VDBG(sti, "---> %s()\n", __func__);
4924 + *preq = usb_ep_alloc_request(ep, GFP_ATOMIC);
4928 + ERROR(sti, "can't allocate request for %s\n", ep->name);
4930 + VDBG(sti, "<--- %s()\n", __func__);
4935 + * Reset interface setting and re-init endpoint state (toggle etc).
4936 + * Call with altsetting < 0 to disable the interface. The only other
4937 + * available altsetting is 0, which enables the interface.
4939 +static int do_set_interface(struct sti_dev *sti, int altsetting)
4943 + const struct usb_endpoint_descriptor *d;
4944 + VDBG(sti, "---> %s()\n", __func__);
4947 + DBG(sti, "reset interface\n");
4950 + /* deallocate the requests */
4951 + for (i = 0; i < NUM_BUFFERS; ++i) {
4952 + struct sti_buffhd *bh = &sti->buffhds[i];
4955 + usb_ep_free_request(sti->bulk_in, bh->inreq);
4959 + usb_ep_free_request(sti->bulk_out, bh->outreq);
4960 + bh->outreq = NULL;
4963 + if (sti->intreq) {
4964 + usb_ep_free_request(sti->intr_in, sti->intreq);
4965 + sti->intreq = NULL;
4968 + /* disable the endpoints */
4969 + if (sti->bulk_in_enabled) {
4970 + usb_ep_disable(sti->bulk_in);
4971 + sti->bulk_in_enabled = 0;
4973 + if (sti->bulk_out_enabled) {
4974 + usb_ep_disable(sti->bulk_out);
4975 + sti->bulk_out_enabled = 0;
4977 + if (sti->intr_in_enabled) {
4978 + usb_ep_disable(sti->intr_in);
4979 + sti->intr_in_enabled = 0;
4983 + if (altsetting < 0 || rc != 0)
4986 + DBG(sti, "set interface %d\n", altsetting);
4988 + /* enable the endpoints */
4989 + d = ep_desc(sti->gadget, &fs_bulk_in_desc, &hs_bulk_in_desc);
4990 + rc = enable_endpoint(sti, sti->bulk_in, d);
4993 + sti->bulk_in_enabled = 1;
4995 + d = ep_desc(sti->gadget, &fs_bulk_out_desc, &hs_bulk_out_desc);
4996 + rc = enable_endpoint(sti, sti->bulk_out, d);
4999 + sti->bulk_out_enabled = 1;
5000 + sti->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
5001 + clear_bit(CLEAR_BULK_HALTS, &sti->atomic_bitflags);
5003 + d = ep_desc(sti->gadget, &fs_intr_in_desc, &hs_intr_in_desc);
5004 + rc = enable_endpoint(sti, sti->intr_in, d);
5007 + sti->intr_in_enabled = 1;
5009 + /* allocate the requests */
5010 + for (i = 0; i < NUM_BUFFERS; ++i) {
5011 + struct sti_buffhd *bh = &sti->buffhds[i];
5013 + rc = alloc_request(sti, sti->bulk_in, &bh->inreq);
5017 + rc = alloc_request(sti, sti->bulk_out, &bh->outreq);
5021 + bh->inreq->buf = bh->outreq->buf = bh->buf;
5022 + bh->inreq->context = bh->outreq->context = bh;
5023 + bh->inreq->complete = bulk_in_complete;
5024 + bh->outreq->complete = bulk_out_complete;
5027 + rc = alloc_request(sti, sti->intr_in, &sti->intreq);
5033 + VDBG(sti, "<--- %s()\n", __func__);
5039 + * Change our operational configuration. This code must agree with the code
5040 + * that returns config descriptors, and with interface altsetting code.
5042 + * It's also responsible for power management interactions. Some
5043 + * configurations might not work with our current power sources.
5044 + * For now we just assume the gadget is always self-powered.
5046 +static int do_set_config(struct sti_dev *sti, u8 new_config)
5049 + VDBG(sti, "---> %s()\n", __func__);
5051 + /* disable the single interface */
5052 + if (sti->config != 0) {
5053 + DBG(sti, "reset config\n");
5055 + rc = do_set_interface(sti, -1);
5058 + /* enable the interface */
5059 + if (new_config != 0) {
5060 + sti->config = new_config;
5061 + rc = do_set_interface(sti, 0);
5063 + sti->config = 0; /* reset on errors */
5067 + switch (sti->gadget->speed) {
5068 + case USB_SPEED_LOW:
5071 + case USB_SPEED_FULL:
5074 + case USB_SPEED_HIGH:
5081 + INFO(sti, "%s speed config #%d\n",
5082 + speed, sti->config);
5086 + VDBG(sti, "<--- %s()\n", __func__);
5091 +/*-------------------------------------------------------------------------*/
5093 +static void handle_exception(struct sti_dev *sti)
5099 + struct sti_buffhd *bh;
5100 + enum sti_state old_state;
5102 + unsigned int exception_req_tag;
5105 + VDBG(sti, "---> %s()\n", __func__);
5107 + /* Clear the existing signals. Anything but SIGUSR1 is converted
5108 + * into a high-priority EXIT exception. */
5110 + sig = dequeue_signal_lock(current, ¤t->blocked, &info);
5114 + if (sig != SIGUSR1) {
5115 + if (sti->state < STI_STATE_EXIT)
5116 + DBG(sti, "main thread exiting on signal\n");
5117 + raise_exception(sti, STI_STATE_EXIT);
5121 + /* cancel all the pending transfers */
5122 + if (sti->intreq_busy)
5123 + usb_ep_dequeue(sti->intr_in, sti->intreq);
5125 + for (i = 0; i < NUM_BUFFERS; ++i) {
5126 + bh = &sti->buffhds[i];
5127 + if (bh->inreq_busy)
5128 + usb_ep_dequeue(sti->bulk_in, bh->inreq);
5129 + if (bh->outreq_busy)
5130 + usb_ep_dequeue(sti->bulk_out, bh->outreq);
5133 + /* wait until everything is idle */
5135 + num_active = sti->intreq_busy;
5136 + for (i = 0; i < NUM_BUFFERS; ++i) {
5137 + bh = &sti->buffhds[i];
5138 + num_active += bh->inreq_busy + bh->outreq_busy;
5141 + if (num_active == 0)
5144 + if (sleep_thread(sti))
5148 + /* clear out the controller's fifos */
5149 + if (sti->bulk_in_enabled)
5150 + usb_ep_fifo_flush(sti->bulk_in);
5151 + if (sti->bulk_out_enabled)
5152 + usb_ep_fifo_flush(sti->bulk_out);
5153 + if (sti->intr_in_enabled)
5154 + usb_ep_fifo_flush(sti->intr_in);
5157 + * Reset the I/O buffer states and pointers, the device
5158 + * state, and the exception. Then invoke the handler.
5160 + spin_lock_irq(&sti->lock);
5162 + for (i = 0; i < NUM_BUFFERS; ++i) {
5163 + bh = &sti->buffhds[i];
5164 + bh->state = BUF_STATE_EMPTY;
5166 + sti->next_buffhd_to_fill = sti->next_buffhd_to_drain =
5169 + exception_req_tag = sti->exception_req_tag;
5170 + new_config = sti->new_config;
5171 + old_state = sti->state;
5173 + if (old_state == STI_STATE_ABORT_BULK_OUT)
5174 + sti->state = STI_STATE_STATUS_PHASE;
5176 + sti->state = STI_STATE_IDLE;
5177 + spin_unlock_irq(&sti->lock);
5179 + /* carry out any extra actions required for the exception */
5180 + switch (old_state) {
5184 + case STI_STATE_CANCEL:
5185 + if (usb_ep_clear_halt(sti->bulk_out) ||
5186 + usb_ep_clear_halt(sti->bulk_in))
5187 + sti->response_code = PIMA15740_RES_DEVICE_BUSY;
5189 + sti->response_code = PIMA15740_RES_OK;
5192 + case STI_STATE_ABORT_BULK_OUT:
5194 + spin_lock_irq(&sti->lock);
5195 + if (sti->state == STI_STATE_STATUS_PHASE)
5196 + sti->state = STI_STATE_IDLE;
5197 + spin_unlock_irq(&sti->lock);
5200 + case STI_STATE_RESET:
5201 + /* in case we were forced against our will to halt a
5202 + * bulk endpoint, clear the halt now */
5203 + if (test_and_clear_bit(CLEAR_BULK_HALTS,
5204 + &sti->atomic_bitflags)) {
5205 + usb_ep_clear_halt(sti->bulk_in);
5206 + usb_ep_clear_halt(sti->bulk_out);
5209 + if (sti->ep0_req_tag == exception_req_tag)
5210 + /* complete the status stage */
5214 + case STI_STATE_INTERFACE_CHANGE:
5215 + rc = do_set_interface(sti, 0);
5216 + if (sti->ep0_req_tag != exception_req_tag)
5218 + if (rc != 0) /* STALL on errors */
5219 + sti_set_halt(sti, sti->ep0);
5220 + else /* complete the status stage */
5224 + case STI_STATE_CONFIG_CHANGE:
5225 + rc = do_set_config(sti, new_config);
5226 + if (sti->ep0_req_tag != exception_req_tag)
5228 + if (rc != 0) /* STALL on errors */
5229 + sti_set_halt(sti, sti->ep0);
5230 + else /* complete the status stage */
5234 + case STI_STATE_DISCONNECT:
5235 + do_set_config(sti, 0); /* unconfigured state */
5238 + case STI_STATE_EXIT:
5239 + case STI_STATE_TERMINATED:
5240 + do_set_config(sti, 0); /* free resources */
5241 + spin_lock_irq(&sti->lock);
5242 + sti->state = STI_STATE_TERMINATED; /* stop the thread */
5243 + spin_unlock_irq(&sti->lock);
5247 + VDBG(sti, "<--- %s()\n", __func__);
5251 +/*-------------------------------------------------------------------------*/
5253 +static int sti_main_thread(void *sti_)
5255 + struct sti_dev *sti = sti_;
5256 + VDBG(sti, "---> %s()\n", __func__);
5259 + * allow the thread to be killed by a signal, but set the signal mask
5260 + * to block everything but INT, TERM, KILL, and USR1
5262 + allow_signal(SIGINT);
5263 + allow_signal(SIGTERM);
5264 + allow_signal(SIGKILL);
5265 + allow_signal(SIGUSR1);
5267 + /* allow the thread to be frozen */
5271 + * arrange for userspace references to be interpreted as kernel
5272 + * pointers. That way we can pass a kernel pointer to a routine
5273 + * that expects a __user pointer and it will work okay.
5277 + /* the main loop */
5278 + while (sti->state != STI_STATE_TERMINATED) {
5279 + if (exception_in_progress(sti) || signal_pending(current)) {
5280 + handle_exception(sti);
5284 + if (!sti->running) {
5285 + sleep_thread(sti);
5289 + if (get_next_command(sti))
5292 + spin_lock_irq(&sti->lock);
5293 + if (!exception_in_progress(sti))
5294 + sti->state = STI_STATE_DATA_PHASE;
5295 + spin_unlock_irq(&sti->lock);
5297 + if (do_still_image_command(sti))
5300 + spin_lock_irq(&sti->lock);
5301 + if (!exception_in_progress(sti))
5302 + sti->state = STI_STATE_STATUS_PHASE;
5303 + spin_unlock_irq(&sti->lock);
5305 + if (send_status(sti))
5308 + spin_lock_irq(&sti->lock);
5309 + if (!exception_in_progress(sti))
5310 + sti->state = STI_STATE_IDLE;
5311 + spin_unlock_irq(&sti->lock);
5314 + spin_lock_irq(&sti->lock);
5315 + sti->thread_task = NULL;
5316 + spin_unlock_irq(&sti->lock);
5318 + /* in case we are exiting because of a signal, unregister the
5319 + * gadget driver */
5320 + if (test_and_clear_bit(REGISTERED, &sti->atomic_bitflags))
5321 + usb_gadget_unregister_driver(&sti_driver);
5323 + /* let the unbind and cleanup routines know the thread has exited */
5324 + complete_and_exit(&sti->thread_notifier, 0);
5326 + VDBG(sti, "<--- %s()\n", __func__);
5330 +/*-------------------------------------------------------------------------*/
5332 +static int open_backing_folder(struct sti_dev *sti, const char *folder_name)
5334 + struct file *filp = NULL;
5336 + struct inode *inode = NULL;
5338 + VDBG(sti, "---> %s()\n", __func__);
5340 + /* remove the trailing path sign */
5341 + len = strlen(folder_name);
5342 + if (len > 1 && folder_name[len-1] == '/')
5343 + ((char *) folder_name)[len-1] = 0;
5345 + memset(sti->root_path, 0, sizeof(sti->root_path));
5346 + strncpy(sti->root_path, folder_name, sizeof(sti->root_path));
5348 + filp = filp_open(sti->root_path, O_RDONLY | O_DIRECTORY, 0);
5349 + if (IS_ERR(filp)) {
5350 + ERROR(sti, "unable to open backing folder: %s\n",
5352 + return PTR_ERR(filp);
5355 + if (filp->f_path.dentry)
5356 + inode = filp->f_dentry->d_inode;
5358 + if (!inode || !S_ISDIR(inode->i_mode)) {
5359 + ERROR(sti, "%s is not a directory\n", sti->root_path);
5365 + sti->root_filp = filp;
5367 + INFO(sti, "open backing folder: %s\n", folder_name);
5370 + filp_close(filp, current->files);
5372 + VDBG(sti, "<--- %s()\n", __func__);
5376 +static void close_backing_folder(struct sti_dev *sti)
5378 + VDBG(sti, "---> %s()\n", __func__);
5380 + if (sti->root_filp) {
5381 + INFO(sti, "close backing folder\n");
5382 + fput(sti->root_filp);
5383 + sti->root_filp = NULL;
5386 + VDBG(sti, "<--- %s()\n", __func__);
5390 +/*-------------------------------------------------------------------------*/
5392 +/* sysfs attribute files */
5393 +static ssize_t show_folder(struct device *dev, struct device_attribute *attr,
5396 + struct sti_dev *sti = dev_get_drvdata(dev);
5400 + down_read(&sti->filesem);
5401 + if (backing_folder_is_open(sti)) {
5402 + /* get the complete pathname */
5403 + p = d_path(&sti->root_filp->f_path, buf, PAGE_SIZE - 1);
5408 + memmove(buf, p, rc);
5410 + /* add a newline */
5414 + } else { /* no file */
5418 + up_read(&sti->filesem);
5424 +static ssize_t store_folder(struct device *dev, struct device_attribute *attr,
5425 + const char *buf, size_t count)
5427 + struct sti_dev *sti = dev_get_drvdata(dev);
5430 + /* remove a trailing newline */
5431 + if (count > 0 && buf[count-1] == '\n')
5432 + ((char *) buf)[count-1] = 0;
5434 + /* eject current medium */
5435 + down_write(&sti->filesem);
5436 + if (backing_folder_is_open(sti))
5437 + close_backing_folder(sti);
5439 + /* load new medium */
5440 + if (count > 0 && buf[0])
5441 + rc = open_backing_folder(sti, buf);
5443 + up_write(&sti->filesem);
5445 + return (rc < 0 ? rc : count);
5448 +/* the write permissions and store_xxx pointers are set in sti_bind() */
5449 +static DEVICE_ATTR(folder, 0444, show_folder, NULL);
5452 +/*-------------------------------------------------------------------------*/
5454 +static void sti_release(struct kref *ref)
5456 + struct sti_dev *sti = container_of(ref, struct sti_dev, ref);
5458 + while (!list_empty(&sti->obj_list)) {
5459 + struct sti_object *obj = NULL;
5460 + obj = list_entry(sti->obj_list.next, struct sti_object, list);
5461 + list_del_init(&obj->list);
5465 + while (!list_empty(&sti->tmp_obj_list)) {
5466 + struct sti_object *obj = NULL;
5467 + obj = list_entry(sti->tmp_obj_list.next, struct sti_object,
5469 + list_del_init(&obj->list);
5476 +static void gadget_release(struct device *dev)
5478 + struct sti_dev *sti = dev_get_drvdata(dev);
5479 + VDBG(sti, "---> %s()\n", __func__);
5480 + VDBG(sti, "<--- %s()\n", __func__);
5482 + kref_put(&sti->ref, sti_release);
5486 +static void /* __init_or_exit */ sti_unbind(struct usb_gadget *gadget)
5488 + struct sti_dev *sti = get_gadget_data(gadget);
5490 + struct usb_request *req = sti->ep0req;
5491 + VDBG(sti, "---> %s()\n", __func__);
5493 + DBG(sti, "unbind\n");
5494 + clear_bit(REGISTERED, &sti->atomic_bitflags);
5496 + /* unregister the sysfs attribute files */
5497 + if (sti->registered) {
5498 + device_remove_file(&sti->dev, &dev_attr_folder);
5499 + close_backing_folder(sti);
5500 + device_unregister(&sti->dev);
5501 + sti->registered = 0;
5504 + /* if the thread isn't already dead, tell it to exit now */
5505 + if (sti->state != STI_STATE_TERMINATED) {
5506 + raise_exception(sti, STI_STATE_EXIT);
5507 + wait_for_completion(&sti->thread_notifier);
5509 + /* the cleanup routine waits for this completion also */
5510 + complete(&sti->thread_notifier);
5513 + /* free the data buffers */
5514 + for (i = 0; i < NUM_BUFFERS; ++i)
5515 + kfree(sti->buffhds[i].buf);
5517 + /* free the request and buffer for endpoint 0 */
5520 + usb_ep_free_request(sti->ep0, req);
5523 + set_gadget_data(gadget, NULL);
5525 + VDBG(sti, "<--- %s()\n", __func__);
5529 +static int __init check_parameters(struct sti_dev *sti)
5532 + VDBG(sti, "---> %s()\n", __func__);
5534 + /* parameter wasn't set */
5535 + if (mod_data.release == 0xffff) {
5536 + gcnum = usb_gadget_controller_number(sti->gadget);
5538 + mod_data.release = 0x0300 + gcnum;
5540 + WARNING(sti, "controller '%s' not recognized\n",
5541 + sti->gadget->name);
5542 + mod_data.release = 0x0399;
5546 + mod_data.buflen &= PAGE_CACHE_MASK;
5547 + if (mod_data.buflen <= 0) {
5548 + ERROR(sti, "invalid buflen\n");
5549 + return -ETOOSMALL;
5552 + VDBG(sti, "<--- %s()\n", __func__);
5557 +static int __init sti_bind(struct usb_gadget *gadget)
5559 + struct sti_dev *sti = the_sti;
5562 + struct usb_ep *ep;
5563 + struct usb_request *req;
5565 + sti->gadget = gadget;
5566 + set_gadget_data(gadget, sti);
5567 + sti->ep0 = gadget->ep0;
5568 + sti->ep0->driver_data = sti;
5570 + rc = check_parameters(sti);
5574 + /* enable store_xxx attributes */
5575 + dev_attr_folder.attr.mode = 0644;
5576 + dev_attr_folder.store = store_folder;
5578 + sti->dev.release = gadget_release;
5579 + sti->dev.parent = &gadget->dev;
5580 + sti->dev.driver = &sti_driver.driver;
5581 + dev_set_drvdata(&sti->dev, sti);
5582 + dev_set_name(&sti->dev, "%s", sti_driver.driver.name);
5584 + rc = device_register(&sti->dev);
5586 + INFO(sti, "failed to register sti: %d\n", rc);
5590 + rc = device_create_file(&sti->dev, &dev_attr_folder);
5592 + device_unregister(&sti->dev);
5596 + sti->registered = 1;
5597 + kref_get(&sti->ref);
5599 + /* initialize object list */
5600 + INIT_LIST_HEAD(&sti->obj_list);
5601 + INIT_LIST_HEAD(&sti->tmp_obj_list);
5603 + if (mod_data.folder && *mod_data.folder)
5604 + rc = open_backing_folder(sti, mod_data.folder);
5608 + /* find all the endpoints we will use */
5609 + usb_ep_autoconfig_reset(gadget);
5610 + ep = usb_ep_autoconfig(gadget, &fs_bulk_in_desc);
5612 + goto autoconf_fail;
5614 + /* claim bulk-in endpoint */
5615 + ep->driver_data = sti;
5616 + sti->bulk_in = ep;
5618 + ep = usb_ep_autoconfig(gadget, &fs_bulk_out_desc);
5620 + goto autoconf_fail;
5622 + /* claim bulk-out endpoint */
5623 + ep->driver_data = sti;
5624 + sti->bulk_out = ep;
5626 + ep = usb_ep_autoconfig(gadget, &fs_intr_in_desc);
5628 + goto autoconf_fail;
5630 + /* claim intr-in endpoint */
5631 + ep->driver_data = sti;
5632 + sti->intr_in = ep;
5634 + /* fix up the descriptors */
5635 + device_desc.bMaxPacketSize0 = sti->ep0->maxpacket;
5636 + device_desc.idVendor = cpu_to_le16(mod_data.vendor);
5637 + device_desc.idProduct = cpu_to_le16(mod_data.product);
5638 + device_desc.bcdDevice = cpu_to_le16(mod_data.release);
5640 + fs_function[3 + FS_FUNCTION_PRE_EP_ENTRIES] = NULL;
5642 + if (gadget_is_dualspeed(gadget)) {
5643 + hs_function[3 + HS_FUNCTION_PRE_EP_ENTRIES] = NULL;
5645 + /* assume ep0 uses the same maxpacket value for both speeds */
5646 + dev_qualifier.bMaxPacketSize0 = sti->ep0->maxpacket;
5648 + /* assume endpoint addresses are the same for both speeds */
5649 + hs_bulk_in_desc.bEndpointAddress =
5650 + fs_bulk_in_desc.bEndpointAddress;
5651 + hs_bulk_out_desc.bEndpointAddress =
5652 + fs_bulk_out_desc.bEndpointAddress;
5653 + hs_intr_in_desc.bEndpointAddress =
5654 + fs_intr_in_desc.bEndpointAddress;
5657 + if (gadget_is_otg(gadget))
5658 + otg_desc.bmAttributes |= USB_OTG_HNP;
5662 + /* allocate the request and buffer for endpoint 0 */
5663 + sti->ep0req = req = usb_ep_alloc_request(sti->ep0, GFP_KERNEL);
5665 + goto autoconf_fail;
5667 + req->buf = kmalloc(EP0_BUFSIZE, GFP_KERNEL);
5669 + goto autoconf_fail;
5671 + req->complete = ep0_complete;
5673 + /* allocate the data buffers */
5674 + for (i = 0; i < NUM_BUFFERS; ++i) {
5675 + struct sti_buffhd *bh = &sti->buffhds[i];
5678 + * Allocate for the bulk-in endpoint. We assume that
5679 + * the buffer will also work with the bulk-out (and
5680 + * interrupt-in) endpoint.
5682 + bh->buf = kmalloc(mod_data.buflen, GFP_KERNEL);
5684 + goto autoconf_fail;
5686 + bh->next = bh + 1;
5688 + sti->buffhds[NUM_BUFFERS - 1].next = &sti->buffhds[0];
5690 + /* this should reflect the actual gadget power source */
5691 + usb_gadget_set_selfpowered(gadget);
5693 + snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
5694 + init_utsname()->sysname, init_utsname()->release,
5697 + DBG(sti, "manufacturer: %s\n", manufacturer);
5700 + * on a real device, serial[] would be loaded from permanent
5701 + * storage. We just encode it from the driver version string.
5703 + for (i = 0; i < sizeof(serial) - 2; i += 2) {
5704 + unsigned char c = DRIVER_VERSION[i / 2];
5709 + snprintf(&serial[i], sizeof(&serial[i]), "%02X", c);
5712 + /* fill remained device info */
5713 + sti_device_info.manufacturer_len = sizeof(manufacturer);
5714 + str_to_uni16(manufacturer, sti_device_info.manufacturer);
5716 + sti_device_info.model_len = sizeof(longname);
5717 + str_to_uni16(longname, sti_device_info.model);
5719 + sti_device_info.device_version_len = sizeof(device_version);
5720 + str_to_uni16(device_version, sti_device_info.device_version);
5722 + sti_device_info.serial_number_len = sizeof(serial);
5723 + str_to_uni16(serial, sti_device_info.serial_number);
5725 + /* create main kernel thread */
5726 + sti->thread_task = kthread_create(sti_main_thread, sti,
5727 + "still-image-gadget");
5729 + if (IS_ERR(sti->thread_task)) {
5730 + rc = PTR_ERR(sti->thread_task);
5731 + goto autoconf_fail;
5734 + INFO(sti, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
5735 + INFO(sti, "VendorID=x%04x, ProductID=x%04x, Release=x%04x\n",
5736 + mod_data.vendor, mod_data.product, mod_data.release);
5737 + INFO(sti, "I/O thread pid: %d, buflen=%u\n",
5738 + task_pid_nr(sti->thread_task), mod_data.buflen);
5740 + set_bit(REGISTERED, &sti->atomic_bitflags);
5742 + /* tell the thread to start working */
5743 + wake_up_process(sti->thread_task);
5745 + DBG(sti, "bind\n");
5749 + ERROR(sti, "unable to autoconfigure all endpoints\n");
5752 + /* the thread is dead */
5753 + sti->state = STI_STATE_TERMINATED;
5755 + sti_unbind(gadget);
5756 + complete(&sti->thread_notifier);
5758 + VDBG(sti, "<---> %s()\n", __func__);
5763 +/*-------------------------------------------------------------------------*/
5765 +static void sti_suspend(struct usb_gadget *gadget)
5767 + struct sti_dev *sti = get_gadget_data(gadget);
5769 + DBG(sti, "suspend\n");
5770 + set_bit(SUSPENDED, &sti->atomic_bitflags);
5774 +static void sti_resume(struct usb_gadget *gadget)
5776 + struct sti_dev *sti = get_gadget_data(gadget);
5778 + DBG(sti, "resume\n");
5779 + clear_bit(SUSPENDED, &sti->atomic_bitflags);
5783 +/*-------------------------------------------------------------------------*/
5785 +static struct usb_gadget_driver sti_driver = {
5786 +#ifdef CONFIG_USB_GADGET_DUALSPEED
5787 + .speed = USB_SPEED_HIGH,
5789 + .speed = USB_SPEED_FULL,
5791 + .function = (char *) longname,
5793 + .unbind = sti_unbind,
5794 + .disconnect = sti_disconnect,
5795 + .setup = sti_setup,
5796 + .suspend = sti_suspend,
5797 + .resume = sti_resume,
5800 + .name = (char *) shortname,
5801 + .owner = THIS_MODULE,
5802 + /* .release = ... */
5803 + /* .suspend = ... */
5804 + /* .resume = ... */
5809 +static int __init sti_alloc(void)
5811 + struct sti_dev *sti;
5813 + sti = kzalloc(sizeof *sti, GFP_KERNEL);
5817 + spin_lock_init(&sti->lock);
5818 + init_rwsem(&sti->filesem);
5819 + kref_init(&sti->ref);
5820 + init_completion(&sti->thread_notifier);
5828 +static int __init sti_init(void)
5831 + struct sti_dev *sti;
5839 + rc = usb_gadget_register_driver(&sti_driver);
5841 + kref_put(&sti->ref, sti_release);
5845 +module_init(sti_init);
5848 +static void __exit sti_cleanup(void)
5850 + struct sti_dev *sti = the_sti;
5852 + /* unregister the driver if the thread hasn't already done */
5853 + if (test_and_clear_bit(REGISTERED, &sti->atomic_bitflags))
5854 + usb_gadget_unregister_driver(&sti_driver);
5856 + /* wait for the thread to finish up */
5857 + wait_for_completion(&sti->thread_notifier);
5859 + kref_put(&sti->ref, sti_release);
5861 +module_exit(sti_cleanup);
5862 diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
5863 index 3d2d3e5..69ff37b 100644
5864 --- a/drivers/usb/otg/Kconfig
5865 +++ b/drivers/usb/otg/Kconfig
5866 @@ -69,4 +69,18 @@ config NOP_USB_XCEIV
5867 built-in with usb ip or which are autonomous and doesn't require any
5868 phy programming such as ISP1x04 etc.
5870 +config USB_LANGWELL_OTG
5871 + tristate "Intel Langwell USB OTG dual-role support"
5872 + depends on USB && X86_MRST
5874 + select USB_OTG_UTILS
5876 + Say Y here if you want to build Intel Langwell USB OTG
5877 + transciever driver in kernel. This driver implements role
5878 + switch between EHCI host driver and Langwell USB OTG
5881 + To compile this driver as a module, choose M here: the
5882 + module will be called langwell_otg.
5885 diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile
5886 index aeb49a8..b6609db 100644
5887 --- a/drivers/usb/otg/Makefile
5888 +++ b/drivers/usb/otg/Makefile
5889 @@ -9,6 +9,7 @@ obj-$(CONFIG_USB_OTG_UTILS) += otg.o
5890 obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o
5891 obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o
5892 obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o
5893 +obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o
5894 obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o
5895 obj-$(CONFIG_USB_ULPI) += ulpi.o
5897 diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c
5898 new file mode 100644
5899 index 0000000..46ae881
5901 +++ b/drivers/usb/otg/langwell_otg.c
5904 + * Intel Langwell USB OTG transceiver driver
5905 + * Copyright (C) 2008 - 2009, Intel Corporation.
5907 + * This program is free software; you can redistribute it and/or modify it
5908 + * under the terms and conditions of the GNU General Public License,
5909 + * version 2, as published by the Free Software Foundation.
5911 + * This program is distributed in the hope it will be useful, but WITHOUT
5912 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5913 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
5916 + * You should have received a copy of the GNU General Public License along with
5917 + * this program; if not, write to the Free Software Foundation, Inc.,
5918 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
5921 +/* This driver helps to switch Langwell OTG controller function between host
5922 + * and peripheral. It works with EHCI driver and Langwell client controller
5923 + * driver together.
5925 +#include <linux/module.h>
5926 +#include <linux/init.h>
5927 +#include <linux/pci.h>
5928 +#include <linux/errno.h>
5929 +#include <linux/interrupt.h>
5930 +#include <linux/kernel.h>
5931 +#include <linux/device.h>
5932 +#include <linux/moduleparam.h>
5933 +#include <linux/usb/ch9.h>
5934 +#include <linux/usb/gadget.h>
5935 +#include <linux/usb.h>
5936 +#include <linux/usb/otg.h>
5937 +#include <linux/notifier.h>
5938 +#include <asm/ipc_defs.h>
5939 +#include <linux/delay.h>
5940 +#include "../core/hcd.h"
5942 +#include <linux/usb/langwell_otg.h>
5944 +#define DRIVER_DESC "Intel Langwell USB OTG transceiver driver"
5945 +#define DRIVER_VERSION "March 19, 2010"
5947 +MODULE_DESCRIPTION(DRIVER_DESC);
5948 +MODULE_AUTHOR("Henry Yuan <hang.yuan@intel.com>, Hao Wu <hao.wu@intel.com>");
5949 +MODULE_VERSION(DRIVER_VERSION);
5950 +MODULE_LICENSE("GPL");
5952 +static const char driver_name[] = "langwell_otg";
5954 +static int langwell_otg_probe(struct pci_dev *pdev,
5955 + const struct pci_device_id *id);
5956 +static void langwell_otg_remove(struct pci_dev *pdev);
5957 +static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message);
5958 +static int langwell_otg_resume(struct pci_dev *pdev);
5960 +static int langwell_otg_set_host(struct otg_transceiver *otg,
5961 + struct usb_bus *host);
5962 +static int langwell_otg_set_peripheral(struct otg_transceiver *otg,
5963 + struct usb_gadget *gadget);
5964 +static int langwell_otg_start_srp(struct otg_transceiver *otg);
5966 +static const struct pci_device_id pci_ids[] = {{
5967 + .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
5971 + .subvendor = PCI_ANY_ID,
5972 + .subdevice = PCI_ANY_ID,
5973 +}, { /* end: all zeroes */ }
5976 +static struct pci_driver otg_pci_driver = {
5977 + .name = (char *) driver_name,
5978 + .id_table = pci_ids,
5980 + .probe = langwell_otg_probe,
5981 + .remove = langwell_otg_remove,
5983 + .suspend = langwell_otg_suspend,
5984 + .resume = langwell_otg_resume,
5987 +static const char *state_string(enum usb_otg_state state)
5990 + case OTG_STATE_A_IDLE:
5992 + case OTG_STATE_A_WAIT_VRISE:
5993 + return "a_wait_vrise";
5994 + case OTG_STATE_A_WAIT_BCON:
5995 + return "a_wait_bcon";
5996 + case OTG_STATE_A_HOST:
5998 + case OTG_STATE_A_SUSPEND:
5999 + return "a_suspend";
6000 + case OTG_STATE_A_PERIPHERAL:
6001 + return "a_peripheral";
6002 + case OTG_STATE_A_WAIT_VFALL:
6003 + return "a_wait_vfall";
6004 + case OTG_STATE_A_VBUS_ERR:
6005 + return "a_vbus_err";
6006 + case OTG_STATE_B_IDLE:
6008 + case OTG_STATE_B_SRP_INIT:
6009 + return "b_srp_init";
6010 + case OTG_STATE_B_PERIPHERAL:
6011 + return "b_peripheral";
6012 + case OTG_STATE_B_WAIT_ACON:
6013 + return "b_wait_acon";
6014 + case OTG_STATE_B_HOST:
6017 + return "UNDEFINED";
6022 +static inline struct langwell_otg_timer *otg_timer_initializer
6023 +(void (*function)(unsigned long), unsigned long expires, unsigned long data)
6025 + struct langwell_otg_timer *timer;
6026 + timer = kmalloc(sizeof(struct langwell_otg_timer), GFP_KERNEL);
6027 + timer->function = function;
6028 + timer->expires = expires;
6029 + timer->data = data;
6033 +static struct langwell_otg_timer *a_wait_vrise_tmr, *a_aidl_bdis_tmr,
6034 + *b_se0_srp_tmr, *b_srp_init_tmr;
6036 +static struct list_head active_timers;
6038 +static struct langwell_otg *the_transceiver;
6040 +/* host/client notify transceiver when event affects HNP state */
6041 +void langwell_update_transceiver()
6043 + struct langwell_otg *langwell = the_transceiver;
6045 + otg_dbg("transceiver is updated\n");
6047 + if (!langwell->qwork)
6050 + queue_work(langwell->qwork, &langwell->work);
6052 +EXPORT_SYMBOL(langwell_update_transceiver);
6054 +static int langwell_otg_set_host(struct otg_transceiver *otg,
6055 + struct usb_bus *host)
6062 +static int langwell_otg_set_peripheral(struct otg_transceiver *otg,
6063 + struct usb_gadget *gadget)
6065 + otg->gadget = gadget;
6070 +static int langwell_otg_set_power(struct otg_transceiver *otg,
6076 +/* A-device drives vbus, controlled through PMIC CHRGCNTL register*/
6077 +static void langwell_otg_drv_vbus(int on)
6079 + struct ipc_pmic_reg_data pmic_data = {0};
6080 + struct ipc_pmic_reg_data data = {0};
6082 + data.pmic_reg_data[0].register_address = 0xd2;
6084 + data.num_entries = 1;
6086 + if (ipc_pmic_register_read(&data)) {
6087 + otg_dbg("Failed to read PMIC register 0x00.\n");
6091 + if (data.pmic_reg_data[0].value & 0x20)
6092 + otg_dbg("battery attached(%x)\n", data.pmic_reg_data[0].value);
6094 + otg_dbg("no battery detected\n");
6098 + pmic_data.ioc = 0;
6099 + pmic_data.pmic_reg_data[0].register_address = 0xd4;
6100 + pmic_data.num_entries = 1;
6102 + pmic_data.pmic_reg_data[0].value = 0x20;
6104 + pmic_data.pmic_reg_data[0].value = 0xc0;
6106 + if (ipc_pmic_register_write(&pmic_data, TRUE))
6107 + otg_dbg("Failed to write PMIC.\n");
6110 +/* charge vbus or discharge vbus through a resistor to ground */
6111 +static void langwell_otg_chrg_vbus(int on)
6116 + val = readl(the_transceiver->regs + CI_OTGSC);
6119 + writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VC,
6120 + the_transceiver->regs + CI_OTGSC);
6122 + writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VD,
6123 + the_transceiver->regs + CI_OTGSC);
6128 +static int langwell_otg_start_srp(struct otg_transceiver *otg)
6132 + otg_dbg("Start SRP ->\n");
6134 + val = readl(the_transceiver->regs + CI_OTGSC);
6136 + writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HADP,
6137 + the_transceiver->regs + CI_OTGSC);
6139 + /* Check if the data plus is finished or not */
6141 + val = readl(the_transceiver->regs + CI_OTGSC);
6142 + if (val & (OTGSC_HADP | OTGSC_DP))
6143 + otg_dbg("DataLine SRP Error\n");
6145 + /* Disable interrupt - b_sess_vld */
6146 + val = readl(the_transceiver->regs + CI_OTGSC);
6147 + val &= (~(OTGSC_BSVIE | OTGSC_BSEIE));
6148 + writel(val, the_transceiver->regs + CI_OTGSC);
6150 + /* Start VBus SRP */
6151 + langwell_otg_drv_vbus(1);
6153 + langwell_otg_drv_vbus(0);
6155 + /* Enable interrupt - b_sess_vld*/
6156 + val = readl(the_transceiver->regs + CI_OTGSC);
6157 + val |= (OTGSC_BSVIE | OTGSC_BSEIE);
6158 + writel(val, the_transceiver->regs + CI_OTGSC);
6160 + otg_dbg("Start SRP <-\n");
6164 +/* stop SOF via bus_suspend */
6165 +static void langwell_otg_loc_sof(int on)
6167 + struct usb_hcd *hcd;
6170 + otg_dbg("loc_sof -> %d\n", on);
6172 + hcd = bus_to_hcd(the_transceiver->otg.host);
6174 + err = hcd->driver->bus_resume(hcd);
6176 + err = hcd->driver->bus_suspend(hcd);
6179 + otg_dbg("Failed to resume/suspend bus - %d\n", err);
6182 +static int langwell_otg_check_otgsc(void)
6184 + struct langwell_otg *langwell;
6185 + u32 val_otgsc, val_usbcfg;
6187 + langwell = the_transceiver;
6189 + val_otgsc = readl(langwell->regs + CI_OTGSC);
6190 + val_usbcfg = readl(langwell->usbcfg);
6192 + otg_dbg("check sync OTGSC and USBCFG\n");
6193 + otg_dbg("OTGSC = %08x, USBCFG = %08x\n", val_otgsc, val_usbcfg);
6194 + otg_dbg("OTGSC_AVV = %d\n", !!(val_otgsc & OTGSC_AVV));
6195 + otg_dbg("USBCFG.VBUSVAL = %d\n", !!(val_usbcfg & USBCFG_VBUSVAL));
6196 + otg_dbg("OTGSC_ASV = %d\n", !!(val_otgsc & OTGSC_ASV));
6197 + otg_dbg("USBCFG.AVALID = %d\n", !!(val_usbcfg & USBCFG_AVALID));
6198 + otg_dbg("OTGSC_BSV = %d\n", !!(val_otgsc & OTGSC_BSV));
6199 + otg_dbg("USBCFG.BVALID = %d\n", !!(val_usbcfg & USBCFG_BVALID));
6200 + otg_dbg("OTGSC_BSE = %d\n", !!(val_otgsc & OTGSC_BSE));
6201 + otg_dbg("USBCFG.SESEND = %d\n", !!(val_usbcfg & USBCFG_SESEND));
6203 + /* Check USBCFG VBusValid/AValid/BValid/SessEnd */
6204 + if (!!(val_otgsc & OTGSC_AVV) ^ !!(val_usbcfg & USBCFG_VBUSVAL)) {
6205 + otg_dbg("OTGSC AVV and USBCFG VBUSVAL are not sync.\n");
6207 + } else if (!!(val_otgsc & OTGSC_ASV) ^ !!(val_usbcfg & USBCFG_AVALID)) {
6208 + otg_dbg("OTGSC ASV and USBCFG AVALID are not sync.\n");
6210 + } else if (!!(val_otgsc & OTGSC_BSV) ^ !!(val_usbcfg & USBCFG_BVALID)) {
6211 + otg_dbg("OTGSC BSV and USBCFG BVALID are not sync.\n");
6213 + } else if (!!(val_otgsc & OTGSC_BSE) ^ !!(val_usbcfg & USBCFG_SESEND)) {
6214 + otg_dbg("OTGSC BSE and USBCFG SESSEN are not sync.\n");
6218 + otg_dbg("OTGSC and USBCFG are synced\n");
6223 +static void langwell_otg_phy_low_power(int on)
6228 + otg_dbg("phy low power mode-> %d start\n", on);
6232 + val = readb(the_transceiver->regs + CI_HOSTPC1 + 2);
6235 + /* Due to hardware issue, after set PHCD, sync will failed
6236 + * between USBCFG and OTGSC, so before set PHCD, check if
6237 + * sync is in process now. If the answer is "yes", then do
6238 + * not touch PHCD bit */
6239 + retval = langwell_otg_check_otgsc();
6241 + otg_dbg("Skip PHCD programming..\n");
6245 + writeb(val | phcd, the_transceiver->regs + CI_HOSTPC1 + 2);
6247 + writeb(val & ~phcd, the_transceiver->regs + CI_HOSTPC1 + 2);
6249 + otg_dbg("phy low power mode<- %d done\n", on);
6252 +/* After drv vbus, add 2 ms delay to set PHCD */
6253 +static void langwell_otg_phy_low_power_wait(int on)
6255 + otg_dbg("2 ms delay before set PHY low power mode\n");
6258 + langwell_otg_phy_low_power(on);
6261 +/* Enable/Disable OTG interrupts */
6262 +static void langwell_otg_intr(int on)
6266 + otg_dbg("interrupt -> %d\n", on);
6268 + val = readl(the_transceiver->regs + CI_OTGSC);
6270 + /* OTGSC_INT_MASK doesn't contains 1msInt */
6272 + val = val | (OTGSC_INT_MASK);
6273 + writel(val, the_transceiver->regs + CI_OTGSC);
6275 + val = val & ~(OTGSC_INT_MASK);
6276 + writel(val, the_transceiver->regs + CI_OTGSC);
6280 +/* set HAAR: Hardware Assist Auto-Reset */
6281 +static void langwell_otg_HAAR(int on)
6285 + otg_dbg("HAAR -> %d\n", on);
6287 + val = readl(the_transceiver->regs + CI_OTGSC);
6289 + writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HAAR,
6290 + the_transceiver->regs + CI_OTGSC);
6292 + writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HAAR,
6293 + the_transceiver->regs + CI_OTGSC);
6296 +/* set HABA: Hardware Assist B-Disconnect to A-Connect */
6297 +static void langwell_otg_HABA(int on)
6301 + otg_dbg("HABA -> %d\n", on);
6303 + val = readl(the_transceiver->regs + CI_OTGSC);
6305 + writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HABA,
6306 + the_transceiver->regs + CI_OTGSC);
6308 + writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HABA,
6309 + the_transceiver->regs + CI_OTGSC);
6312 +static int langwell_otg_check_se0_srp(int on)
6316 + int delay_time = TB_SE0_SRP * 10; /* step is 100us */
6318 + otg_dbg("check_se0_srp -> \n");
6322 + if (!delay_time--)
6324 + val = readl(the_transceiver->regs + CI_PORTSC1);
6328 + otg_dbg("check_se0_srp <- \n");
6332 +/* The timeout callback function to set time out bit */
6333 +static void set_tmout(unsigned long indicator)
6335 + *(int *)indicator = 1;
6338 +void langwell_otg_nsf_msg(unsigned long indicator)
6340 + switch (indicator) {
6345 + printk(KERN_ERR "OTG:NSF-%lu - deivce not responding\n",
6349 + printk(KERN_ERR "OTG:NSF-%lu - deivce not supported\n",
6353 + printk(KERN_ERR "Do not have this kind of NSF\n");
6358 +/* Initialize timers */
6359 +static void langwell_otg_init_timers(struct otg_hsm *hsm)
6361 + /* HSM used timers */
6362 + a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE,
6363 + (unsigned long)&hsm->a_wait_vrise_tmout);
6364 + a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS,
6365 + (unsigned long)&hsm->a_aidl_bdis_tmout);
6366 + b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP,
6367 + (unsigned long)&hsm->b_se0_srp);
6368 + b_srp_init_tmr = otg_timer_initializer(&set_tmout, TB_SRP_INIT,
6369 + (unsigned long)&hsm->b_srp_init_tmout);
6373 +static void langwell_otg_free_timers(void)
6375 + kfree(a_wait_vrise_tmr);
6376 + kfree(a_aidl_bdis_tmr);
6377 + kfree(b_se0_srp_tmr);
6378 + kfree(b_srp_init_tmr);
6381 +/* The timeout callback function to set time out bit */
6382 +static void langwell_otg_timer_fn(unsigned long indicator)
6384 + struct langwell_otg *langwell;
6386 + langwell = the_transceiver;
6388 + *(int *)indicator = 1;
6390 + otg_dbg("kernel timer - timeout\n");
6392 + queue_work(langwell->qwork, &langwell->work);
6395 +/* kernel timer used instead of HW based interrupt */
6396 +static void langwell_otg_add_ktimer(enum langwell_otg_timer_type timers)
6398 + struct langwell_otg *langwell;
6399 + unsigned long j = jiffies;
6400 + unsigned long data, time;
6402 + langwell = the_transceiver;
6405 + case TA_WAIT_VRISE_TMR:
6406 + langwell->hsm.a_wait_vrise_tmout = 0;
6407 + data = (unsigned long)&langwell->hsm.a_wait_vrise_tmout;
6408 + time = TA_WAIT_VRISE;
6410 + case TA_WAIT_BCON_TMR:
6411 + langwell->hsm.a_wait_bcon_tmout = 0;
6412 + data = (unsigned long)&langwell->hsm.a_wait_bcon_tmout;
6413 + time = TA_WAIT_BCON;
6415 + case TA_AIDL_BDIS_TMR:
6416 + langwell->hsm.a_aidl_bdis_tmout = 0;
6417 + data = (unsigned long)&langwell->hsm.a_aidl_bdis_tmout;
6418 + time = TA_AIDL_BDIS;
6420 + case TB_ASE0_BRST_TMR:
6421 + langwell->hsm.b_ase0_brst_tmout = 0;
6422 + data = (unsigned long)&langwell->hsm.b_ase0_brst_tmout;
6423 + time = TB_ASE0_BRST;
6425 + case TB_SRP_INIT_TMR:
6426 + langwell->hsm.b_srp_init_tmout = 0;
6427 + data = (unsigned long)&langwell->hsm.b_srp_init_tmout;
6428 + time = TB_SRP_INIT;
6430 + case TB_SRP_FAIL_TMR:
6431 + langwell->hsm.b_srp_fail_tmout = 0;
6432 + data = (unsigned long)&langwell->hsm.b_srp_fail_tmout;
6433 + time = TB_SRP_FAIL;
6435 + case TB_BUS_SUSPEND_TMR:
6436 + langwell->hsm.b_bus_suspend_tmout = 0;
6437 + data = (unsigned long)&langwell->hsm.b_bus_suspend_tmout;
6438 + time = TB_BUS_SUSPEND;
6441 + otg_dbg("OTG: unkown timer, can not enable such timer\n");
6445 + langwell->hsm_timer.data = data;
6446 + langwell->hsm_timer.function = langwell_otg_timer_fn;
6447 + langwell->hsm_timer.expires = j + time * HZ / 1000; /* milliseconds */
6449 + add_timer(&langwell->hsm_timer);
6451 + otg_dbg("OTG: add timer successfully\n");
6454 +/* Add timer to timer list */
6455 +static void langwell_otg_add_timer(void *gtimer)
6457 + struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer;
6458 + struct langwell_otg_timer *tmp_timer;
6461 + /* Check if the timer is already in the active list,
6462 + * if so update timer count
6464 + list_for_each_entry(tmp_timer, &active_timers, list)
6465 + if (tmp_timer == timer) {
6466 + timer->count = timer->expires;
6469 + timer->count = timer->expires;
6471 + if (list_empty(&active_timers)) {
6472 + val32 = readl(the_transceiver->regs + CI_OTGSC);
6473 + writel(val32 | OTGSC_1MSE, the_transceiver->regs + CI_OTGSC);
6476 + list_add_tail(&timer->list, &active_timers);
6479 +/* Remove timer from the timer list; clear timeout status */
6480 +static void langwell_otg_del_timer(void *gtimer)
6482 + struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer;
6483 + struct langwell_otg_timer *tmp_timer, *del_tmp;
6486 + list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list)
6487 + if (tmp_timer == timer)
6488 + list_del(&timer->list);
6490 + if (list_empty(&active_timers)) {
6491 + val32 = readl(the_transceiver->regs + CI_OTGSC);
6492 + writel(val32 & ~OTGSC_1MSE, the_transceiver->regs + CI_OTGSC);
6496 +/* Reduce timer count by 1, and find timeout conditions.*/
6497 +static int langwell_otg_tick_timer(u32 *int_sts)
6499 + struct langwell_otg_timer *tmp_timer, *del_tmp;
6502 + list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) {
6503 + tmp_timer->count--;
6504 + /* check if timer expires */
6505 + if (!tmp_timer->count) {
6506 + list_del(&tmp_timer->list);
6507 + tmp_timer->function(tmp_timer->data);
6512 + if (list_empty(&active_timers)) {
6513 + otg_dbg("tick timer: disable 1ms int\n");
6514 + *int_sts = *int_sts & ~OTGSC_1MSE;
6519 +static void reset_otg(void)
6522 + int delay_time = 1000;
6524 + otg_dbg("reseting OTG controller ...\n");
6525 + val = readl(the_transceiver->regs + CI_USBCMD);
6526 + writel(val | USBCMD_RST, the_transceiver->regs + CI_USBCMD);
6529 + if (!delay_time--)
6530 + otg_dbg("reset timeout\n");
6531 + val = readl(the_transceiver->regs + CI_USBCMD);
6532 + val &= USBCMD_RST;
6533 + } while (val != 0);
6534 + otg_dbg("reset done.\n");
6537 +static void set_host_mode(void)
6542 + val = readl(the_transceiver->regs + CI_USBMODE);
6543 + val = (val & (~USBMODE_CM)) | USBMODE_HOST;
6544 + writel(val, the_transceiver->regs + CI_USBMODE);
6547 +static void set_client_mode(void)
6552 + val = readl(the_transceiver->regs + CI_USBMODE);
6553 + val = (val & (~USBMODE_CM)) | USBMODE_DEVICE;
6554 + writel(val, the_transceiver->regs + CI_USBMODE);
6557 +static void init_hsm(void)
6559 + struct langwell_otg *langwell = the_transceiver;
6562 + /* read OTGSC after reset */
6563 + val32 = readl(langwell->regs + CI_OTGSC);
6564 + otg_dbg("%s: OTGSC init value = 0x%x\n", __func__, val32);
6566 + /* set init state */
6567 + if (val32 & OTGSC_ID) {
6568 + langwell->hsm.id = 1;
6569 + langwell->otg.default_a = 0;
6570 + set_client_mode();
6571 + langwell->otg.state = OTG_STATE_B_IDLE;
6572 + langwell_otg_drv_vbus(0);
6574 + langwell->hsm.id = 0;
6575 + langwell->otg.default_a = 1;
6577 + langwell->otg.state = OTG_STATE_A_IDLE;
6580 + /* set session indicator */
6581 + if (val32 & OTGSC_BSE)
6582 + langwell->hsm.b_sess_end = 1;
6583 + if (val32 & OTGSC_BSV)
6584 + langwell->hsm.b_sess_vld = 1;
6585 + if (val32 & OTGSC_ASV)
6586 + langwell->hsm.a_sess_vld = 1;
6587 + if (val32 & OTGSC_AVV)
6588 + langwell->hsm.a_vbus_vld = 1;
6590 + /* defautly power the bus */
6591 + langwell->hsm.a_bus_req = 1;
6592 + langwell->hsm.a_bus_drop = 0;
6593 + /* defautly don't request bus as B device */
6594 + langwell->hsm.b_bus_req = 0;
6595 + /* no system error */
6596 + langwell->hsm.a_clr_err = 0;
6598 + langwell_otg_phy_low_power_wait(1);
6601 +static void update_hsm(void)
6603 + struct langwell_otg *langwell = the_transceiver;
6607 + val32 = readl(langwell->regs + CI_OTGSC);
6608 + otg_dbg("%s: OTGSC current value = 0x%x\n", __func__, val32);
6610 + langwell->hsm.id = !!(val32 & OTGSC_ID);
6611 + langwell->hsm.b_sess_end = !!(val32 & OTGSC_BSE);
6612 + langwell->hsm.b_sess_vld = !!(val32 & OTGSC_BSV);
6613 + langwell->hsm.a_sess_vld = !!(val32 & OTGSC_ASV);
6614 + langwell->hsm.a_vbus_vld = !!(val32 & OTGSC_AVV);
6617 +static irqreturn_t otg_dummy_irq(int irq, void *_dev)
6619 + void __iomem *reg_base = _dev;
6623 + val = readl(reg_base + CI_USBMODE);
6624 + if ((val & USBMODE_CM) != USBMODE_DEVICE)
6627 + val = readl(reg_base + CI_USBSTS);
6628 + int_mask = val & INTR_DUMMY_MASK;
6630 + if (int_mask == 0)
6633 + /* clear hsm.b_conn here since host driver can't detect it
6634 + * otg_dummy_irq called means B-disconnect happened.
6636 + if (the_transceiver->hsm.b_conn) {
6637 + the_transceiver->hsm.b_conn = 0;
6638 + if (spin_trylock(&the_transceiver->wq_lock)) {
6639 + queue_work(the_transceiver->qwork,
6640 + &the_transceiver->work);
6641 + spin_unlock(&the_transceiver->wq_lock);
6644 + /* Clear interrupts */
6645 + writel(int_mask, reg_base + CI_USBSTS);
6646 + return IRQ_HANDLED;
6649 +static irqreturn_t otg_irq(int irq, void *_dev)
6651 + struct langwell_otg *langwell = _dev;
6652 + u32 int_sts, int_en;
6656 + int_sts = readl(langwell->regs + CI_OTGSC);
6657 + int_en = (int_sts & OTGSC_INTEN_MASK) >> 8;
6658 + int_mask = int_sts & int_en;
6659 + if (int_mask == 0)
6662 + if (int_mask & OTGSC_IDIS) {
6663 + otg_dbg("%s: id change int\n", __func__);
6664 + langwell->hsm.id = (int_sts & OTGSC_ID) ? 1 : 0;
6667 + if (int_mask & OTGSC_DPIS) {
6668 + otg_dbg("%s: data pulse int\n", __func__);
6669 + langwell->hsm.a_srp_det = (int_sts & OTGSC_DPS) ? 1 : 0;
6672 + if (int_mask & OTGSC_BSEIS) {
6673 + otg_dbg("%s: b session end int\n", __func__);
6674 + langwell->hsm.b_sess_end = (int_sts & OTGSC_BSE) ? 1 : 0;
6677 + if (int_mask & OTGSC_BSVIS) {
6678 + otg_dbg("%s: b session valid int\n", __func__);
6679 + langwell->hsm.b_sess_vld = (int_sts & OTGSC_BSV) ? 1 : 0;
6682 + if (int_mask & OTGSC_ASVIS) {
6683 + otg_dbg("%s: a session valid int\n", __func__);
6684 + langwell->hsm.a_sess_vld = (int_sts & OTGSC_ASV) ? 1 : 0;
6687 + if (int_mask & OTGSC_AVVIS) {
6688 + otg_dbg("%s: a vbus valid int\n", __func__);
6689 + langwell->hsm.a_vbus_vld = (int_sts & OTGSC_AVV) ? 1 : 0;
6693 + if (int_mask & OTGSC_1MSS) {
6694 + /* need to schedule otg_work if any timer is expired */
6695 + if (langwell_otg_tick_timer(&int_sts))
6699 + writel((int_sts & ~OTGSC_INTSTS_MASK) | int_mask,
6700 + langwell->regs + CI_OTGSC);
6702 + queue_work(langwell->qwork, &langwell->work);
6704 + return IRQ_HANDLED;
6707 +static void langwell_otg_work(struct work_struct *work)
6709 + struct langwell_otg *langwell = container_of(work,
6710 + struct langwell_otg, work);
6713 + otg_dbg("%s: old state = %s\n", __func__,
6714 + state_string(langwell->otg.state));
6716 + switch (langwell->otg.state) {
6717 + case OTG_STATE_UNDEFINED:
6718 + case OTG_STATE_B_IDLE:
6719 + if (!langwell->hsm.id) {
6720 + langwell_otg_del_timer(b_srp_init_tmr);
6721 + del_timer_sync(&langwell->hsm_timer);
6722 + langwell->otg.default_a = 1;
6723 + langwell->hsm.a_srp_det = 0;
6724 + langwell_otg_chrg_vbus(0);
6726 + langwell_otg_phy_low_power(1);
6727 + langwell->otg.state = OTG_STATE_A_IDLE;
6728 + queue_work(langwell->qwork, &langwell->work);
6729 + } else if (langwell->hsm.b_srp_init_tmout) {
6730 + langwell->hsm.b_srp_init_tmout = 0;
6731 + printk(KERN_WARNING "USB OTG: SRP init timeout\n");
6732 + } else if (langwell->hsm.b_srp_fail_tmout) {
6733 + langwell->hsm.b_srp_fail_tmout = 0;
6734 + langwell->hsm.b_bus_req = 0;
6735 + langwell_otg_nsf_msg(6);
6736 + } else if (langwell->hsm.b_sess_vld) {
6737 + langwell_otg_del_timer(b_srp_init_tmr);
6738 + del_timer_sync(&langwell->hsm_timer);
6739 + langwell->hsm.b_sess_end = 0;
6740 + langwell->hsm.a_bus_suspend = 0;
6741 + langwell_otg_chrg_vbus(0);
6742 + if (langwell->client_ops) {
6743 + langwell->client_ops->resume(langwell->pdev);
6744 + langwell->otg.state = OTG_STATE_B_PERIPHERAL;
6746 + otg_dbg("client driver not loaded.\n");
6748 + } else if (langwell->hsm.b_bus_req &&
6749 + (langwell->hsm.b_sess_end)) {
6750 + del_timer_sync(&langwell->hsm_timer);
6751 + /* workaround for b_se0_srp detection */
6752 + retval = langwell_otg_check_se0_srp(0);
6754 + langwell->hsm.b_bus_req = 0;
6755 + otg_dbg("LS is not SE0, try again later\n");
6757 + /* clear the PHCD before start srp */
6758 + langwell_otg_phy_low_power(0);
6761 + langwell_otg_add_timer(b_srp_init_tmr);
6762 + langwell_otg_start_srp(&langwell->otg);
6763 + langwell_otg_del_timer(b_srp_init_tmr);
6764 + langwell_otg_add_ktimer(TB_SRP_FAIL_TMR);
6766 + /* reset PHY low power mode here */
6767 + langwell_otg_phy_low_power_wait(1);
6771 + case OTG_STATE_B_SRP_INIT:
6772 + if (!langwell->hsm.id) {
6773 + langwell->otg.default_a = 1;
6774 + langwell->hsm.a_srp_det = 0;
6775 + langwell_otg_drv_vbus(0);
6776 + langwell_otg_chrg_vbus(0);
6778 + langwell_otg_phy_low_power(1);
6779 + langwell->otg.state = OTG_STATE_A_IDLE;
6780 + queue_work(langwell->qwork, &langwell->work);
6781 + } else if (langwell->hsm.b_sess_vld) {
6782 + langwell_otg_chrg_vbus(0);
6783 + if (langwell->client_ops) {
6784 + langwell->client_ops->resume(langwell->pdev);
6785 + langwell->otg.state = OTG_STATE_B_PERIPHERAL;
6787 + otg_dbg("client driver not loaded.\n");
6790 + case OTG_STATE_B_PERIPHERAL:
6791 + if (!langwell->hsm.id) {
6792 + langwell->otg.default_a = 1;
6793 + langwell->hsm.a_srp_det = 0;
6795 + langwell_otg_chrg_vbus(0);
6797 + if (langwell->client_ops) {
6798 + langwell->client_ops->suspend(langwell->pdev,
6801 + otg_dbg("client driver has been removed.\n");
6804 + langwell_otg_phy_low_power(1);
6805 + langwell->otg.state = OTG_STATE_A_IDLE;
6806 + queue_work(langwell->qwork, &langwell->work);
6807 + } else if (!langwell->hsm.b_sess_vld) {
6808 + langwell->hsm.b_hnp_enable = 0;
6810 + if (langwell->client_ops) {
6811 + langwell->client_ops->suspend(langwell->pdev,
6814 + otg_dbg("client driver has been removed.\n");
6816 + langwell->otg.state = OTG_STATE_B_IDLE;
6817 + } else if (langwell->hsm.b_bus_req && langwell->hsm.b_hnp_enable
6818 + && langwell->hsm.a_bus_suspend) {
6820 + if (langwell->client_ops) {
6821 + langwell->client_ops->suspend(langwell->pdev,
6824 + otg_dbg("client driver has been removed.\n");
6826 + langwell_otg_HAAR(1);
6827 + langwell->hsm.a_conn = 0;
6829 + if (langwell->host_ops) {
6830 + langwell->host_ops->probe(langwell->pdev,
6831 + langwell->host_ops->id_table);
6832 + langwell->otg.state = OTG_STATE_B_WAIT_ACON;
6834 + otg_dbg("host driver not loaded.\n");
6836 + langwell->hsm.a_bus_resume = 0;
6837 + langwell_otg_add_ktimer(TB_ASE0_BRST_TMR);
6841 + case OTG_STATE_B_WAIT_ACON:
6842 + if (!langwell->hsm.id) {
6843 + /* delete hsm timer for a_wait_bcon_tmr */
6844 + del_timer_sync(&langwell->hsm_timer);
6846 + langwell->otg.default_a = 1;
6847 + langwell->hsm.a_srp_det = 0;
6849 + langwell_otg_chrg_vbus(0);
6851 + langwell_otg_HAAR(0);
6852 + if (langwell->host_ops)
6853 + langwell->host_ops->remove(langwell->pdev);
6855 + otg_dbg("host driver has been removed.\n");
6858 + langwell_otg_phy_low_power(1);
6859 + langwell->otg.state = OTG_STATE_A_IDLE;
6860 + queue_work(langwell->qwork, &langwell->work);
6861 + } else if (!langwell->hsm.b_sess_vld) {
6862 + /* delete hsm timer for a_wait_bcon_tmr */
6863 + del_timer_sync(&langwell->hsm_timer);
6865 + langwell->hsm.b_hnp_enable = 0;
6866 + langwell->hsm.b_bus_req = 0;
6867 + langwell_otg_chrg_vbus(0);
6868 + langwell_otg_HAAR(0);
6870 + if (langwell->host_ops)
6871 + langwell->host_ops->remove(langwell->pdev);
6873 + otg_dbg("host driver has been removed.\n");
6875 + set_client_mode();
6876 + langwell_otg_phy_low_power(1);
6877 + langwell->otg.state = OTG_STATE_B_IDLE;
6878 + } else if (langwell->hsm.a_conn) {
6879 + /* delete hsm timer for a_wait_bcon_tmr */
6880 + del_timer_sync(&langwell->hsm_timer);
6882 + langwell_otg_HAAR(0);
6883 + langwell->otg.state = OTG_STATE_B_HOST;
6884 + queue_work(langwell->qwork, &langwell->work);
6885 + } else if (langwell->hsm.a_bus_resume ||
6886 + langwell->hsm.b_ase0_brst_tmout) {
6887 + /* delete hsm timer for a_wait_bcon_tmr */
6888 + del_timer_sync(&langwell->hsm_timer);
6890 + langwell_otg_HAAR(0);
6891 + langwell_otg_nsf_msg(7);
6893 + if (langwell->host_ops)
6894 + langwell->host_ops->remove(langwell->pdev);
6896 + otg_dbg("host driver has been removed.\n");
6898 + langwell->hsm.a_bus_suspend = 0;
6899 + langwell->hsm.b_bus_req = 0;
6901 + if (langwell->client_ops)
6902 + langwell->client_ops->resume(langwell->pdev);
6904 + otg_dbg("client driver not loaded.\n");
6906 + langwell->otg.state = OTG_STATE_B_PERIPHERAL;
6910 + case OTG_STATE_B_HOST:
6911 + if (!langwell->hsm.id) {
6912 + langwell->otg.default_a = 1;
6913 + langwell->hsm.a_srp_det = 0;
6915 + langwell_otg_chrg_vbus(0);
6916 + if (langwell->host_ops)
6917 + langwell->host_ops->remove(langwell->pdev);
6919 + otg_dbg("host driver has been removed.\n");
6922 + langwell_otg_phy_low_power(1);
6923 + langwell->otg.state = OTG_STATE_A_IDLE;
6924 + queue_work(langwell->qwork, &langwell->work);
6925 + } else if (!langwell->hsm.b_sess_vld) {
6926 + langwell->hsm.b_hnp_enable = 0;
6927 + langwell->hsm.b_bus_req = 0;
6928 + langwell_otg_chrg_vbus(0);
6929 + if (langwell->host_ops)
6930 + langwell->host_ops->remove(langwell->pdev);
6932 + otg_dbg("host driver has been removed.\n");
6934 + set_client_mode();
6935 + langwell_otg_phy_low_power(1);
6936 + langwell->otg.state = OTG_STATE_B_IDLE;
6937 + } else if ((!langwell->hsm.b_bus_req) ||
6938 + (!langwell->hsm.a_conn)) {
6939 + langwell->hsm.b_bus_req = 0;
6940 + langwell_otg_loc_sof(0);
6941 + if (langwell->host_ops)
6942 + langwell->host_ops->remove(langwell->pdev);
6944 + otg_dbg("host driver has been removed.\n");
6946 + langwell->hsm.a_bus_suspend = 0;
6948 + if (langwell->client_ops)
6949 + langwell->client_ops->resume(langwell->pdev);
6951 + otg_dbg("client driver not loaded.\n");
6953 + langwell->otg.state = OTG_STATE_B_PERIPHERAL;
6957 + case OTG_STATE_A_IDLE:
6958 + langwell->otg.default_a = 1;
6959 + if (langwell->hsm.id) {
6960 + langwell->otg.default_a = 0;
6961 + langwell->hsm.b_bus_req = 0;
6962 + langwell->hsm.vbus_srp_up = 0;
6963 + langwell_otg_chrg_vbus(0);
6964 + set_client_mode();
6965 + langwell_otg_phy_low_power(1);
6966 + langwell->otg.state = OTG_STATE_B_IDLE;
6967 + queue_work(langwell->qwork, &langwell->work);
6968 + } else if (!langwell->hsm.a_bus_drop &&
6969 + (langwell->hsm.a_srp_det || langwell->hsm.a_bus_req)) {
6970 + langwell_otg_phy_low_power(0);
6971 + langwell_otg_drv_vbus(1);
6972 + langwell->hsm.a_srp_det = 1;
6973 + langwell->hsm.vbus_srp_up = 0;
6974 + langwell->hsm.a_wait_vrise_tmout = 0;
6975 + langwell_otg_add_timer(a_wait_vrise_tmr);
6976 + langwell->otg.state = OTG_STATE_A_WAIT_VRISE;
6977 + queue_work(langwell->qwork, &langwell->work);
6978 + } else if (!langwell->hsm.a_bus_drop &&
6979 + langwell->hsm.a_sess_vld) {
6980 + langwell->hsm.vbus_srp_up = 1;
6981 + } else if (!langwell->hsm.a_sess_vld &&
6982 + langwell->hsm.vbus_srp_up) {
6984 + langwell_otg_phy_low_power(0);
6985 + langwell_otg_drv_vbus(1);
6986 + langwell->hsm.a_srp_det = 1;
6987 + langwell->hsm.vbus_srp_up = 0;
6988 + langwell->hsm.a_wait_vrise_tmout = 0;
6989 + langwell_otg_add_timer(a_wait_vrise_tmr);
6990 + langwell->otg.state = OTG_STATE_A_WAIT_VRISE;
6991 + queue_work(langwell->qwork, &langwell->work);
6992 + } else if (!langwell->hsm.a_sess_vld &&
6993 + !langwell->hsm.vbus_srp_up) {
6994 + langwell_otg_phy_low_power(1);
6997 + case OTG_STATE_A_WAIT_VRISE:
6998 + if (langwell->hsm.id) {
6999 + langwell_otg_del_timer(a_wait_vrise_tmr);
7000 + langwell->hsm.b_bus_req = 0;
7001 + langwell->otg.default_a = 0;
7002 + langwell_otg_drv_vbus(0);
7003 + set_client_mode();
7004 + langwell_otg_phy_low_power_wait(1);
7005 + langwell->otg.state = OTG_STATE_B_IDLE;
7006 + } else if (langwell->hsm.a_vbus_vld) {
7007 + langwell_otg_del_timer(a_wait_vrise_tmr);
7008 + if (langwell->host_ops)
7009 + langwell->host_ops->probe(langwell->pdev,
7010 + langwell->host_ops->id_table);
7012 + otg_dbg("host driver not loaded.\n");
7015 + langwell->hsm.b_conn = 0;
7016 + /* Replace HW timer with kernel timer */
7017 + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
7018 + langwell->otg.state = OTG_STATE_A_WAIT_BCON;
7019 + } else if (langwell->hsm.a_wait_vrise_tmout) {
7020 + if (langwell->hsm.a_vbus_vld) {
7021 + if (langwell->host_ops)
7022 + langwell->host_ops->probe(
7024 + langwell->host_ops->id_table);
7026 + otg_dbg("host driver not loaded.\n");
7029 + langwell->hsm.b_conn = 0;
7030 + /* change to kernel timer */
7031 + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
7032 + langwell->otg.state = OTG_STATE_A_WAIT_BCON;
7034 + langwell_otg_drv_vbus(0);
7035 + langwell_otg_phy_low_power_wait(1);
7036 + langwell->otg.state = OTG_STATE_A_VBUS_ERR;
7040 + case OTG_STATE_A_WAIT_BCON:
7041 + if (langwell->hsm.id) {
7042 + /* delete hsm timer for a_wait_bcon_tmr */
7043 + del_timer_sync(&langwell->hsm_timer);
7045 + langwell->otg.default_a = 0;
7046 + langwell->hsm.b_bus_req = 0;
7047 + if (langwell->host_ops)
7048 + langwell->host_ops->remove(langwell->pdev);
7050 + otg_dbg("host driver has been removed.\n");
7051 + langwell_otg_drv_vbus(0);
7052 + set_client_mode();
7053 + langwell_otg_phy_low_power_wait(1);
7054 + langwell->otg.state = OTG_STATE_B_IDLE;
7055 + queue_work(langwell->qwork, &langwell->work);
7056 + } else if (!langwell->hsm.a_vbus_vld) {
7057 + /* delete hsm timer for a_wait_bcon_tmr */
7058 + del_timer_sync(&langwell->hsm_timer);
7060 + if (langwell->host_ops)
7061 + langwell->host_ops->remove(langwell->pdev);
7063 + otg_dbg("host driver has been removed.\n");
7064 + langwell_otg_drv_vbus(0);
7065 + langwell_otg_phy_low_power_wait(1);
7066 + langwell->otg.state = OTG_STATE_A_VBUS_ERR;
7067 + } else if (langwell->hsm.a_bus_drop ||
7068 + (langwell->hsm.a_wait_bcon_tmout &&
7069 + !langwell->hsm.a_bus_req)) {
7070 + /* delete hsm timer for a_wait_bcon_tmr */
7071 + del_timer_sync(&langwell->hsm_timer);
7073 + if (langwell->host_ops)
7074 + langwell->host_ops->remove(langwell->pdev);
7076 + otg_dbg("host driver has been removed.\n");
7077 + langwell_otg_drv_vbus(0);
7078 + langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
7079 + } else if (langwell->hsm.b_conn) {
7080 + /* delete hsm timer for a_wait_bcon_tmr */
7081 + del_timer_sync(&langwell->hsm_timer);
7083 + langwell->hsm.a_suspend_req = 0;
7084 + langwell->otg.state = OTG_STATE_A_HOST;
7085 + if (langwell->hsm.a_srp_det &&
7086 + !langwell->otg.host->b_hnp_enable) {
7087 + /* SRP capable peripheral-only device */
7088 + langwell->hsm.a_bus_req = 1;
7089 + langwell->hsm.a_srp_det = 0;
7090 + } else if (!langwell->hsm.a_bus_req &&
7091 + langwell->otg.host->b_hnp_enable) {
7092 + /* It is not safe enough to do a fast
7093 + * transistion from A_WAIT_BCON to
7096 + if (langwell->hsm.a_bus_req)
7099 + if (request_irq(langwell->pdev->irq,
7100 + otg_dummy_irq, IRQF_SHARED,
7101 + driver_name, langwell->regs) != 0) {
7102 + otg_dbg("request interrupt %d fail\n",
7103 + langwell->pdev->irq);
7106 + langwell_otg_HABA(1);
7107 + langwell->hsm.b_bus_resume = 0;
7108 + langwell->hsm.a_aidl_bdis_tmout = 0;
7109 + langwell_otg_add_timer(a_aidl_bdis_tmr);
7111 + langwell_otg_loc_sof(0);
7112 + /* clear PHCD to enable HW timer */
7113 + langwell_otg_phy_low_power(0);
7114 + langwell->otg.state = OTG_STATE_A_SUSPEND;
7115 + } else if (!langwell->hsm.a_bus_req &&
7116 + !langwell->otg.host->b_hnp_enable) {
7117 + struct pci_dev *pdev = langwell->pdev;
7118 + if (langwell->host_ops)
7119 + langwell->host_ops->remove(pdev);
7121 + otg_dbg("host driver removed.\n");
7122 + langwell_otg_drv_vbus(0);
7123 + langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
7127 + case OTG_STATE_A_HOST:
7128 + if (langwell->hsm.id) {
7129 + langwell->otg.default_a = 0;
7130 + langwell->hsm.b_bus_req = 0;
7131 + if (langwell->host_ops)
7132 + langwell->host_ops->remove(langwell->pdev);
7134 + otg_dbg("host driver has been removed.\n");
7135 + langwell_otg_drv_vbus(0);
7136 + set_client_mode();
7137 + langwell_otg_phy_low_power_wait(1);
7138 + langwell->otg.state = OTG_STATE_B_IDLE;
7139 + queue_work(langwell->qwork, &langwell->work);
7140 + } else if (langwell->hsm.a_bus_drop ||
7141 + (!langwell->otg.host->b_hnp_enable &&
7142 + !langwell->hsm.a_bus_req)) {
7143 + if (langwell->host_ops)
7144 + langwell->host_ops->remove(langwell->pdev);
7146 + otg_dbg("host driver has been removed.\n");
7147 + langwell_otg_drv_vbus(0);
7148 + langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
7149 + } else if (!langwell->hsm.a_vbus_vld) {
7150 + if (langwell->host_ops)
7151 + langwell->host_ops->remove(langwell->pdev);
7153 + otg_dbg("host driver has been removed.\n");
7154 + langwell_otg_drv_vbus(0);
7155 + langwell_otg_phy_low_power_wait(1);
7156 + langwell->otg.state = OTG_STATE_A_VBUS_ERR;
7157 + } else if (langwell->otg.host->b_hnp_enable
7158 + && !langwell->hsm.a_bus_req) {
7159 + /* Set HABA to enable hardware assistance to signal
7160 + * A-connect after receiver B-disconnect. Hardware
7161 + * will then set client mode and enable URE, SLE and
7162 + * PCE after the assistance. otg_dummy_irq is used to
7163 + * clean these ints when client driver is not resumed.
7165 + if (request_irq(langwell->pdev->irq,
7166 + otg_dummy_irq, IRQF_SHARED, driver_name,
7167 + langwell->regs) != 0) {
7168 + otg_dbg("request interrupt %d failed\n",
7169 + langwell->pdev->irq);
7173 + langwell_otg_HABA(1);
7174 + langwell->hsm.b_bus_resume = 0;
7175 + langwell->hsm.a_aidl_bdis_tmout = 0;
7176 + langwell_otg_add_timer(a_aidl_bdis_tmr);
7177 + langwell_otg_loc_sof(0);
7178 + /* clear PHCD to enable HW timer */
7179 + langwell_otg_phy_low_power(0);
7180 + langwell->otg.state = OTG_STATE_A_SUSPEND;
7181 + } else if (!langwell->hsm.b_conn || !langwell->hsm.a_bus_req) {
7182 + langwell->hsm.a_wait_bcon_tmout = 0;
7183 + /* add kernel timer */
7184 + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
7185 + langwell->otg.state = OTG_STATE_A_WAIT_BCON;
7188 + case OTG_STATE_A_SUSPEND:
7189 + if (langwell->hsm.id) {
7190 + langwell_otg_del_timer(a_aidl_bdis_tmr);
7191 + langwell_otg_HABA(0);
7192 + free_irq(langwell->pdev->irq, langwell->regs);
7193 + langwell->otg.default_a = 0;
7194 + langwell->hsm.b_bus_req = 0;
7195 + if (langwell->host_ops)
7196 + langwell->host_ops->remove(langwell->pdev);
7198 + otg_dbg("host driver has been removed.\n");
7199 + langwell_otg_drv_vbus(0);
7200 + set_client_mode();
7201 + langwell_otg_phy_low_power(1);
7202 + langwell->otg.state = OTG_STATE_B_IDLE;
7203 + queue_work(langwell->qwork, &langwell->work);
7204 + } else if (langwell->hsm.a_bus_req ||
7205 + langwell->hsm.b_bus_resume) {
7206 + langwell_otg_del_timer(a_aidl_bdis_tmr);
7207 + langwell_otg_HABA(0);
7208 + free_irq(langwell->pdev->irq, langwell->regs);
7209 + langwell->hsm.a_suspend_req = 0;
7210 + langwell_otg_loc_sof(1);
7211 + langwell->otg.state = OTG_STATE_A_HOST;
7212 + } else if (langwell->hsm.a_aidl_bdis_tmout ||
7213 + langwell->hsm.a_bus_drop) {
7214 + langwell_otg_del_timer(a_aidl_bdis_tmr);
7215 + langwell_otg_HABA(0);
7216 + free_irq(langwell->pdev->irq, langwell->regs);
7217 + if (langwell->host_ops)
7218 + langwell->host_ops->remove(langwell->pdev);
7220 + otg_dbg("host driver has been removed.\n");
7221 + langwell_otg_drv_vbus(0);
7222 + langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
7223 + } else if (!langwell->hsm.b_conn &&
7224 + langwell->otg.host->b_hnp_enable) {
7225 + langwell_otg_del_timer(a_aidl_bdis_tmr);
7226 + langwell_otg_HABA(0);
7227 + free_irq(langwell->pdev->irq, langwell->regs);
7229 + if (langwell->host_ops)
7230 + langwell->host_ops->remove(langwell->pdev);
7232 + otg_dbg("host driver has been removed.\n");
7234 + langwell->hsm.b_bus_suspend = 0;
7235 + langwell->hsm.b_bus_suspend_vld = 0;
7237 + /* msleep(200); */
7238 + if (langwell->client_ops)
7239 + langwell->client_ops->resume(langwell->pdev);
7241 + otg_dbg("client driver not loaded.\n");
7243 + langwell_otg_add_ktimer(TB_BUS_SUSPEND_TMR);
7244 + langwell->otg.state = OTG_STATE_A_PERIPHERAL;
7246 + } else if (!langwell->hsm.a_vbus_vld) {
7247 + langwell_otg_del_timer(a_aidl_bdis_tmr);
7248 + langwell_otg_HABA(0);
7249 + free_irq(langwell->pdev->irq, langwell->regs);
7250 + if (langwell->host_ops)
7251 + langwell->host_ops->remove(langwell->pdev);
7253 + otg_dbg("host driver has been removed.\n");
7254 + langwell_otg_drv_vbus(0);
7255 + langwell_otg_phy_low_power_wait(1);
7256 + langwell->otg.state = OTG_STATE_A_VBUS_ERR;
7259 + case OTG_STATE_A_PERIPHERAL:
7260 + if (langwell->hsm.id) {
7261 + /* delete hsm timer for b_bus_suspend_tmr */
7262 + del_timer_sync(&langwell->hsm_timer);
7263 + langwell->otg.default_a = 0;
7264 + langwell->hsm.b_bus_req = 0;
7265 + if (langwell->client_ops)
7266 + langwell->client_ops->suspend(langwell->pdev,
7269 + otg_dbg("client driver has been removed.\n");
7270 + langwell_otg_drv_vbus(0);
7271 + set_client_mode();
7272 + langwell_otg_phy_low_power_wait(1);
7273 + langwell->otg.state = OTG_STATE_B_IDLE;
7274 + queue_work(langwell->qwork, &langwell->work);
7275 + } else if (!langwell->hsm.a_vbus_vld) {
7276 + /* delete hsm timer for b_bus_suspend_tmr */
7277 + del_timer_sync(&langwell->hsm_timer);
7278 + if (langwell->client_ops)
7279 + langwell->client_ops->suspend(langwell->pdev,
7282 + otg_dbg("client driver has been removed.\n");
7283 + langwell_otg_drv_vbus(0);
7284 + langwell_otg_phy_low_power_wait(1);
7285 + langwell->otg.state = OTG_STATE_A_VBUS_ERR;
7286 + } else if (langwell->hsm.a_bus_drop) {
7287 + /* delete hsm timer for b_bus_suspend_tmr */
7288 + del_timer_sync(&langwell->hsm_timer);
7289 + if (langwell->client_ops)
7290 + langwell->client_ops->suspend(langwell->pdev,
7293 + otg_dbg("client driver has been removed.\n");
7294 + langwell_otg_drv_vbus(0);
7295 + langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
7296 + } else if (langwell->hsm.b_bus_suspend) {
7297 + /* delete hsm timer for b_bus_suspend_tmr */
7298 + del_timer_sync(&langwell->hsm_timer);
7299 + if (langwell->client_ops)
7300 + langwell->client_ops->suspend(langwell->pdev,
7303 + otg_dbg("client driver has been removed.\n");
7304 + if (langwell->host_ops)
7305 + langwell->host_ops->probe(langwell->pdev,
7306 + langwell->host_ops->id_table);
7308 + otg_dbg("host driver not loaded.\n");
7309 + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
7310 + langwell->otg.state = OTG_STATE_A_WAIT_BCON;
7311 + } else if (langwell->hsm.b_bus_suspend_tmout) {
7313 + val = readl(langwell->regs + CI_PORTSC1);
7314 + if (!(val & PORTSC_SUSP))
7316 + if (langwell->client_ops)
7317 + langwell->client_ops->suspend(langwell->pdev,
7320 + otg_dbg("client driver has been removed.\n");
7321 + if (langwell->host_ops)
7322 + langwell->host_ops->probe(langwell->pdev,
7323 + langwell->host_ops->id_table);
7325 + otg_dbg("host driver not loaded.\n");
7326 + /* replaced with kernel timer */
7327 + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
7328 + langwell->otg.state = OTG_STATE_A_WAIT_BCON;
7331 + case OTG_STATE_A_VBUS_ERR:
7332 + if (langwell->hsm.id) {
7333 + langwell->otg.default_a = 0;
7334 + langwell->hsm.a_clr_err = 0;
7335 + langwell->hsm.a_srp_det = 0;
7336 + set_client_mode();
7337 + langwell_otg_phy_low_power(1);
7338 + langwell->otg.state = OTG_STATE_B_IDLE;
7339 + queue_work(langwell->qwork, &langwell->work);
7340 + } else if (langwell->hsm.a_clr_err) {
7341 + langwell->hsm.a_clr_err = 0;
7342 + langwell->hsm.a_srp_det = 0;
7345 + if (langwell->otg.state == OTG_STATE_A_IDLE)
7346 + queue_work(langwell->qwork, &langwell->work);
7348 + /* FIXME: Because FW will clear PHCD bit when any VBus
7349 + * event detected. Reset PHCD to 1 again */
7350 + langwell_otg_phy_low_power(1);
7353 + case OTG_STATE_A_WAIT_VFALL:
7354 + if (langwell->hsm.id) {
7355 + langwell->otg.default_a = 0;
7356 + set_client_mode();
7357 + langwell_otg_phy_low_power(1);
7358 + langwell->otg.state = OTG_STATE_B_IDLE;
7359 + queue_work(langwell->qwork, &langwell->work);
7360 + } else if (langwell->hsm.a_bus_req) {
7361 + langwell_otg_drv_vbus(1);
7362 + langwell->hsm.a_wait_vrise_tmout = 0;
7363 + langwell_otg_add_timer(a_wait_vrise_tmr);
7364 + langwell->otg.state = OTG_STATE_A_WAIT_VRISE;
7365 + } else if (!langwell->hsm.a_sess_vld) {
7366 + langwell->hsm.a_srp_det = 0;
7368 + langwell_otg_phy_low_power(1);
7369 + langwell->otg.state = OTG_STATE_A_IDLE;
7376 + otg_dbg("%s: new state = %s\n", __func__,
7377 + state_string(langwell->otg.state));
7381 +show_registers(struct device *_dev, struct device_attribute *attr, char *buf)
7383 + struct langwell_otg *langwell;
7388 + langwell = the_transceiver;
7392 + t = scnprintf(next, size,
7394 + "USBCMD = 0x%08x \n"
7395 + "USBSTS = 0x%08x \n"
7396 + "USBINTR = 0x%08x \n"
7397 + "ASYNCLISTADDR = 0x%08x \n"
7398 + "PORTSC1 = 0x%08x \n"
7399 + "HOSTPC1 = 0x%08x \n"
7400 + "OTGSC = 0x%08x \n"
7401 + "USBMODE = 0x%08x \n",
7402 + readl(langwell->regs + 0x30),
7403 + readl(langwell->regs + 0x34),
7404 + readl(langwell->regs + 0x38),
7405 + readl(langwell->regs + 0x48),
7406 + readl(langwell->regs + 0x74),
7407 + readl(langwell->regs + 0xb4),
7408 + readl(langwell->regs + 0xf4),
7409 + readl(langwell->regs + 0xf8)
7414 + return PAGE_SIZE - size;
7416 +static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
7419 +show_hsm(struct device *_dev, struct device_attribute *attr, char *buf)
7421 + struct langwell_otg *langwell;
7425 + enum usb_otg_state state;
7427 + langwell = the_transceiver;
7430 + state = langwell->otg.state;
7432 + /* Add a_set_b_hnp_en */
7433 + if (state == OTG_STATE_A_HOST || state == OTG_STATE_A_SUSPEND)
7434 + langwell->hsm.a_set_b_hnp_en = langwell->otg.host->b_hnp_enable;
7436 + langwell->hsm.a_set_b_hnp_en = 0;
7438 + t = scnprintf(next, size,
7440 + "current state = %s\n"
7441 + "a_bus_resume = \t%d\n"
7442 + "a_bus_suspend = \t%d\n"
7444 + "a_sess_vld = \t%d\n"
7445 + "a_srp_det = \t%d\n"
7446 + "a_vbus_vld = \t%d\n"
7447 + "b_bus_resume = \t%d\n"
7448 + "b_bus_suspend = \t%d\n"
7450 + "b_se0_srp = \t%d\n"
7451 + "b_sess_end = \t%d\n"
7452 + "b_sess_vld = \t%d\n"
7454 + "a_set_b_hnp_en = \t%d\n"
7455 + "b_srp_done = \t%d\n"
7456 + "b_hnp_enable = \t%d\n"
7457 + "a_wait_vrise_tmout = \t%d\n"
7458 + "a_wait_bcon_tmout = \t%d\n"
7459 + "a_aidl_bdis_tmout = \t%d\n"
7460 + "b_ase0_brst_tmout = \t%d\n"
7461 + "a_bus_drop = \t%d\n"
7462 + "a_bus_req = \t%d\n"
7463 + "a_clr_err = \t%d\n"
7464 + "a_suspend_req = \t%d\n"
7465 + "b_bus_req = \t%d\n"
7466 + "b_bus_suspend_tmout = \t%d\n"
7467 + "b_bus_suspend_vld = \t%d\n",
7468 + state_string(langwell->otg.state),
7469 + langwell->hsm.a_bus_resume,
7470 + langwell->hsm.a_bus_suspend,
7471 + langwell->hsm.a_conn,
7472 + langwell->hsm.a_sess_vld,
7473 + langwell->hsm.a_srp_det,
7474 + langwell->hsm.a_vbus_vld,
7475 + langwell->hsm.b_bus_resume,
7476 + langwell->hsm.b_bus_suspend,
7477 + langwell->hsm.b_conn,
7478 + langwell->hsm.b_se0_srp,
7479 + langwell->hsm.b_sess_end,
7480 + langwell->hsm.b_sess_vld,
7482 + langwell->hsm.a_set_b_hnp_en,
7483 + langwell->hsm.b_srp_done,
7484 + langwell->hsm.b_hnp_enable,
7485 + langwell->hsm.a_wait_vrise_tmout,
7486 + langwell->hsm.a_wait_bcon_tmout,
7487 + langwell->hsm.a_aidl_bdis_tmout,
7488 + langwell->hsm.b_ase0_brst_tmout,
7489 + langwell->hsm.a_bus_drop,
7490 + langwell->hsm.a_bus_req,
7491 + langwell->hsm.a_clr_err,
7492 + langwell->hsm.a_suspend_req,
7493 + langwell->hsm.b_bus_req,
7494 + langwell->hsm.b_bus_suspend_tmout,
7495 + langwell->hsm.b_bus_suspend_vld
7500 + return PAGE_SIZE - size;
7502 +static DEVICE_ATTR(hsm, S_IRUGO, show_hsm, NULL);
7505 +get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
7507 + struct langwell_otg *langwell;
7512 + langwell = the_transceiver;
7516 + t = scnprintf(next, size, "%d", langwell->hsm.a_bus_req);
7520 + return PAGE_SIZE - size;
7524 +set_a_bus_req(struct device *dev, struct device_attribute *attr,
7525 + const char *buf, size_t count)
7527 + struct langwell_otg *langwell;
7528 + langwell = the_transceiver;
7529 + if (!langwell->otg.default_a)
7534 + if (buf[0] == '0') {
7535 + langwell->hsm.a_bus_req = 0;
7536 + otg_dbg("a_bus_req = 0\n");
7537 + } else if (buf[0] == '1') {
7538 + /* If a_bus_drop is TRUE, a_bus_req can't be set */
7539 + if (langwell->hsm.a_bus_drop)
7541 + langwell->hsm.a_bus_req = 1;
7542 + otg_dbg("a_bus_req = 1\n");
7545 + langwell_update_transceiver();
7549 +static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUGO, get_a_bus_req, set_a_bus_req);
7552 +get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf)
7554 + struct langwell_otg *langwell;
7559 + langwell = the_transceiver;
7563 + t = scnprintf(next, size, "%d", langwell->hsm.a_bus_drop);
7567 + return PAGE_SIZE - size;
7571 +set_a_bus_drop(struct device *dev, struct device_attribute *attr,
7572 + const char *buf, size_t count)
7574 + struct langwell_otg *langwell;
7575 + langwell = the_transceiver;
7576 + if (!langwell->otg.default_a)
7581 + if (buf[0] == '0') {
7582 + langwell->hsm.a_bus_drop = 0;
7583 + otg_dbg("a_bus_drop = 0\n");
7584 + } else if (buf[0] == '1') {
7585 + langwell->hsm.a_bus_drop = 1;
7586 + langwell->hsm.a_bus_req = 0;
7587 + otg_dbg("a_bus_drop = 1, then a_bus_req = 0\n");
7590 + langwell_update_transceiver();
7594 +static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUGO,
7595 + get_a_bus_drop, set_a_bus_drop);
7598 +get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
7600 + struct langwell_otg *langwell;
7605 + langwell = the_transceiver;
7609 + t = scnprintf(next, size, "%d", langwell->hsm.b_bus_req);
7613 + return PAGE_SIZE - size;
7617 +set_b_bus_req(struct device *dev, struct device_attribute *attr,
7618 + const char *buf, size_t count)
7620 + struct langwell_otg *langwell;
7621 + langwell = the_transceiver;
7623 + if (langwell->otg.default_a)
7629 + if (buf[0] == '0') {
7630 + langwell->hsm.b_bus_req = 0;
7631 + otg_dbg("b_bus_req = 0\n");
7632 + } else if (buf[0] == '1') {
7633 + langwell->hsm.b_bus_req = 1;
7634 + otg_dbg("b_bus_req = 1\n");
7637 + langwell_update_transceiver();
7641 +static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUGO, get_b_bus_req, set_b_bus_req);
7644 +set_a_clr_err(struct device *dev, struct device_attribute *attr,
7645 + const char *buf, size_t count)
7647 + struct langwell_otg *langwell;
7648 + langwell = the_transceiver;
7650 + if (!langwell->otg.default_a)
7655 + if (buf[0] == '1') {
7656 + langwell->hsm.a_clr_err = 1;
7657 + otg_dbg("a_clr_err = 1\n");
7660 + langwell_update_transceiver();
7664 +static DEVICE_ATTR(a_clr_err, S_IWUGO, NULL, set_a_clr_err);
7666 +static struct attribute *inputs_attrs[] = {
7667 + &dev_attr_a_bus_req.attr,
7668 + &dev_attr_a_bus_drop.attr,
7669 + &dev_attr_b_bus_req.attr,
7670 + &dev_attr_a_clr_err.attr,
7674 +static struct attribute_group debug_dev_attr_group = {
7676 + .attrs = inputs_attrs,
7679 +int langwell_register_host(struct pci_driver *host_driver)
7683 + the_transceiver->host_ops = host_driver;
7684 + queue_work(the_transceiver->qwork, &the_transceiver->work);
7685 + otg_dbg("host controller driver is registered\n");
7689 +EXPORT_SYMBOL(langwell_register_host);
7691 +void langwell_unregister_host(struct pci_driver *host_driver)
7693 + if (the_transceiver->host_ops)
7694 + the_transceiver->host_ops->remove(the_transceiver->pdev);
7695 + the_transceiver->host_ops = NULL;
7696 + the_transceiver->hsm.a_bus_drop = 1;
7697 + queue_work(the_transceiver->qwork, &the_transceiver->work);
7698 + otg_dbg("host controller driver is unregistered\n");
7700 +EXPORT_SYMBOL(langwell_unregister_host);
7702 +int langwell_register_peripheral(struct pci_driver *client_driver)
7706 + if (client_driver)
7707 + ret = client_driver->probe(the_transceiver->pdev,
7708 + client_driver->id_table);
7710 + the_transceiver->client_ops = client_driver;
7711 + queue_work(the_transceiver->qwork, &the_transceiver->work);
7712 + otg_dbg("client controller driver is registered\n");
7717 +EXPORT_SYMBOL(langwell_register_peripheral);
7719 +void langwell_unregister_peripheral(struct pci_driver *client_driver)
7721 + if (the_transceiver->client_ops)
7722 + the_transceiver->client_ops->remove(the_transceiver->pdev);
7723 + the_transceiver->client_ops = NULL;
7724 + the_transceiver->hsm.b_bus_req = 0;
7725 + queue_work(the_transceiver->qwork, &the_transceiver->work);
7726 + otg_dbg("client controller driver is unregistered\n");
7728 +EXPORT_SYMBOL(langwell_unregister_peripheral);
7730 +static int langwell_otg_probe(struct pci_dev *pdev,
7731 + const struct pci_device_id *id)
7733 + unsigned long resource, len;
7734 + void __iomem *base = NULL;
7737 + struct langwell_otg *langwell;
7738 + char qname[] = "langwell_otg_queue";
7741 + otg_dbg("\notg controller is detected.\n");
7742 + if (pci_enable_device(pdev) < 0) {
7747 + langwell = kzalloc(sizeof *langwell, GFP_KERNEL);
7748 + if (langwell == NULL) {
7752 + the_transceiver = langwell;
7754 + /* control register: BAR 0 */
7755 + resource = pci_resource_start(pdev, 0);
7756 + len = pci_resource_len(pdev, 0);
7757 + if (!request_mem_region(resource, len, driver_name)) {
7761 + langwell->region = 1;
7763 + base = ioremap_nocache(resource, len);
7764 + if (base == NULL) {
7768 + langwell->regs = base;
7770 + if (!request_mem_region(USBCFG_ADDR, USBCFG_LEN, driver_name)) {
7774 + langwell->cfg_region = 1;
7776 + /* For the SCCB.USBCFG register */
7777 + base = ioremap_nocache(USBCFG_ADDR, USBCFG_LEN);
7778 + if (base == NULL) {
7782 + langwell->usbcfg = base;
7785 + otg_dbg("No IRQ.\n");
7790 + langwell->qwork = create_singlethread_workqueue(qname);
7791 + if (!langwell->qwork) {
7792 + otg_dbg("cannot create workqueue %s\n", qname);
7796 + INIT_WORK(&langwell->work, langwell_otg_work);
7798 + /* OTG common part */
7799 + langwell->pdev = pdev;
7800 + langwell->otg.dev = &pdev->dev;
7801 + langwell->otg.label = driver_name;
7802 + langwell->otg.set_host = langwell_otg_set_host;
7803 + langwell->otg.set_peripheral = langwell_otg_set_peripheral;
7804 + langwell->otg.set_power = langwell_otg_set_power;
7805 + langwell->otg.start_srp = langwell_otg_start_srp;
7806 + langwell->otg.state = OTG_STATE_UNDEFINED;
7807 + if (otg_set_transceiver(&langwell->otg)) {
7808 + otg_dbg("can't set transceiver\n");
7816 + spin_lock_init(&langwell->lock);
7817 + spin_lock_init(&langwell->wq_lock);
7818 + INIT_LIST_HEAD(&active_timers);
7819 + langwell_otg_init_timers(&langwell->hsm);
7820 + init_timer(&langwell->hsm_timer);
7822 + if (request_irq(pdev->irq, otg_irq, IRQF_SHARED,
7823 + driver_name, langwell) != 0) {
7824 + otg_dbg("request interrupt %d failed\n", pdev->irq);
7829 + /* enable OTGSC int */
7830 + val32 = OTGSC_DPIE | OTGSC_BSEIE | OTGSC_BSVIE |
7831 + OTGSC_ASVIE | OTGSC_AVVIE | OTGSC_IDIE | OTGSC_IDPU;
7832 + writel(val32, langwell->regs + CI_OTGSC);
7834 + retval = device_create_file(&pdev->dev, &dev_attr_registers);
7836 + otg_dbg("Can't register sysfs attribute: %d\n", retval);
7840 + retval = device_create_file(&pdev->dev, &dev_attr_hsm);
7842 + otg_dbg("Can't hsm sysfs attribute: %d\n", retval);
7846 + retval = sysfs_create_group(&pdev->dev.kobj, &debug_dev_attr_group);
7848 + otg_dbg("Can't register sysfs attr group: %d\n", retval);
7852 + if (langwell->otg.state == OTG_STATE_A_IDLE)
7853 + queue_work(langwell->qwork, &langwell->work);
7858 + if (the_transceiver)
7859 + langwell_otg_remove(pdev);
7864 +static void langwell_otg_remove(struct pci_dev *pdev)
7866 + struct langwell_otg *langwell;
7868 + langwell = the_transceiver;
7870 + if (langwell->qwork) {
7871 + flush_workqueue(langwell->qwork);
7872 + destroy_workqueue(langwell->qwork);
7874 + langwell_otg_free_timers();
7876 + /* disable OTGSC interrupt as OTGSC doesn't change in reset */
7877 + writel(0, langwell->regs + CI_OTGSC);
7880 + free_irq(pdev->irq, langwell);
7881 + if (langwell->usbcfg)
7882 + iounmap(langwell->usbcfg);
7883 + if (langwell->cfg_region)
7884 + release_mem_region(USBCFG_ADDR, USBCFG_LEN);
7885 + if (langwell->regs)
7886 + iounmap(langwell->regs);
7887 + if (langwell->region)
7888 + release_mem_region(pci_resource_start(pdev, 0),
7889 + pci_resource_len(pdev, 0));
7891 + otg_set_transceiver(NULL);
7892 + pci_disable_device(pdev);
7893 + sysfs_remove_group(&pdev->dev.kobj, &debug_dev_attr_group);
7894 + device_remove_file(&pdev->dev, &dev_attr_hsm);
7895 + device_remove_file(&pdev->dev, &dev_attr_registers);
7900 +static void transceiver_suspend(struct pci_dev *pdev)
7902 + pci_save_state(pdev);
7903 + pci_set_power_state(pdev, PCI_D3hot);
7904 + langwell_otg_phy_low_power(1);
7907 +static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message)
7909 + struct langwell_otg *langwell;
7910 + struct pci_driver *ops;
7913 + langwell = the_transceiver;
7915 + /* Disbale OTG interrupts */
7916 + langwell_otg_intr(0);
7919 + free_irq(pdev->irq, langwell);
7921 + /* Prevent more otg_work */
7922 + flush_workqueue(langwell->qwork);
7923 + destroy_workqueue(langwell->qwork);
7924 + langwell->qwork = NULL;
7926 + /* start actions */
7927 + switch (langwell->otg.state) {
7928 + case OTG_STATE_A_WAIT_VFALL:
7929 + langwell->otg.state = OTG_STATE_A_IDLE;
7930 + case OTG_STATE_A_IDLE:
7931 + case OTG_STATE_A_VBUS_ERR:
7932 + case OTG_STATE_B_IDLE:
7933 + transceiver_suspend(pdev);
7935 + case OTG_STATE_A_WAIT_VRISE:
7936 + langwell_otg_del_timer(a_wait_vrise_tmr);
7937 + langwell->hsm.a_srp_det = 0;
7938 + langwell_otg_drv_vbus(0);
7939 + langwell->otg.state = OTG_STATE_A_IDLE;
7940 + transceiver_suspend(pdev);
7942 + case OTG_STATE_A_WAIT_BCON:
7943 + del_timer_sync(&langwell->hsm_timer);
7944 + ops = langwell->host_ops;
7946 + switch (message.event) {
7947 + case PM_EVENT_SUSPEND:
7948 + if (ops && ops->driver.pm && ops->driver.pm->suspend)
7949 + ret = ops->driver.pm->suspend(&pdev->dev);
7951 + case PM_EVENT_FREEZE:
7952 + if (ops && ops->driver.pm && ops->driver.pm->freeze)
7953 + ret = ops->driver.pm->freeze(&pdev->dev);
7955 + case PM_EVENT_HIBERNATE:
7956 + if (ops && ops->driver.pm && ops->driver.pm->poweroff)
7957 + ret = ops->driver.pm->poweroff(&pdev->dev);
7960 + otg_dbg("not suspend/freeze/hibernate pm event\n");
7966 + otg_dbg("pm suspend function error = %d\n", ret);
7967 + /* restart timer */
7968 + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
7972 + if (ops && ops->remove)
7973 + ops->remove(pdev);
7975 + otg_dbg("host driver has been removed.\n");
7977 + langwell->hsm.a_srp_det = 0;
7978 + langwell_otg_drv_vbus(0);
7979 + langwell->otg.state = OTG_STATE_A_IDLE;
7980 + transceiver_suspend(pdev);
7982 + case OTG_STATE_A_HOST:
7983 + ops = langwell->host_ops;
7985 + switch (message.event) {
7986 + case PM_EVENT_SUSPEND:
7987 + if (ops && ops->driver.pm && ops->driver.pm->suspend)
7988 + ret = ops->driver.pm->suspend(&pdev->dev);
7990 + case PM_EVENT_FREEZE:
7991 + if (ops && ops->driver.pm && ops->driver.pm->freeze)
7992 + ret = ops->driver.pm->freeze(&pdev->dev);
7994 + case PM_EVENT_HIBERNATE:
7995 + if (ops && ops->driver.pm && ops->driver.pm->poweroff)
7996 + ret = ops->driver.pm->poweroff(&pdev->dev);
7999 + otg_dbg("not suspend/freeze/hibernate pm event\n");
8005 + otg_dbg("pm suspend function error = %d\n", ret);
8009 + if (ops && ops->remove)
8010 + ops->remove(pdev);
8012 + otg_dbg("host driver has been removed.\n");
8014 + langwell->hsm.a_srp_det = 0;
8015 + langwell_otg_drv_vbus(0);
8016 + langwell->otg.state = OTG_STATE_A_IDLE;
8017 + transceiver_suspend(pdev);
8019 + case OTG_STATE_A_SUSPEND:
8020 + langwell_otg_del_timer(a_aidl_bdis_tmr);
8021 + langwell_otg_HABA(0);
8022 + if (langwell->host_ops && langwell->host_ops->remove)
8023 + langwell->host_ops->remove(pdev);
8025 + otg_dbg("host driver has been removed.\n");
8026 + langwell->hsm.a_srp_det = 0;
8027 + langwell_otg_drv_vbus(0);
8028 + langwell->otg.state = OTG_STATE_A_IDLE;
8029 + transceiver_suspend(pdev);
8031 + case OTG_STATE_A_PERIPHERAL:
8032 + del_timer_sync(&langwell->hsm_timer);
8033 + if (langwell->client_ops && langwell->client_ops->suspend)
8034 + ret = langwell->client_ops->suspend(pdev, message);
8036 + otg_dbg("client driver has been removed.\n");
8039 + otg_dbg("pm suspend function error = %d\n", ret);
8043 + langwell_otg_drv_vbus(0);
8044 + langwell->hsm.a_srp_det = 0;
8045 + langwell->otg.state = OTG_STATE_A_IDLE;
8046 + transceiver_suspend(pdev);
8048 + case OTG_STATE_B_HOST:
8049 + if (langwell->host_ops && langwell->host_ops->remove)
8050 + langwell->host_ops->remove(pdev);
8052 + otg_dbg("host driver has been removed.\n");
8053 + langwell->hsm.b_bus_req = 0;
8054 + langwell->otg.state = OTG_STATE_B_IDLE;
8055 + transceiver_suspend(pdev);
8057 + case OTG_STATE_B_PERIPHERAL:
8058 + if (langwell->client_ops && langwell->client_ops->suspend)
8059 + ret = langwell->client_ops->suspend(pdev, message);
8061 + otg_dbg("client driver has been removed.\n");
8064 + otg_dbg("pm suspend function error = %d\n", ret);
8068 + langwell->otg.state = OTG_STATE_B_IDLE;
8069 + transceiver_suspend(pdev);
8071 + case OTG_STATE_B_WAIT_ACON:
8072 + /* delete hsm timer for b_ase0_brst_tmr */
8073 + del_timer_sync(&langwell->hsm_timer);
8075 + langwell_otg_HAAR(0);
8076 + if (langwell->host_ops && langwell->host_ops->remove)
8077 + langwell->host_ops->remove(pdev);
8079 + otg_dbg("host driver has been removed.\n");
8080 + langwell->hsm.b_bus_req = 0;
8081 + langwell->otg.state = OTG_STATE_B_IDLE;
8082 + transceiver_suspend(pdev);
8085 + otg_dbg("error state before suspend\n ");
8091 + langwell->qwork = create_singlethread_workqueue("langwell_otg_queue");
8092 + if (!langwell->qwork) {
8093 + otg_dbg("cannot create workqueue langwell_otg_queue\n");
8097 + if (request_irq(pdev->irq, otg_irq, IRQF_SHARED,
8098 + driver_name, the_transceiver) != 0) {
8099 + otg_dbg("request interrupt %d failed\n", pdev->irq);
8103 + /* enable OTG interrupts */
8104 + langwell_otg_intr(1);
8109 +static void transceiver_resume(struct pci_dev *pdev)
8111 + pci_restore_state(pdev);
8112 + pci_set_power_state(pdev, PCI_D0);
8115 +static int langwell_otg_resume(struct pci_dev *pdev)
8117 + struct langwell_otg *langwell;
8120 + langwell = the_transceiver;
8122 + transceiver_resume(pdev);
8124 + langwell->qwork = create_singlethread_workqueue("langwell_otg_queue");
8125 + if (!langwell->qwork) {
8126 + otg_dbg("cannot create workqueue langwell_otg_queue\n");
8131 + if (request_irq(pdev->irq, otg_irq, IRQF_SHARED,
8132 + driver_name, the_transceiver) != 0) {
8133 + otg_dbg("request interrupt %d failed\n", pdev->irq);
8138 + /* enable OTG interrupts */
8139 + langwell_otg_intr(1);
8143 + langwell_update_transceiver();
8147 + langwell_otg_intr(0);
8148 + transceiver_suspend(pdev);
8152 +static int __init langwell_otg_init(void)
8154 + return pci_register_driver(&otg_pci_driver);
8156 +module_init(langwell_otg_init);
8158 +static void __exit langwell_otg_cleanup(void)
8160 + pci_unregister_driver(&otg_pci_driver);
8162 +module_exit(langwell_otg_cleanup);
8163 diff --git a/include/linux/usb/langwell_otg.h b/include/linux/usb/langwell_otg.h
8164 new file mode 100644
8165 index 0000000..cbb204b
8167 +++ b/include/linux/usb/langwell_otg.h
8170 + * Intel Langwell USB OTG transceiver driver
8171 + * Copyright (C) 2008, Intel Corporation.
8173 + * This program is free software; you can redistribute it and/or modify it
8174 + * under the terms and conditions of the GNU General Public License,
8175 + * version 2, as published by the Free Software Foundation.
8177 + * This program is distributed in the hope it will be useful, but WITHOUT
8178 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8179 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
8182 + * You should have received a copy of the GNU General Public License along with
8183 + * this program; if not, write to the Free Software Foundation, Inc.,
8184 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
8188 +#ifndef __LANGWELL_OTG_H__
8189 +#define __LANGWELL_OTG_H__
8191 +/* notify transceiver driver about OTG events */
8192 +extern void langwell_update_transceiver(void);
8193 +/* HCD register bus driver */
8194 +extern int langwell_register_host(struct pci_driver *host_driver);
8195 +/* HCD unregister bus driver */
8196 +extern void langwell_unregister_host(struct pci_driver *host_driver);
8197 +/* DCD register bus driver */
8198 +extern int langwell_register_peripheral(struct pci_driver *client_driver);
8199 +/* DCD unregister bus driver */
8200 +extern void langwell_unregister_peripheral(struct pci_driver *client_driver);
8201 +/* No silent failure, output warning message */
8202 +extern void langwell_otg_nsf_msg(unsigned long message);
8204 +#define CI_USBCMD 0x30
8205 +# define USBCMD_RST BIT(1)
8206 +# define USBCMD_RS BIT(0)
8207 +#define CI_USBSTS 0x34
8208 +# define USBSTS_SLI BIT(8)
8209 +# define USBSTS_URI BIT(6)
8210 +# define USBSTS_PCI BIT(2)
8211 +#define CI_PORTSC1 0x74
8212 +# define PORTSC_PP BIT(12)
8213 +# define PORTSC_LS (BIT(11) | BIT(10))
8214 +# define PORTSC_SUSP BIT(7)
8215 +# define PORTSC_CCS BIT(0)
8216 +#define CI_HOSTPC1 0xb4
8217 +# define HOSTPC1_PHCD BIT(22)
8218 +#define CI_OTGSC 0xf4
8219 +# define OTGSC_DPIE BIT(30)
8220 +# define OTGSC_1MSE BIT(29)
8221 +# define OTGSC_BSEIE BIT(28)
8222 +# define OTGSC_BSVIE BIT(27)
8223 +# define OTGSC_ASVIE BIT(26)
8224 +# define OTGSC_AVVIE BIT(25)
8225 +# define OTGSC_IDIE BIT(24)
8226 +# define OTGSC_DPIS BIT(22)
8227 +# define OTGSC_1MSS BIT(21)
8228 +# define OTGSC_BSEIS BIT(20)
8229 +# define OTGSC_BSVIS BIT(19)
8230 +# define OTGSC_ASVIS BIT(18)
8231 +# define OTGSC_AVVIS BIT(17)
8232 +# define OTGSC_IDIS BIT(16)
8233 +# define OTGSC_DPS BIT(14)
8234 +# define OTGSC_1MST BIT(13)
8235 +# define OTGSC_BSE BIT(12)
8236 +# define OTGSC_BSV BIT(11)
8237 +# define OTGSC_ASV BIT(10)
8238 +# define OTGSC_AVV BIT(9)
8239 +# define OTGSC_ID BIT(8)
8240 +# define OTGSC_HABA BIT(7)
8241 +# define OTGSC_HADP BIT(6)
8242 +# define OTGSC_IDPU BIT(5)
8243 +# define OTGSC_DP BIT(4)
8244 +# define OTGSC_OT BIT(3)
8245 +# define OTGSC_HAAR BIT(2)
8246 +# define OTGSC_VC BIT(1)
8247 +# define OTGSC_VD BIT(0)
8248 +# define OTGSC_INTEN_MASK (0x7f << 24)
8249 +# define OTGSC_INT_MASK (0x5f << 24)
8250 +# define OTGSC_INTSTS_MASK (0x7f << 16)
8251 +#define CI_USBMODE 0xf8
8252 +# define USBMODE_CM (BIT(1) | BIT(0))
8253 +# define USBMODE_IDLE 0
8254 +# define USBMODE_DEVICE 0x2
8255 +# define USBMODE_HOST 0x3
8256 +#define USBCFG_ADDR 0xff10801c
8257 +#define USBCFG_LEN 4
8258 +# define USBCFG_VBUSVAL BIT(14)
8259 +# define USBCFG_AVALID BIT(13)
8260 +# define USBCFG_BVALID BIT(12)
8261 +# define USBCFG_SESEND BIT(11)
8263 +#define INTR_DUMMY_MASK (USBSTS_SLI | USBSTS_URI | USBSTS_PCI)
8268 + int a_bus_suspend;
8274 + int b_bus_suspend;
8281 + /* Internal variables */
8282 + int a_set_b_hnp_en;
8286 + /* Timeout indicator for timers */
8287 + int a_wait_vrise_tmout;
8288 + int a_wait_bcon_tmout;
8289 + int a_aidl_bdis_tmout;
8290 + int b_ase0_brst_tmout;
8291 + int b_bus_suspend_tmout;
8292 + int b_srp_init_tmout;
8293 + int b_srp_fail_tmout;
8295 + /* Informative variables */
8299 + int a_suspend_req;
8308 + int b_bus_suspend_vld;
8312 +enum langwell_otg_timer_type {
8313 + TA_WAIT_VRISE_TMR,
8320 + TB_BUS_SUSPEND_TMR
8323 +#define TA_WAIT_VRISE 100
8324 +#define TA_WAIT_BCON 30000
8325 +#define TA_AIDL_BDIS 15000
8326 +#define TB_ASE0_BRST 5000
8327 +#define TB_SE0_SRP 2
8328 +#define TB_SRP_INIT 100
8329 +#define TB_SRP_FAIL 5500
8330 +#define TB_BUS_SUSPEND 500
8332 +struct langwell_otg_timer {
8333 + unsigned long expires; /* Number of count increase to timeout */
8334 + unsigned long count; /* Tick counter */
8335 + void (*function)(unsigned long); /* Timeout function */
8336 + unsigned long data; /* Data passed to function */
8337 + struct list_head list;
8340 +struct langwell_otg {
8341 + struct otg_transceiver otg;
8342 + struct otg_hsm hsm;
8343 + void __iomem *regs;
8344 + void __iomem *usbcfg; /* SCCB USB config Reg */
8346 + unsigned cfg_region;
8347 + struct pci_driver *host_ops;
8348 + struct pci_driver *client_ops;
8349 + struct pci_dev *pdev;
8350 + struct work_struct work;
8351 + struct workqueue_struct *qwork;
8352 + struct timer_list hsm_timer;
8354 + spinlock_t wq_lock;
8357 +static inline struct langwell_otg *otg_to_langwell(struct otg_transceiver *otg)
8359 + return container_of(otg, struct langwell_otg, otg);
8363 +#define otg_dbg(fmt, args...) \
8364 + printk(KERN_DEBUG fmt , ## args)
8366 +#define otg_dbg(fmt, args...) \
8369 +#endif /* __LANGWELL_OTG_H__ */
8370 diff --git a/include/linux/usb/langwell_udc.h b/include/linux/usb/langwell_udc.h
8371 index c949178..fe2c698 100644
8372 --- a/include/linux/usb/langwell_udc.h
8373 +++ b/include/linux/usb/langwell_udc.h
8374 @@ -306,5 +306,18 @@ struct langwell_op_regs {
8375 #define EPCTRL_RXS BIT(0) /* RX endpoint STALL */
8376 } __attribute__ ((packed));
8379 +/* export function declaration */
8381 +/* gets the maximum power consumption */
8382 +extern int langwell_udc_maxpower(int *mA);
8384 +/* return errors of langwell_udc_maxpower() */
8386 +#define EOTGNODEVICE 2
8387 +#define EOTGCHARGER 3
8388 +#define EOTGDISCONN 4
8389 +#define EOTGINVAL 5
8391 #endif /* __LANGWELL_UDC_H */