blob: a7fa0d75567dcdb995fca738f65878ca30f71f18 [file] [log] [blame]
Tony Olechd774efe2006-09-13 11:27:35 +01001/*
2* Host Controller Driver for the Elan Digital Systems U132 adapter
3*
4* Copyright(C) 2006 Elan Digital Systems Limited
5* http://www.elandigitalsystems.com
6*
7* Author and Maintainer - Tony Olech - Elan Digital Systems
8* tony.olech@elandigitalsystems.com
9*
10* This program is free software;you can redistribute it and/or
11* modify it under the terms of the GNU General Public License as
12* published by the Free Software Foundation, version 2.
13*
14*
15* This driver was written by Tony Olech(tony.olech@elandigitalsystems.com)
16* based on various USB host drivers in the 2.6.15 linux kernel
17* with constant reference to the 3rd Edition of Linux Device Drivers
18* published by O'Reilly
19*
20* The U132 adapter is a USB to CardBus adapter specifically designed
21* for PC cards that contain an OHCI host controller. Typical PC cards
22* are the Orange Mobile 3G Option GlobeTrotter Fusion card.
23*
24* The U132 adapter will *NOT *work with PC cards that do not contain
25* an OHCI controller. A simple way to test whether a PC card has an
26* OHCI controller as an interface is to insert the PC card directly
27* into a laptop(or desktop) with a CardBus slot and if "lspci" shows
28* a new USB controller and "lsusb -v" shows a new OHCI Host Controller
29* then there is a good chance that the U132 adapter will support the
30* PC card.(you also need the specific client driver for the PC card)
31*
32* Please inform the Author and Maintainer about any PC cards that
33* contain OHCI Host Controller and work when directly connected to
34* an embedded CardBus slot but do not work when they are connected
35* via an ELAN U132 adapter.
36*
37*/
Tony Olechd774efe2006-09-13 11:27:35 +010038#include <linux/kernel.h>
39#include <linux/module.h>
40#include <linux/moduleparam.h>
41#include <linux/delay.h>
42#include <linux/ioport.h>
Tony Olech4b873612006-12-06 13:16:22 +000043#include <linux/pci_ids.h>
Tony Olechd774efe2006-09-13 11:27:35 +010044#include <linux/sched.h>
45#include <linux/slab.h>
46#include <linux/smp_lock.h>
47#include <linux/errno.h>
48#include <linux/init.h>
49#include <linux/timer.h>
50#include <linux/list.h>
51#include <linux/interrupt.h>
52#include <linux/usb.h>
53#include <linux/workqueue.h>
54#include <linux/platform_device.h>
55#include <linux/pci_ids.h>
56#include <asm/io.h>
57#include <asm/irq.h>
58#include <asm/system.h>
59#include <asm/byteorder.h>
60#include "../core/hcd.h"
61#include "ohci.h"
62#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
63#define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \
64 OHCI_INTR_WDH)
65MODULE_AUTHOR("Tony Olech - Elan Digital Systems Limited");
66MODULE_DESCRIPTION("U132 USB Host Controller Driver");
67MODULE_LICENSE("GPL");
68#define INT_MODULE_PARM(n, v) static int n = v;module_param(n, int, 0444)
69INT_MODULE_PARM(testing, 0);
70/* Some boards misreport power switching/overcurrent*/
71static int distrust_firmware = 1;
72module_param(distrust_firmware, bool, 0);
73MODULE_PARM_DESC(distrust_firmware, "true to distrust firmware power/overcurren"
74 "t setup");
Adrian Bunk27a3de42006-11-20 03:23:54 +010075static DECLARE_WAIT_QUEUE_HEAD(u132_hcd_wait);
Tony Olechd774efe2006-09-13 11:27:35 +010076/*
77* u132_module_lock exists to protect access to global variables
78*
79*/
80static struct semaphore u132_module_lock;
81static int u132_exiting = 0;
82static int u132_instances = 0;
83static struct list_head u132_static_list;
84/*
85* end of the global variables protected by u132_module_lock
86*/
87static struct workqueue_struct *workqueue;
88#define MAX_U132_PORTS 7
89#define MAX_U132_ADDRS 128
90#define MAX_U132_UDEVS 4
91#define MAX_U132_ENDPS 100
92#define MAX_U132_RINGS 4
93static const char *cc_to_text[16] = {
94 "No Error ",
95 "CRC Error ",
96 "Bit Stuff ",
97 "Data Togg ",
98 "Stall ",
99 "DevNotResp ",
100 "PIDCheck ",
101 "UnExpPID ",
102 "DataOver ",
103 "DataUnder ",
104 "(for hw) ",
105 "(for hw) ",
106 "BufferOver ",
107 "BuffUnder ",
108 "(for HCD) ",
109 "(for HCD) "
110};
111struct u132_port {
112 struct u132 *u132;
113 int reset;
114 int enable;
115 int power;
116 int Status;
117};
118struct u132_addr {
119 u8 address;
120};
121struct u132_udev {
122 struct kref kref;
123 struct usb_device *usb_device;
124 u8 enumeration;
125 u8 udev_number;
126 u8 usb_addr;
127 u8 portnumber;
128 u8 endp_number_in[16];
129 u8 endp_number_out[16];
130};
131#define ENDP_QUEUE_SHIFT 3
132#define ENDP_QUEUE_SIZE (1<<ENDP_QUEUE_SHIFT)
133#define ENDP_QUEUE_MASK (ENDP_QUEUE_SIZE-1)
134struct u132_urbq {
135 struct list_head urb_more;
136 struct urb *urb;
137};
138struct u132_spin {
139 spinlock_t slock;
140};
141struct u132_endp {
142 struct kref kref;
143 u8 udev_number;
144 u8 endp_number;
145 u8 usb_addr;
146 u8 usb_endp;
147 struct u132 *u132;
148 struct list_head endp_ring;
149 struct u132_ring *ring;
150 unsigned toggle_bits:2;
151 unsigned active:1;
152 unsigned delayed:1;
153 unsigned input:1;
154 unsigned output:1;
155 unsigned pipetype:2;
156 unsigned dequeueing:1;
157 unsigned edset_flush:1;
158 unsigned spare_bits:14;
159 unsigned long jiffies;
160 struct usb_host_endpoint *hep;
161 struct u132_spin queue_lock;
162 u16 queue_size;
163 u16 queue_last;
164 u16 queue_next;
165 struct urb *urb_list[ENDP_QUEUE_SIZE];
166 struct list_head urb_more;
David Howellsc4028952006-11-22 14:57:56 +0000167 struct delayed_work scheduler;
Tony Olechd774efe2006-09-13 11:27:35 +0100168};
169struct u132_ring {
170 unsigned in_use:1;
171 unsigned length:7;
172 u8 number;
173 struct u132 *u132;
174 struct u132_endp *curr_endp;
David Howellsc4028952006-11-22 14:57:56 +0000175 struct delayed_work scheduler;
Tony Olechd774efe2006-09-13 11:27:35 +0100176};
177#define OHCI_QUIRK_AMD756 0x01
178#define OHCI_QUIRK_SUPERIO 0x02
179#define OHCI_QUIRK_INITRESET 0x04
180#define OHCI_BIG_ENDIAN 0x08
181#define OHCI_QUIRK_ZFMICRO 0x10
182struct u132 {
183 struct kref kref;
184 struct list_head u132_list;
185 struct semaphore sw_lock;
186 struct semaphore scheduler_lock;
187 struct u132_platform_data *board;
188 struct platform_device *platform_dev;
189 struct u132_ring ring[MAX_U132_RINGS];
190 int sequence_num;
191 int going;
192 int power;
193 int reset;
194 int num_ports;
195 u32 hc_control;
196 u32 hc_fminterval;
197 u32 hc_roothub_status;
198 u32 hc_roothub_a;
199 u32 hc_roothub_portstatus[MAX_ROOT_PORTS];
200 int flags;
201 unsigned long next_statechange;
David Howellsc4028952006-11-22 14:57:56 +0000202 struct delayed_work monitor;
Tony Olechd774efe2006-09-13 11:27:35 +0100203 int num_endpoints;
204 struct u132_addr addr[MAX_U132_ADDRS];
205 struct u132_udev udev[MAX_U132_UDEVS];
206 struct u132_port port[MAX_U132_PORTS];
207 struct u132_endp *endp[MAX_U132_ENDPS];
208};
Adrian Bunk9ce85402006-11-20 03:24:44 +0100209
Tony Olechd774efe2006-09-13 11:27:35 +0100210/*
Matt LaPlante0779bf22006-11-30 05:24:39 +0100211* these cannot be inlines because we need the structure offset!!
Tony Olechd774efe2006-09-13 11:27:35 +0100212* Does anyone have a better way?????
213*/
Tony Olech4b873612006-12-06 13:16:22 +0000214#define ftdi_read_pcimem(pdev, member, data) usb_ftdi_elan_read_pcimem(pdev, \
215 offsetof(struct ohci_regs, member), 0, data);
216#define ftdi_write_pcimem(pdev, member, data) usb_ftdi_elan_write_pcimem(pdev, \
217 offsetof(struct ohci_regs, member), 0, data);
Tony Olechd774efe2006-09-13 11:27:35 +0100218#define u132_read_pcimem(u132, member, data) \
219 usb_ftdi_elan_read_pcimem(u132->platform_dev, offsetof(struct \
220 ohci_regs, member), 0, data);
221#define u132_write_pcimem(u132, member, data) \
222 usb_ftdi_elan_write_pcimem(u132->platform_dev, offsetof(struct \
223 ohci_regs, member), 0, data);
Tony Olechd774efe2006-09-13 11:27:35 +0100224static inline struct u132 *udev_to_u132(struct u132_udev *udev)
225{
226 u8 udev_number = udev->udev_number;
227 return container_of(udev, struct u132, udev[udev_number]);
228}
229
230static inline struct u132 *hcd_to_u132(struct usb_hcd *hcd)
231{
232 return (struct u132 *)(hcd->hcd_priv);
233}
234
235static inline struct usb_hcd *u132_to_hcd(struct u132 *u132)
236{
237 return container_of((void *)u132, struct usb_hcd, hcd_priv);
238}
239
240static inline void u132_disable(struct u132 *u132)
241{
242 u132_to_hcd(u132)->state = HC_STATE_HALT;
243}
244
245
246#define kref_to_u132(d) container_of(d, struct u132, kref)
247#define kref_to_u132_endp(d) container_of(d, struct u132_endp, kref)
248#define kref_to_u132_udev(d) container_of(d, struct u132_udev, kref)
249#include "../misc/usb_u132.h"
250static const char hcd_name[] = "u132_hcd";
251#define PORT_C_MASK ((USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE | \
252 USB_PORT_STAT_C_SUSPEND | USB_PORT_STAT_C_OVERCURRENT | \
253 USB_PORT_STAT_C_RESET) << 16)
254static void u132_hcd_delete(struct kref *kref)
255{
256 struct u132 *u132 = kref_to_u132(kref);
257 struct platform_device *pdev = u132->platform_dev;
258 struct usb_hcd *hcd = u132_to_hcd(u132);
259 u132->going += 1;
260 down(&u132_module_lock);
261 list_del_init(&u132->u132_list);
262 u132_instances -= 1;
263 up(&u132_module_lock);
264 dev_warn(&u132->platform_dev->dev, "FREEING the hcd=%p and thus the u13"
265 "2=%p going=%d pdev=%p\n", hcd, u132, u132->going, pdev);
266 usb_put_hcd(hcd);
267}
268
269static inline void u132_u132_put_kref(struct u132 *u132)
270{
271 kref_put(&u132->kref, u132_hcd_delete);
272}
273
274static inline void u132_u132_init_kref(struct u132 *u132)
275{
276 kref_init(&u132->kref);
277}
278
279static void u132_udev_delete(struct kref *kref)
280{
281 struct u132_udev *udev = kref_to_u132_udev(kref);
282 udev->udev_number = 0;
283 udev->usb_device = NULL;
284 udev->usb_addr = 0;
285 udev->enumeration = 0;
286}
287
288static inline void u132_udev_put_kref(struct u132 *u132, struct u132_udev *udev)
289{
290 kref_put(&udev->kref, u132_udev_delete);
291}
292
293static inline void u132_udev_get_kref(struct u132 *u132, struct u132_udev *udev)
294{
295 kref_get(&udev->kref);
296}
297
298static inline void u132_udev_init_kref(struct u132 *u132,
299 struct u132_udev *udev)
300{
301 kref_init(&udev->kref);
302}
303
304static inline void u132_ring_put_kref(struct u132 *u132, struct u132_ring *ring)
305{
306 kref_put(&u132->kref, u132_hcd_delete);
307}
308
309static void u132_ring_requeue_work(struct u132 *u132, struct u132_ring *ring,
310 unsigned int delta)
311{
312 if (delta > 0) {
313 if (queue_delayed_work(workqueue, &ring->scheduler, delta))
314 return;
David Howellsc4028952006-11-22 14:57:56 +0000315 } else if (queue_delayed_work(workqueue, &ring->scheduler, 0))
Tony Olechd774efe2006-09-13 11:27:35 +0100316 return;
317 kref_put(&u132->kref, u132_hcd_delete);
318 return;
319}
320
321static void u132_ring_queue_work(struct u132 *u132, struct u132_ring *ring,
322 unsigned int delta)
323{
324 kref_get(&u132->kref);
325 u132_ring_requeue_work(u132, ring, delta);
326 return;
327}
328
329static void u132_ring_cancel_work(struct u132 *u132, struct u132_ring *ring)
330{
331 if (cancel_delayed_work(&ring->scheduler)) {
332 kref_put(&u132->kref, u132_hcd_delete);
333 }
334}
335
336static void u132_endp_delete(struct kref *kref)
337{
338 struct u132_endp *endp = kref_to_u132_endp(kref);
339 struct u132 *u132 = endp->u132;
340 u8 usb_addr = endp->usb_addr;
341 u8 usb_endp = endp->usb_endp;
342 u8 address = u132->addr[usb_addr].address;
343 struct u132_udev *udev = &u132->udev[address];
344 u8 endp_number = endp->endp_number;
345 struct usb_host_endpoint *hep = endp->hep;
346 struct u132_ring *ring = endp->ring;
347 struct list_head *head = &endp->endp_ring;
348 ring->length -= 1;
349 if (endp == ring->curr_endp) {
350 if (list_empty(head)) {
351 ring->curr_endp = NULL;
352 list_del(head);
353 } else {
354 struct u132_endp *next_endp = list_entry(head->next,
355 struct u132_endp, endp_ring);
356 ring->curr_endp = next_endp;
357 list_del(head);
358 }} else
359 list_del(head);
360 if (endp->input) {
361 udev->endp_number_in[usb_endp] = 0;
362 u132_udev_put_kref(u132, udev);
363 }
364 if (endp->output) {
365 udev->endp_number_out[usb_endp] = 0;
366 u132_udev_put_kref(u132, udev);
367 }
368 u132->endp[endp_number - 1] = NULL;
369 hep->hcpriv = NULL;
370 kfree(endp);
371 u132_u132_put_kref(u132);
372}
373
374static inline void u132_endp_put_kref(struct u132 *u132, struct u132_endp *endp)
375{
376 kref_put(&endp->kref, u132_endp_delete);
377}
378
379static inline void u132_endp_get_kref(struct u132 *u132, struct u132_endp *endp)
380{
381 kref_get(&endp->kref);
382}
383
384static inline void u132_endp_init_kref(struct u132 *u132,
385 struct u132_endp *endp)
386{
387 kref_init(&endp->kref);
388 kref_get(&u132->kref);
389}
390
391static void u132_endp_queue_work(struct u132 *u132, struct u132_endp *endp,
392 unsigned int delta)
393{
David Howellsc4028952006-11-22 14:57:56 +0000394 if (queue_delayed_work(workqueue, &endp->scheduler, delta))
395 kref_get(&endp->kref);
Tony Olechd774efe2006-09-13 11:27:35 +0100396}
397
398static void u132_endp_cancel_work(struct u132 *u132, struct u132_endp *endp)
399{
400 if (cancel_delayed_work(&endp->scheduler))
401 kref_put(&endp->kref, u132_endp_delete);
402}
403
404static inline void u132_monitor_put_kref(struct u132 *u132)
405{
406 kref_put(&u132->kref, u132_hcd_delete);
407}
408
409static void u132_monitor_queue_work(struct u132 *u132, unsigned int delta)
410{
David Howellsc4028952006-11-22 14:57:56 +0000411 if (queue_delayed_work(workqueue, &u132->monitor, delta))
412 kref_get(&u132->kref);
Tony Olechd774efe2006-09-13 11:27:35 +0100413}
414
415static void u132_monitor_requeue_work(struct u132 *u132, unsigned int delta)
416{
David Howellsc4028952006-11-22 14:57:56 +0000417 if (!queue_delayed_work(workqueue, &u132->monitor, delta))
418 kref_put(&u132->kref, u132_hcd_delete);
Tony Olechd774efe2006-09-13 11:27:35 +0100419}
420
421static void u132_monitor_cancel_work(struct u132 *u132)
422{
423 if (cancel_delayed_work(&u132->monitor))
424 kref_put(&u132->kref, u132_hcd_delete);
425}
426
427static int read_roothub_info(struct u132 *u132)
428{
429 u32 revision;
430 int retval;
431 retval = u132_read_pcimem(u132, revision, &revision);
432 if (retval) {
433 dev_err(&u132->platform_dev->dev, "error %d accessing device co"
434 "ntrol\n", retval);
435 return retval;
436 } else if ((revision & 0xFF) == 0x10) {
437 } else if ((revision & 0xFF) == 0x11) {
438 } else {
439 dev_err(&u132->platform_dev->dev, "device revision is not valid"
440 " %08X\n", revision);
441 return -ENODEV;
442 }
443 retval = u132_read_pcimem(u132, control, &u132->hc_control);
444 if (retval) {
445 dev_err(&u132->platform_dev->dev, "error %d accessing device co"
446 "ntrol\n", retval);
447 return retval;
448 }
449 retval = u132_read_pcimem(u132, roothub.status,
450 &u132->hc_roothub_status);
451 if (retval) {
452 dev_err(&u132->platform_dev->dev, "error %d accessing device re"
453 "g roothub.status\n", retval);
454 return retval;
455 }
456 retval = u132_read_pcimem(u132, roothub.a, &u132->hc_roothub_a);
457 if (retval) {
458 dev_err(&u132->platform_dev->dev, "error %d accessing device re"
459 "g roothub.a\n", retval);
460 return retval;
461 }
462 {
463 int I = u132->num_ports;
464 int i = 0;
465 while (I-- > 0) {
466 retval = u132_read_pcimem(u132, roothub.portstatus[i],
467 &u132->hc_roothub_portstatus[i]);
468 if (retval) {
469 dev_err(&u132->platform_dev->dev, "error %d acc"
470 "essing device roothub.portstatus[%d]\n"
471 , retval, i);
472 return retval;
473 } else
474 i += 1;
475 }
476 }
477 return 0;
478}
479
David Howellsc4028952006-11-22 14:57:56 +0000480static void u132_hcd_monitor_work(struct work_struct *work)
Tony Olechd774efe2006-09-13 11:27:35 +0100481{
David Howellsc4028952006-11-22 14:57:56 +0000482 struct u132 *u132 = container_of(work, struct u132, monitor.work);
Tony Olechd774efe2006-09-13 11:27:35 +0100483 if (u132->going > 1) {
484 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
485 , u132->going);
486 u132_monitor_put_kref(u132);
487 return;
488 } else if (u132->going > 0) {
489 dev_err(&u132->platform_dev->dev, "device is being removed\n");
490 u132_monitor_put_kref(u132);
491 return;
492 } else {
493 int retval;
494 down(&u132->sw_lock);
495 retval = read_roothub_info(u132);
496 if (retval) {
497 struct usb_hcd *hcd = u132_to_hcd(u132);
498 u132_disable(u132);
499 u132->going = 1;
500 up(&u132->sw_lock);
501 usb_hc_died(hcd);
502 ftdi_elan_gone_away(u132->platform_dev);
503 u132_monitor_put_kref(u132);
504 return;
505 } else {
506 u132_monitor_requeue_work(u132, 500);
507 up(&u132->sw_lock);
508 return;
509 }
510 }
511}
512
513static void u132_hcd_giveback_urb(struct u132 *u132, struct u132_endp *endp,
514 struct urb *urb, int status)
515{
516 struct u132_ring *ring;
517 unsigned long irqs;
518 struct usb_hcd *hcd = u132_to_hcd(u132);
519 urb->error_count = 0;
520 urb->status = status;
521 urb->hcpriv = NULL;
522 spin_lock_irqsave(&endp->queue_lock.slock, irqs);
523 endp->queue_next += 1;
524 if (ENDP_QUEUE_SIZE > --endp->queue_size) {
525 endp->active = 0;
526 spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
527 } else {
528 struct list_head *next = endp->urb_more.next;
529 struct u132_urbq *urbq = list_entry(next, struct u132_urbq,
530 urb_more);
531 list_del(next);
532 endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] =
533 urbq->urb;
534 endp->active = 0;
535 spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
536 kfree(urbq);
537 } down(&u132->scheduler_lock);
538 ring = endp->ring;
539 ring->in_use = 0;
540 u132_ring_cancel_work(u132, ring);
541 u132_ring_queue_work(u132, ring, 0);
542 up(&u132->scheduler_lock);
543 u132_endp_put_kref(u132, endp);
David Howells7d12e782006-10-05 14:55:46 +0100544 usb_hcd_giveback_urb(hcd, urb);
Tony Olechd774efe2006-09-13 11:27:35 +0100545 return;
546}
547
548static void u132_hcd_forget_urb(struct u132 *u132, struct u132_endp *endp,
549 struct urb *urb, int status)
550{
551 u132_endp_put_kref(u132, endp);
552}
553
554static void u132_hcd_abandon_urb(struct u132 *u132, struct u132_endp *endp,
555 struct urb *urb, int status)
556{
557 unsigned long irqs;
558 struct usb_hcd *hcd = u132_to_hcd(u132);
559 urb->error_count = 0;
560 urb->status = status;
561 urb->hcpriv = NULL;
562 spin_lock_irqsave(&endp->queue_lock.slock, irqs);
563 endp->queue_next += 1;
564 if (ENDP_QUEUE_SIZE > --endp->queue_size) {
565 endp->active = 0;
566 spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
567 } else {
568 struct list_head *next = endp->urb_more.next;
569 struct u132_urbq *urbq = list_entry(next, struct u132_urbq,
570 urb_more);
571 list_del(next);
572 endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] =
573 urbq->urb;
574 endp->active = 0;
575 spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
576 kfree(urbq);
David Howells7d12e782006-10-05 14:55:46 +0100577 } usb_hcd_giveback_urb(hcd, urb);
Tony Olechd774efe2006-09-13 11:27:35 +0100578 return;
579}
580
581static inline int edset_input(struct u132 *u132, struct u132_ring *ring,
582 struct u132_endp *endp, struct urb *urb, u8 address, u8 toggle_bits,
583 void (*callback) (void *endp, struct urb *urb, u8 *buf, int len,
584 int toggle_bits, int error_count, int condition_code, int repeat_number,
585 int halted, int skipped, int actual, int non_null))
586{
587 return usb_ftdi_elan_edset_input(u132->platform_dev, ring->number, endp,
588 urb, address, endp->usb_endp, toggle_bits, callback);
589}
590
591static inline int edset_setup(struct u132 *u132, struct u132_ring *ring,
592 struct u132_endp *endp, struct urb *urb, u8 address, u8 toggle_bits,
593 void (*callback) (void *endp, struct urb *urb, u8 *buf, int len,
594 int toggle_bits, int error_count, int condition_code, int repeat_number,
595 int halted, int skipped, int actual, int non_null))
596{
597 return usb_ftdi_elan_edset_setup(u132->platform_dev, ring->number, endp,
598 urb, address, endp->usb_endp, toggle_bits, callback);
599}
600
601static inline int edset_single(struct u132 *u132, struct u132_ring *ring,
602 struct u132_endp *endp, struct urb *urb, u8 address, u8 toggle_bits,
603 void (*callback) (void *endp, struct urb *urb, u8 *buf, int len,
604 int toggle_bits, int error_count, int condition_code, int repeat_number,
605 int halted, int skipped, int actual, int non_null))
606{
607 return usb_ftdi_elan_edset_single(u132->platform_dev, ring->number,
608 endp, urb, address, endp->usb_endp, toggle_bits, callback);
609}
610
611static inline int edset_output(struct u132 *u132, struct u132_ring *ring,
612 struct u132_endp *endp, struct urb *urb, u8 address, u8 toggle_bits,
613 void (*callback) (void *endp, struct urb *urb, u8 *buf, int len,
614 int toggle_bits, int error_count, int condition_code, int repeat_number,
615 int halted, int skipped, int actual, int non_null))
616{
617 return usb_ftdi_elan_edset_output(u132->platform_dev, ring->number,
618 endp, urb, address, endp->usb_endp, toggle_bits, callback);
619}
620
621
622/*
623* must not LOCK sw_lock
624*
625*/
626static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf,
627 int len, int toggle_bits, int error_count, int condition_code,
628 int repeat_number, int halted, int skipped, int actual, int non_null)
629{
630 struct u132_endp *endp = data;
631 struct u132 *u132 = endp->u132;
632 u8 address = u132->addr[endp->usb_addr].address;
633 struct u132_udev *udev = &u132->udev[address];
634 down(&u132->scheduler_lock);
635 if (u132->going > 1) {
636 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
637 , u132->going);
638 up(&u132->scheduler_lock);
639 u132_hcd_forget_urb(u132, endp, urb, -ENODEV);
640 return;
641 } else if (endp->dequeueing) {
642 endp->dequeueing = 0;
643 up(&u132->scheduler_lock);
644 u132_hcd_giveback_urb(u132, endp, urb, -EINTR);
645 return;
646 } else if (u132->going > 0) {
647 dev_err(&u132->platform_dev->dev, "device is being removed urb="
648 "%p status=%d\n", urb, urb->status);
649 up(&u132->scheduler_lock);
650 u132_hcd_giveback_urb(u132, endp, urb, -ENODEV);
651 return;
652 } else if (urb->status == -EINPROGRESS) {
653 struct u132_ring *ring = endp->ring;
654 u8 *u = urb->transfer_buffer + urb->actual_length;
655 u8 *b = buf;
656 int L = len;
657 while (L-- > 0) {
658 *u++ = *b++;
659 }
660 urb->actual_length += len;
661 if ((condition_code == TD_CC_NOERROR) &&
662 (urb->transfer_buffer_length > urb->actual_length)) {
663 endp->toggle_bits = toggle_bits;
664 usb_settoggle(udev->usb_device, endp->usb_endp, 0,
665 1 & toggle_bits);
666 if (urb->actual_length > 0) {
667 int retval;
668 up(&u132->scheduler_lock);
669 retval = edset_single(u132, ring, endp, urb,
670 address, endp->toggle_bits,
671 u132_hcd_interrupt_recv);
672 if (retval == 0) {
673 } else
674 u132_hcd_giveback_urb(u132, endp, urb,
675 retval);
676 } else {
677 ring->in_use = 0;
678 endp->active = 0;
679 endp->jiffies = jiffies +
680 msecs_to_jiffies(urb->interval);
681 u132_ring_cancel_work(u132, ring);
682 u132_ring_queue_work(u132, ring, 0);
683 up(&u132->scheduler_lock);
684 u132_endp_put_kref(u132, endp);
685 }
686 return;
687 } else if ((condition_code == TD_DATAUNDERRUN) &&
688 ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0)) {
689 endp->toggle_bits = toggle_bits;
690 usb_settoggle(udev->usb_device, endp->usb_endp, 0,
691 1 & toggle_bits);
692 up(&u132->scheduler_lock);
693 u132_hcd_giveback_urb(u132, endp, urb, 0);
694 return;
695 } else {
696 if (condition_code == TD_CC_NOERROR) {
697 endp->toggle_bits = toggle_bits;
698 usb_settoggle(udev->usb_device, endp->usb_endp,
699 0, 1 & toggle_bits);
700 } else if (condition_code == TD_CC_STALL) {
701 endp->toggle_bits = 0x2;
702 usb_settoggle(udev->usb_device, endp->usb_endp,
703 0, 0);
704 } else {
705 endp->toggle_bits = 0x2;
706 usb_settoggle(udev->usb_device, endp->usb_endp,
707 0, 0);
708 dev_err(&u132->platform_dev->dev, "urb=%p givin"
709 "g back INTERRUPT %s\n", urb,
710 cc_to_text[condition_code]);
711 }
712 up(&u132->scheduler_lock);
713 u132_hcd_giveback_urb(u132, endp, urb,
714 cc_to_error[condition_code]);
715 return;
716 }
717 } else {
718 dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu"
719 "s=%d\n", urb, urb->status);
720 up(&u132->scheduler_lock);
721 u132_hcd_giveback_urb(u132, endp, urb, urb->status);
722 return;
723 }
724}
725
726static void u132_hcd_bulk_output_sent(void *data, struct urb *urb, u8 *buf,
727 int len, int toggle_bits, int error_count, int condition_code,
728 int repeat_number, int halted, int skipped, int actual, int non_null)
729{
730 struct u132_endp *endp = data;
731 struct u132 *u132 = endp->u132;
732 u8 address = u132->addr[endp->usb_addr].address;
733 down(&u132->scheduler_lock);
734 if (u132->going > 1) {
735 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
736 , u132->going);
737 up(&u132->scheduler_lock);
738 u132_hcd_forget_urb(u132, endp, urb, -ENODEV);
739 return;
740 } else if (endp->dequeueing) {
741 endp->dequeueing = 0;
742 up(&u132->scheduler_lock);
743 u132_hcd_giveback_urb(u132, endp, urb, -EINTR);
744 return;
745 } else if (u132->going > 0) {
746 dev_err(&u132->platform_dev->dev, "device is being removed urb="
747 "%p status=%d\n", urb, urb->status);
748 up(&u132->scheduler_lock);
749 u132_hcd_giveback_urb(u132, endp, urb, -ENODEV);
750 return;
751 } else if (urb->status == -EINPROGRESS) {
752 struct u132_ring *ring = endp->ring;
753 urb->actual_length += len;
754 endp->toggle_bits = toggle_bits;
755 if (urb->transfer_buffer_length > urb->actual_length) {
756 int retval;
757 up(&u132->scheduler_lock);
758 retval = edset_output(u132, ring, endp, urb, address,
759 endp->toggle_bits, u132_hcd_bulk_output_sent);
760 if (retval == 0) {
761 } else
762 u132_hcd_giveback_urb(u132, endp, urb, retval);
763 return;
764 } else {
765 up(&u132->scheduler_lock);
766 u132_hcd_giveback_urb(u132, endp, urb, 0);
767 return;
768 }
769 } else {
770 dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu"
771 "s=%d\n", urb, urb->status);
772 up(&u132->scheduler_lock);
773 u132_hcd_giveback_urb(u132, endp, urb, urb->status);
774 return;
775 }
776}
777
778static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf,
779 int len, int toggle_bits, int error_count, int condition_code,
780 int repeat_number, int halted, int skipped, int actual, int non_null)
781{
782 struct u132_endp *endp = data;
783 struct u132 *u132 = endp->u132;
784 u8 address = u132->addr[endp->usb_addr].address;
785 struct u132_udev *udev = &u132->udev[address];
786 down(&u132->scheduler_lock);
787 if (u132->going > 1) {
788 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
789 , u132->going);
790 up(&u132->scheduler_lock);
791 u132_hcd_forget_urb(u132, endp, urb, -ENODEV);
792 return;
793 } else if (endp->dequeueing) {
794 endp->dequeueing = 0;
795 up(&u132->scheduler_lock);
796 u132_hcd_giveback_urb(u132, endp, urb, -EINTR);
797 return;
798 } else if (u132->going > 0) {
799 dev_err(&u132->platform_dev->dev, "device is being removed urb="
800 "%p status=%d\n", urb, urb->status);
801 up(&u132->scheduler_lock);
802 u132_hcd_giveback_urb(u132, endp, urb, -ENODEV);
803 return;
804 } else if (urb->status == -EINPROGRESS) {
805 struct u132_ring *ring = endp->ring;
806 u8 *u = urb->transfer_buffer + urb->actual_length;
807 u8 *b = buf;
808 int L = len;
809 while (L-- > 0) {
810 *u++ = *b++;
811 }
812 urb->actual_length += len;
813 if ((condition_code == TD_CC_NOERROR) &&
814 (urb->transfer_buffer_length > urb->actual_length)) {
815 int retval;
816 endp->toggle_bits = toggle_bits;
817 usb_settoggle(udev->usb_device, endp->usb_endp, 0,
818 1 & toggle_bits);
819 up(&u132->scheduler_lock);
820 retval = usb_ftdi_elan_edset_input(u132->platform_dev,
821 ring->number, endp, urb, address,
822 endp->usb_endp, endp->toggle_bits,
823 u132_hcd_bulk_input_recv);
824 if (retval == 0) {
825 } else
826 u132_hcd_giveback_urb(u132, endp, urb, retval);
827 return;
828 } else if (condition_code == TD_CC_NOERROR) {
829 endp->toggle_bits = toggle_bits;
830 usb_settoggle(udev->usb_device, endp->usb_endp, 0,
831 1 & toggle_bits);
832 up(&u132->scheduler_lock);
833 u132_hcd_giveback_urb(u132, endp, urb,
834 cc_to_error[condition_code]);
835 return;
836 } else if ((condition_code == TD_DATAUNDERRUN) &&
837 ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0)) {
838 endp->toggle_bits = toggle_bits;
839 usb_settoggle(udev->usb_device, endp->usb_endp, 0,
840 1 & toggle_bits);
841 up(&u132->scheduler_lock);
842 u132_hcd_giveback_urb(u132, endp, urb, 0);
843 return;
844 } else if (condition_code == TD_DATAUNDERRUN) {
845 endp->toggle_bits = toggle_bits;
846 usb_settoggle(udev->usb_device, endp->usb_endp, 0,
847 1 & toggle_bits);
848 dev_warn(&u132->platform_dev->dev, "urb=%p(SHORT NOT OK"
849 ") giving back BULK IN %s\n", urb,
850 cc_to_text[condition_code]);
851 up(&u132->scheduler_lock);
852 u132_hcd_giveback_urb(u132, endp, urb, 0);
853 return;
854 } else if (condition_code == TD_CC_STALL) {
855 endp->toggle_bits = 0x2;
856 usb_settoggle(udev->usb_device, endp->usb_endp, 0, 0);
857 up(&u132->scheduler_lock);
858 u132_hcd_giveback_urb(u132, endp, urb,
859 cc_to_error[condition_code]);
860 return;
861 } else {
862 endp->toggle_bits = 0x2;
863 usb_settoggle(udev->usb_device, endp->usb_endp, 0, 0);
864 dev_err(&u132->platform_dev->dev, "urb=%p giving back B"
865 "ULK IN code=%d %s\n", urb, condition_code,
866 cc_to_text[condition_code]);
867 up(&u132->scheduler_lock);
868 u132_hcd_giveback_urb(u132, endp, urb,
869 cc_to_error[condition_code]);
870 return;
871 }
872 } else {
873 dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu"
874 "s=%d\n", urb, urb->status);
875 up(&u132->scheduler_lock);
876 u132_hcd_giveback_urb(u132, endp, urb, urb->status);
877 return;
878 }
879}
880
881static void u132_hcd_configure_empty_sent(void *data, struct urb *urb, u8 *buf,
882 int len, int toggle_bits, int error_count, int condition_code,
883 int repeat_number, int halted, int skipped, int actual, int non_null)
884{
885 struct u132_endp *endp = data;
886 struct u132 *u132 = endp->u132;
887 down(&u132->scheduler_lock);
888 if (u132->going > 1) {
889 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
890 , u132->going);
891 up(&u132->scheduler_lock);
892 u132_hcd_forget_urb(u132, endp, urb, -ENODEV);
893 return;
894 } else if (endp->dequeueing) {
895 endp->dequeueing = 0;
896 up(&u132->scheduler_lock);
897 u132_hcd_giveback_urb(u132, endp, urb, -EINTR);
898 return;
899 } else if (u132->going > 0) {
900 dev_err(&u132->platform_dev->dev, "device is being removed urb="
901 "%p status=%d\n", urb, urb->status);
902 up(&u132->scheduler_lock);
903 u132_hcd_giveback_urb(u132, endp, urb, -ENODEV);
904 return;
905 } else if (urb->status == -EINPROGRESS) {
906 up(&u132->scheduler_lock);
907 u132_hcd_giveback_urb(u132, endp, urb, 0);
908 return;
909 } else {
910 dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu"
911 "s=%d\n", urb, urb->status);
912 up(&u132->scheduler_lock);
913 u132_hcd_giveback_urb(u132, endp, urb, urb->status);
914 return;
915 }
916}
917
918static void u132_hcd_configure_input_recv(void *data, struct urb *urb, u8 *buf,
919 int len, int toggle_bits, int error_count, int condition_code,
920 int repeat_number, int halted, int skipped, int actual, int non_null)
921{
922 struct u132_endp *endp = data;
923 struct u132 *u132 = endp->u132;
924 u8 address = u132->addr[endp->usb_addr].address;
925 down(&u132->scheduler_lock);
926 if (u132->going > 1) {
927 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
928 , u132->going);
929 up(&u132->scheduler_lock);
930 u132_hcd_forget_urb(u132, endp, urb, -ENODEV);
931 return;
932 } else if (endp->dequeueing) {
933 endp->dequeueing = 0;
934 up(&u132->scheduler_lock);
935 u132_hcd_giveback_urb(u132, endp, urb, -EINTR);
936 return;
937 } else if (u132->going > 0) {
938 dev_err(&u132->platform_dev->dev, "device is being removed urb="
939 "%p status=%d\n", urb, urb->status);
940 up(&u132->scheduler_lock);
941 u132_hcd_giveback_urb(u132, endp, urb, -ENODEV);
942 return;
943 } else if (urb->status == -EINPROGRESS) {
944 struct u132_ring *ring = endp->ring;
945 u8 *u = urb->transfer_buffer;
946 u8 *b = buf;
947 int L = len;
948 while (L-- > 0) {
949 *u++ = *b++;
950 }
951 urb->actual_length = len;
952 if ((condition_code == TD_CC_NOERROR) || ((condition_code ==
953 TD_DATAUNDERRUN) && ((urb->transfer_flags &
954 URB_SHORT_NOT_OK) == 0))) {
955 int retval;
956 up(&u132->scheduler_lock);
957 retval = usb_ftdi_elan_edset_empty(u132->platform_dev,
958 ring->number, endp, urb, address,
959 endp->usb_endp, 0x3,
960 u132_hcd_configure_empty_sent);
961 if (retval == 0) {
962 } else
963 u132_hcd_giveback_urb(u132, endp, urb, retval);
964 return;
965 } else if (condition_code == TD_CC_STALL) {
966 up(&u132->scheduler_lock);
967 dev_warn(&u132->platform_dev->dev, "giving back SETUP I"
968 "NPUT STALL urb %p\n", urb);
969 u132_hcd_giveback_urb(u132, endp, urb,
970 cc_to_error[condition_code]);
971 return;
972 } else {
973 up(&u132->scheduler_lock);
974 dev_err(&u132->platform_dev->dev, "giving back SETUP IN"
975 "PUT %s urb %p\n", cc_to_text[condition_code],
976 urb);
977 u132_hcd_giveback_urb(u132, endp, urb,
978 cc_to_error[condition_code]);
979 return;
980 }
981 } else {
982 dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu"
983 "s=%d\n", urb, urb->status);
984 up(&u132->scheduler_lock);
985 u132_hcd_giveback_urb(u132, endp, urb, urb->status);
986 return;
987 }
988}
989
990static void u132_hcd_configure_empty_recv(void *data, struct urb *urb, u8 *buf,
991 int len, int toggle_bits, int error_count, int condition_code,
992 int repeat_number, int halted, int skipped, int actual, int non_null)
993{
994 struct u132_endp *endp = data;
995 struct u132 *u132 = endp->u132;
996 down(&u132->scheduler_lock);
997 if (u132->going > 1) {
998 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
999 , u132->going);
1000 up(&u132->scheduler_lock);
1001 u132_hcd_forget_urb(u132, endp, urb, -ENODEV);
1002 return;
1003 } else if (endp->dequeueing) {
1004 endp->dequeueing = 0;
1005 up(&u132->scheduler_lock);
1006 u132_hcd_giveback_urb(u132, endp, urb, -EINTR);
1007 return;
1008 } else if (u132->going > 0) {
1009 dev_err(&u132->platform_dev->dev, "device is being removed urb="
1010 "%p status=%d\n", urb, urb->status);
1011 up(&u132->scheduler_lock);
1012 u132_hcd_giveback_urb(u132, endp, urb, -ENODEV);
1013 return;
1014 } else if (urb->status == -EINPROGRESS) {
1015 up(&u132->scheduler_lock);
1016 u132_hcd_giveback_urb(u132, endp, urb, 0);
1017 return;
1018 } else {
1019 dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu"
1020 "s=%d\n", urb, urb->status);
1021 up(&u132->scheduler_lock);
1022 u132_hcd_giveback_urb(u132, endp, urb, urb->status);
1023 return;
1024 }
1025}
1026
1027static void u132_hcd_configure_setup_sent(void *data, struct urb *urb, u8 *buf,
1028 int len, int toggle_bits, int error_count, int condition_code,
1029 int repeat_number, int halted, int skipped, int actual, int non_null)
1030{
1031 struct u132_endp *endp = data;
1032 struct u132 *u132 = endp->u132;
1033 u8 address = u132->addr[endp->usb_addr].address;
1034 down(&u132->scheduler_lock);
1035 if (u132->going > 1) {
1036 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
1037 , u132->going);
1038 up(&u132->scheduler_lock);
1039 u132_hcd_forget_urb(u132, endp, urb, -ENODEV);
1040 return;
1041 } else if (endp->dequeueing) {
1042 endp->dequeueing = 0;
1043 up(&u132->scheduler_lock);
1044 u132_hcd_giveback_urb(u132, endp, urb, -EINTR);
1045 return;
1046 } else if (u132->going > 0) {
1047 dev_err(&u132->platform_dev->dev, "device is being removed urb="
1048 "%p status=%d\n", urb, urb->status);
1049 up(&u132->scheduler_lock);
1050 u132_hcd_giveback_urb(u132, endp, urb, -ENODEV);
1051 return;
1052 } else if (urb->status == -EINPROGRESS) {
1053 if (usb_pipein(urb->pipe)) {
1054 int retval;
1055 struct u132_ring *ring = endp->ring;
1056 up(&u132->scheduler_lock);
1057 retval = usb_ftdi_elan_edset_input(u132->platform_dev,
1058 ring->number, endp, urb, address,
1059 endp->usb_endp, 0,
1060 u132_hcd_configure_input_recv);
1061 if (retval == 0) {
1062 } else
1063 u132_hcd_giveback_urb(u132, endp, urb, retval);
1064 return;
1065 } else {
1066 int retval;
1067 struct u132_ring *ring = endp->ring;
1068 up(&u132->scheduler_lock);
1069 retval = usb_ftdi_elan_edset_input(u132->platform_dev,
1070 ring->number, endp, urb, address,
1071 endp->usb_endp, 0,
1072 u132_hcd_configure_empty_recv);
1073 if (retval == 0) {
1074 } else
1075 u132_hcd_giveback_urb(u132, endp, urb, retval);
1076 return;
1077 }
1078 } else {
1079 dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu"
1080 "s=%d\n", urb, urb->status);
1081 up(&u132->scheduler_lock);
1082 u132_hcd_giveback_urb(u132, endp, urb, urb->status);
1083 return;
1084 }
1085}
1086
1087static void u132_hcd_enumeration_empty_recv(void *data, struct urb *urb,
1088 u8 *buf, int len, int toggle_bits, int error_count, int condition_code,
1089 int repeat_number, int halted, int skipped, int actual, int non_null)
1090{
1091 struct u132_endp *endp = data;
1092 struct u132 *u132 = endp->u132;
1093 u8 address = u132->addr[endp->usb_addr].address;
1094 struct u132_udev *udev = &u132->udev[address];
1095 down(&u132->scheduler_lock);
1096 if (u132->going > 1) {
1097 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
1098 , u132->going);
1099 up(&u132->scheduler_lock);
1100 u132_hcd_forget_urb(u132, endp, urb, -ENODEV);
1101 return;
1102 } else if (endp->dequeueing) {
1103 endp->dequeueing = 0;
1104 up(&u132->scheduler_lock);
1105 u132_hcd_giveback_urb(u132, endp, urb, -EINTR);
1106 return;
1107 } else if (u132->going > 0) {
1108 dev_err(&u132->platform_dev->dev, "device is being removed urb="
1109 "%p status=%d\n", urb, urb->status);
1110 up(&u132->scheduler_lock);
1111 u132_hcd_giveback_urb(u132, endp, urb, -ENODEV);
1112 return;
1113 } else if (urb->status == -EINPROGRESS) {
1114 u132->addr[0].address = 0;
1115 endp->usb_addr = udev->usb_addr;
1116 up(&u132->scheduler_lock);
1117 u132_hcd_giveback_urb(u132, endp, urb, 0);
1118 return;
1119 } else {
1120 dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu"
1121 "s=%d\n", urb, urb->status);
1122 up(&u132->scheduler_lock);
1123 u132_hcd_giveback_urb(u132, endp, urb, urb->status);
1124 return;
1125 }
1126}
1127
1128static void u132_hcd_enumeration_address_sent(void *data, struct urb *urb,
1129 u8 *buf, int len, int toggle_bits, int error_count, int condition_code,
1130 int repeat_number, int halted, int skipped, int actual, int non_null)
1131{
1132 struct u132_endp *endp = data;
1133 struct u132 *u132 = endp->u132;
1134 down(&u132->scheduler_lock);
1135 if (u132->going > 1) {
1136 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
1137 , u132->going);
1138 up(&u132->scheduler_lock);
1139 u132_hcd_forget_urb(u132, endp, urb, -ENODEV);
1140 return;
1141 } else if (endp->dequeueing) {
1142 endp->dequeueing = 0;
1143 up(&u132->scheduler_lock);
1144 u132_hcd_giveback_urb(u132, endp, urb, -EINTR);
1145 return;
1146 } else if (u132->going > 0) {
1147 dev_err(&u132->platform_dev->dev, "device is being removed urb="
1148 "%p status=%d\n", urb, urb->status);
1149 up(&u132->scheduler_lock);
1150 u132_hcd_giveback_urb(u132, endp, urb, -ENODEV);
1151 return;
1152 } else if (urb->status == -EINPROGRESS) {
1153 int retval;
1154 struct u132_ring *ring = endp->ring;
1155 up(&u132->scheduler_lock);
1156 retval = usb_ftdi_elan_edset_input(u132->platform_dev,
1157 ring->number, endp, urb, 0, endp->usb_endp, 0,
1158 u132_hcd_enumeration_empty_recv);
1159 if (retval == 0) {
1160 } else
1161 u132_hcd_giveback_urb(u132, endp, urb, retval);
1162 return;
1163 } else {
1164 dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu"
1165 "s=%d\n", urb, urb->status);
1166 up(&u132->scheduler_lock);
1167 u132_hcd_giveback_urb(u132, endp, urb, urb->status);
1168 return;
1169 }
1170}
1171
1172static void u132_hcd_initial_empty_sent(void *data, struct urb *urb, u8 *buf,
1173 int len, int toggle_bits, int error_count, int condition_code,
1174 int repeat_number, int halted, int skipped, int actual, int non_null)
1175{
1176 struct u132_endp *endp = data;
1177 struct u132 *u132 = endp->u132;
1178 down(&u132->scheduler_lock);
1179 if (u132->going > 1) {
1180 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
1181 , u132->going);
1182 up(&u132->scheduler_lock);
1183 u132_hcd_forget_urb(u132, endp, urb, -ENODEV);
1184 return;
1185 } else if (endp->dequeueing) {
1186 endp->dequeueing = 0;
1187 up(&u132->scheduler_lock);
1188 u132_hcd_giveback_urb(u132, endp, urb, -EINTR);
1189 return;
1190 } else if (u132->going > 0) {
1191 dev_err(&u132->platform_dev->dev, "device is being removed urb="
1192 "%p status=%d\n", urb, urb->status);
1193 up(&u132->scheduler_lock);
1194 u132_hcd_giveback_urb(u132, endp, urb, -ENODEV);
1195 return;
1196 } else if (urb->status == -EINPROGRESS) {
1197 up(&u132->scheduler_lock);
1198 u132_hcd_giveback_urb(u132, endp, urb, 0);
1199 return;
1200 } else {
1201 dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu"
1202 "s=%d\n", urb, urb->status);
1203 up(&u132->scheduler_lock);
1204 u132_hcd_giveback_urb(u132, endp, urb, urb->status);
1205 return;
1206 }
1207}
1208
1209static void u132_hcd_initial_input_recv(void *data, struct urb *urb, u8 *buf,
1210 int len, int toggle_bits, int error_count, int condition_code,
1211 int repeat_number, int halted, int skipped, int actual, int non_null)
1212{
1213 struct u132_endp *endp = data;
1214 struct u132 *u132 = endp->u132;
1215 u8 address = u132->addr[endp->usb_addr].address;
1216 down(&u132->scheduler_lock);
1217 if (u132->going > 1) {
1218 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
1219 , u132->going);
1220 up(&u132->scheduler_lock);
1221 u132_hcd_forget_urb(u132, endp, urb, -ENODEV);
1222 return;
1223 } else if (endp->dequeueing) {
1224 endp->dequeueing = 0;
1225 up(&u132->scheduler_lock);
1226 u132_hcd_giveback_urb(u132, endp, urb, -EINTR);
1227 return;
1228 } else if (u132->going > 0) {
1229 dev_err(&u132->platform_dev->dev, "device is being removed urb="
1230 "%p status=%d\n", urb, urb->status);
1231 up(&u132->scheduler_lock);
1232 u132_hcd_giveback_urb(u132, endp, urb, -ENODEV);
1233 return;
1234 } else if (urb->status == -EINPROGRESS) {
1235 int retval;
1236 struct u132_ring *ring = endp->ring;
1237 u8 *u = urb->transfer_buffer;
1238 u8 *b = buf;
1239 int L = len;
1240 while (L-- > 0) {
1241 *u++ = *b++;
1242 }
1243 urb->actual_length = len;
1244 up(&u132->scheduler_lock);
1245 retval = usb_ftdi_elan_edset_empty(u132->platform_dev,
1246 ring->number, endp, urb, address, endp->usb_endp, 0x3,
1247 u132_hcd_initial_empty_sent);
1248 if (retval == 0) {
1249 } else
1250 u132_hcd_giveback_urb(u132, endp, urb, retval);
1251 return;
1252 } else {
1253 dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu"
1254 "s=%d\n", urb, urb->status);
1255 up(&u132->scheduler_lock);
1256 u132_hcd_giveback_urb(u132, endp, urb, urb->status);
1257 return;
1258 }
1259}
1260
1261static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf,
1262 int len, int toggle_bits, int error_count, int condition_code,
1263 int repeat_number, int halted, int skipped, int actual, int non_null)
1264{
1265 struct u132_endp *endp = data;
1266 struct u132 *u132 = endp->u132;
1267 u8 address = u132->addr[endp->usb_addr].address;
1268 down(&u132->scheduler_lock);
1269 if (u132->going > 1) {
1270 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
1271 , u132->going);
1272 up(&u132->scheduler_lock);
1273 u132_hcd_forget_urb(u132, endp, urb, -ENODEV);
1274 return;
1275 } else if (endp->dequeueing) {
1276 endp->dequeueing = 0;
1277 up(&u132->scheduler_lock);
1278 u132_hcd_giveback_urb(u132, endp, urb, -EINTR);
1279 return;
1280 } else if (u132->going > 0) {
1281 dev_err(&u132->platform_dev->dev, "device is being removed urb="
1282 "%p status=%d\n", urb, urb->status);
1283 up(&u132->scheduler_lock);
1284 u132_hcd_giveback_urb(u132, endp, urb, -ENODEV);
1285 return;
1286 } else if (urb->status == -EINPROGRESS) {
1287 int retval;
1288 struct u132_ring *ring = endp->ring;
1289 up(&u132->scheduler_lock);
1290 retval = usb_ftdi_elan_edset_input(u132->platform_dev,
1291 ring->number, endp, urb, address, endp->usb_endp, 0,
1292 u132_hcd_initial_input_recv);
1293 if (retval == 0) {
1294 } else
1295 u132_hcd_giveback_urb(u132, endp, urb, retval);
1296 return;
1297 } else {
1298 dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu"
1299 "s=%d\n", urb, urb->status);
1300 up(&u132->scheduler_lock);
1301 u132_hcd_giveback_urb(u132, endp, urb, urb->status);
1302 return;
1303 }
1304}
1305
Tony Olechd774efe2006-09-13 11:27:35 +01001306/*
1307* this work function is only executed from the work queue
1308*
1309*/
David Howellsc4028952006-11-22 14:57:56 +00001310static void u132_hcd_ring_work_scheduler(struct work_struct *work)
Tony Olechd774efe2006-09-13 11:27:35 +01001311{
David Howellsc4028952006-11-22 14:57:56 +00001312 struct u132_ring *ring =
1313 container_of(work, struct u132_ring, scheduler.work);
Tony Olechd774efe2006-09-13 11:27:35 +01001314 struct u132 *u132 = ring->u132;
1315 down(&u132->scheduler_lock);
1316 if (ring->in_use) {
1317 up(&u132->scheduler_lock);
1318 u132_ring_put_kref(u132, ring);
1319 return;
1320 } else if (ring->curr_endp) {
1321 struct u132_endp *last_endp = ring->curr_endp;
1322 struct list_head *scan;
1323 struct list_head *head = &last_endp->endp_ring;
1324 unsigned long wakeup = 0;
1325 list_for_each(scan, head) {
1326 struct u132_endp *endp = list_entry(scan,
1327 struct u132_endp, endp_ring);
1328 if (endp->queue_next == endp->queue_last) {
1329 } else if ((endp->delayed == 0)
1330 || time_after_eq(jiffies, endp->jiffies)) {
1331 ring->curr_endp = endp;
1332 u132_endp_cancel_work(u132, last_endp);
1333 u132_endp_queue_work(u132, last_endp, 0);
1334 up(&u132->scheduler_lock);
1335 u132_ring_put_kref(u132, ring);
1336 return;
1337 } else {
1338 unsigned long delta = endp->jiffies - jiffies;
1339 if (delta > wakeup)
1340 wakeup = delta;
1341 }
1342 }
1343 if (last_endp->queue_next == last_endp->queue_last) {
1344 } else if ((last_endp->delayed == 0) || time_after_eq(jiffies,
1345 last_endp->jiffies)) {
1346 u132_endp_cancel_work(u132, last_endp);
1347 u132_endp_queue_work(u132, last_endp, 0);
1348 up(&u132->scheduler_lock);
1349 u132_ring_put_kref(u132, ring);
1350 return;
1351 } else {
1352 unsigned long delta = last_endp->jiffies - jiffies;
1353 if (delta > wakeup)
1354 wakeup = delta;
1355 }
1356 if (wakeup > 0) {
1357 u132_ring_requeue_work(u132, ring, wakeup);
1358 up(&u132->scheduler_lock);
1359 return;
1360 } else {
1361 up(&u132->scheduler_lock);
1362 u132_ring_put_kref(u132, ring);
1363 return;
1364 }
1365 } else {
1366 up(&u132->scheduler_lock);
1367 u132_ring_put_kref(u132, ring);
1368 return;
1369 }
1370}
1371
David Howellsc4028952006-11-22 14:57:56 +00001372static void u132_hcd_endp_work_scheduler(struct work_struct *work)
Tony Olechd774efe2006-09-13 11:27:35 +01001373{
1374 struct u132_ring *ring;
David Howellsc4028952006-11-22 14:57:56 +00001375 struct u132_endp *endp =
1376 container_of(work, struct u132_endp, scheduler.work);
Tony Olechd774efe2006-09-13 11:27:35 +01001377 struct u132 *u132 = endp->u132;
1378 down(&u132->scheduler_lock);
1379 ring = endp->ring;
1380 if (endp->edset_flush) {
1381 endp->edset_flush = 0;
1382 if (endp->dequeueing)
1383 usb_ftdi_elan_edset_flush(u132->platform_dev,
1384 ring->number, endp);
1385 up(&u132->scheduler_lock);
1386 u132_endp_put_kref(u132, endp);
1387 return;
1388 } else if (endp->active) {
1389 up(&u132->scheduler_lock);
1390 u132_endp_put_kref(u132, endp);
1391 return;
1392 } else if (ring->in_use) {
1393 up(&u132->scheduler_lock);
1394 u132_endp_put_kref(u132, endp);
1395 return;
1396 } else if (endp->queue_next == endp->queue_last) {
1397 up(&u132->scheduler_lock);
1398 u132_endp_put_kref(u132, endp);
1399 return;
1400 } else if (endp->pipetype == PIPE_INTERRUPT) {
1401 u8 address = u132->addr[endp->usb_addr].address;
1402 if (ring->in_use) {
1403 up(&u132->scheduler_lock);
1404 u132_endp_put_kref(u132, endp);
1405 return;
1406 } else {
1407 int retval;
1408 struct urb *urb = endp->urb_list[ENDP_QUEUE_MASK &
1409 endp->queue_next];
1410 endp->active = 1;
1411 ring->curr_endp = endp;
1412 ring->in_use = 1;
1413 up(&u132->scheduler_lock);
1414 retval = edset_single(u132, ring, endp, urb, address,
1415 endp->toggle_bits, u132_hcd_interrupt_recv);
1416 if (retval == 0) {
1417 } else
1418 u132_hcd_giveback_urb(u132, endp, urb, retval);
1419 return;
1420 }
1421 } else if (endp->pipetype == PIPE_CONTROL) {
1422 u8 address = u132->addr[endp->usb_addr].address;
1423 if (ring->in_use) {
1424 up(&u132->scheduler_lock);
1425 u132_endp_put_kref(u132, endp);
1426 return;
1427 } else if (address == 0) {
1428 int retval;
1429 struct urb *urb = endp->urb_list[ENDP_QUEUE_MASK &
1430 endp->queue_next];
1431 endp->active = 1;
1432 ring->curr_endp = endp;
1433 ring->in_use = 1;
1434 up(&u132->scheduler_lock);
1435 retval = edset_setup(u132, ring, endp, urb, address,
1436 0x2, u132_hcd_initial_setup_sent);
1437 if (retval == 0) {
1438 } else
1439 u132_hcd_giveback_urb(u132, endp, urb, retval);
1440 return;
1441 } else if (endp->usb_addr == 0) {
1442 int retval;
1443 struct urb *urb = endp->urb_list[ENDP_QUEUE_MASK &
1444 endp->queue_next];
1445 endp->active = 1;
1446 ring->curr_endp = endp;
1447 ring->in_use = 1;
1448 up(&u132->scheduler_lock);
1449 retval = edset_setup(u132, ring, endp, urb, 0, 0x2,
1450 u132_hcd_enumeration_address_sent);
1451 if (retval == 0) {
1452 } else
1453 u132_hcd_giveback_urb(u132, endp, urb, retval);
1454 return;
1455 } else {
1456 int retval;
1457 u8 address = u132->addr[endp->usb_addr].address;
1458 struct urb *urb = endp->urb_list[ENDP_QUEUE_MASK &
1459 endp->queue_next];
1460 endp->active = 1;
1461 ring->curr_endp = endp;
1462 ring->in_use = 1;
1463 up(&u132->scheduler_lock);
1464 retval = edset_setup(u132, ring, endp, urb, address,
1465 0x2, u132_hcd_configure_setup_sent);
1466 if (retval == 0) {
1467 } else
1468 u132_hcd_giveback_urb(u132, endp, urb, retval);
1469 return;
1470 }
1471 } else {
1472 if (endp->input) {
1473 u8 address = u132->addr[endp->usb_addr].address;
1474 if (ring->in_use) {
1475 up(&u132->scheduler_lock);
1476 u132_endp_put_kref(u132, endp);
1477 return;
1478 } else {
1479 int retval;
1480 struct urb *urb = endp->urb_list[
1481 ENDP_QUEUE_MASK & endp->queue_next];
1482 endp->active = 1;
1483 ring->curr_endp = endp;
1484 ring->in_use = 1;
1485 up(&u132->scheduler_lock);
1486 retval = edset_input(u132, ring, endp, urb,
1487 address, endp->toggle_bits,
1488 u132_hcd_bulk_input_recv);
1489 if (retval == 0) {
1490 } else
1491 u132_hcd_giveback_urb(u132, endp, urb,
1492 retval);
1493 return;
1494 }
1495 } else { /* output pipe */
1496 u8 address = u132->addr[endp->usb_addr].address;
1497 if (ring->in_use) {
1498 up(&u132->scheduler_lock);
1499 u132_endp_put_kref(u132, endp);
1500 return;
1501 } else {
1502 int retval;
1503 struct urb *urb = endp->urb_list[
1504 ENDP_QUEUE_MASK & endp->queue_next];
1505 endp->active = 1;
1506 ring->curr_endp = endp;
1507 ring->in_use = 1;
1508 up(&u132->scheduler_lock);
1509 retval = edset_output(u132, ring, endp, urb,
1510 address, endp->toggle_bits,
1511 u132_hcd_bulk_output_sent);
1512 if (retval == 0) {
1513 } else
1514 u132_hcd_giveback_urb(u132, endp, urb,
1515 retval);
1516 return;
1517 }
1518 }
1519 }
1520}
1521
1522static void port_power(struct u132 *u132, int pn, int is_on)
1523{
1524 u132->port[pn].power = is_on;
1525}
1526
1527static void u132_power(struct u132 *u132, int is_on)
1528{
1529 struct usb_hcd *hcd = u132_to_hcd(u132)
1530 ; /* hub is inactive unless the port is powered */
1531 if (is_on) {
1532 if (u132->power)
1533 return;
1534 u132->power = 1;
1535 hcd->self.controller->power.power_state = PMSG_ON;
1536 } else {
1537 u132->power = 0;
1538 hcd->state = HC_STATE_HALT;
1539 hcd->self.controller->power.power_state = PMSG_SUSPEND;
1540 }
1541}
1542
1543static int u132_periodic_reinit(struct u132 *u132)
1544{
1545 int retval;
1546 u32 fi = u132->hc_fminterval & 0x03fff;
1547 u32 fit;
1548 u32 fminterval;
1549 retval = u132_read_pcimem(u132, fminterval, &fminterval);
1550 if (retval)
1551 return retval;
1552 fit = fminterval & FIT;
1553 retval = u132_write_pcimem(u132, fminterval,
1554 (fit ^ FIT) | u132->hc_fminterval);
1555 if (retval)
1556 return retval;
1557 retval = u132_write_pcimem(u132, periodicstart,
1558 ((9 *fi) / 10) & 0x3fff);
1559 if (retval)
1560 return retval;
1561 return 0;
1562}
1563
1564static char *hcfs2string(int state)
1565{
1566 switch (state) {
1567 case OHCI_USB_RESET:
1568 return "reset";
1569 case OHCI_USB_RESUME:
1570 return "resume";
1571 case OHCI_USB_OPER:
1572 return "operational";
1573 case OHCI_USB_SUSPEND:
1574 return "suspend";
1575 }
1576 return "?";
1577}
1578
Tony Olechd774efe2006-09-13 11:27:35 +01001579static int u132_init(struct u132 *u132)
1580{
1581 int retval;
1582 u32 control;
1583 u132_disable(u132);
Tony Olech4b873612006-12-06 13:16:22 +00001584 u132->next_statechange = jiffies;
Tony Olechd774efe2006-09-13 11:27:35 +01001585 retval = u132_write_pcimem(u132, intrdisable, OHCI_INTR_MIE);
1586 if (retval)
1587 return retval;
1588 retval = u132_read_pcimem(u132, control, &control);
1589 if (retval)
1590 return retval;
1591 if (u132->num_ports == 0) {
1592 u32 rh_a = -1;
1593 retval = u132_read_pcimem(u132, roothub.a, &rh_a);
1594 if (retval)
1595 return retval;
1596 u132->num_ports = rh_a & RH_A_NDP;
1597 retval = read_roothub_info(u132);
1598 if (retval)
1599 return retval;
1600 }
1601 if (u132->num_ports > MAX_U132_PORTS) {
1602 return -EINVAL;
1603 }
1604 return 0;
1605}
1606
1607
1608/* Start an OHCI controller, set the BUS operational
1609* resets USB and controller
1610* enable interrupts
1611*/
1612static int u132_run(struct u132 *u132)
1613{
1614 int retval;
1615 u32 control;
1616 u32 status;
1617 u32 fminterval;
1618 u32 periodicstart;
1619 u32 cmdstatus;
1620 u32 roothub_a;
1621 int mask = OHCI_INTR_INIT;
1622 int first = u132->hc_fminterval == 0;
1623 int sleep_time = 0;
1624 int reset_timeout = 30; /* ... allow extra time */
1625 u132_disable(u132);
1626 if (first) {
1627 u32 temp;
1628 retval = u132_read_pcimem(u132, fminterval, &temp);
1629 if (retval)
1630 return retval;
1631 u132->hc_fminterval = temp & 0x3fff;
1632 if (u132->hc_fminterval != FI) {
1633 }
1634 u132->hc_fminterval |= FSMP(u132->hc_fminterval) << 16;
1635 }
1636 retval = u132_read_pcimem(u132, control, &u132->hc_control);
1637 if (retval)
1638 return retval;
1639 dev_info(&u132->platform_dev->dev, "resetting from state '%s', control "
1640 "= %08X\n", hcfs2string(u132->hc_control & OHCI_CTRL_HCFS),
1641 u132->hc_control);
1642 switch (u132->hc_control & OHCI_CTRL_HCFS) {
1643 case OHCI_USB_OPER:
1644 sleep_time = 0;
1645 break;
1646 case OHCI_USB_SUSPEND:
1647 case OHCI_USB_RESUME:
1648 u132->hc_control &= OHCI_CTRL_RWC;
1649 u132->hc_control |= OHCI_USB_RESUME;
1650 sleep_time = 10;
1651 break;
1652 default:
1653 u132->hc_control &= OHCI_CTRL_RWC;
1654 u132->hc_control |= OHCI_USB_RESET;
1655 sleep_time = 50;
1656 break;
1657 }
1658 retval = u132_write_pcimem(u132, control, u132->hc_control);
1659 if (retval)
1660 return retval;
1661 retval = u132_read_pcimem(u132, control, &control);
1662 if (retval)
1663 return retval;
1664 msleep(sleep_time);
1665 retval = u132_read_pcimem(u132, roothub.a, &roothub_a);
1666 if (retval)
1667 return retval;
1668 if (!(roothub_a & RH_A_NPS)) {
1669 int temp; /* power down each port */
1670 for (temp = 0; temp < u132->num_ports; temp++) {
1671 retval = u132_write_pcimem(u132,
1672 roothub.portstatus[temp], RH_PS_LSDA);
1673 if (retval)
1674 return retval;
1675 }
1676 }
1677 retval = u132_read_pcimem(u132, control, &control);
1678 if (retval)
1679 return retval;
1680 retry:retval = u132_read_pcimem(u132, cmdstatus, &status);
1681 if (retval)
1682 return retval;
Tony Olech4b873612006-12-06 13:16:22 +00001683 retval = u132_write_pcimem(u132, cmdstatus, OHCI_HCR);
Tony Olechd774efe2006-09-13 11:27:35 +01001684 if (retval)
1685 return retval;
1686 extra:{
1687 retval = u132_read_pcimem(u132, cmdstatus, &status);
1688 if (retval)
1689 return retval;
1690 if (0 != (status & OHCI_HCR)) {
1691 if (--reset_timeout == 0) {
1692 dev_err(&u132->platform_dev->dev, "USB HC reset"
1693 " timed out!\n");
1694 return -ENODEV;
1695 } else {
1696 msleep(5);
1697 goto extra;
1698 }
1699 }
1700 }
1701 if (u132->flags & OHCI_QUIRK_INITRESET) {
1702 retval = u132_write_pcimem(u132, control, u132->hc_control);
1703 if (retval)
1704 return retval;
1705 retval = u132_read_pcimem(u132, control, &control);
1706 if (retval)
1707 return retval;
1708 }
1709 retval = u132_write_pcimem(u132, ed_controlhead, 0x00000000);
1710 if (retval)
1711 return retval;
1712 retval = u132_write_pcimem(u132, ed_bulkhead, 0x11000000);
1713 if (retval)
1714 return retval;
1715 retval = u132_write_pcimem(u132, hcca, 0x00000000);
1716 if (retval)
1717 return retval;
1718 retval = u132_periodic_reinit(u132);
1719 if (retval)
1720 return retval;
1721 retval = u132_read_pcimem(u132, fminterval, &fminterval);
1722 if (retval)
1723 return retval;
1724 retval = u132_read_pcimem(u132, periodicstart, &periodicstart);
1725 if (retval)
1726 return retval;
1727 if (0 == (fminterval & 0x3fff0000) || 0 == periodicstart) {
1728 if (!(u132->flags & OHCI_QUIRK_INITRESET)) {
1729 u132->flags |= OHCI_QUIRK_INITRESET;
1730 goto retry;
1731 } else
1732 dev_err(&u132->platform_dev->dev, "init err(%08x %04x)"
1733 "\n", fminterval, periodicstart);
1734 } /* start controller operations */
1735 u132->hc_control &= OHCI_CTRL_RWC;
1736 u132->hc_control |= OHCI_CONTROL_INIT | OHCI_CTRL_BLE | OHCI_USB_OPER;
1737 retval = u132_write_pcimem(u132, control, u132->hc_control);
1738 if (retval)
1739 return retval;
Tony Olech4b873612006-12-06 13:16:22 +00001740 retval = u132_write_pcimem(u132, cmdstatus, OHCI_BLF);
Tony Olechd774efe2006-09-13 11:27:35 +01001741 if (retval)
1742 return retval;
1743 retval = u132_read_pcimem(u132, cmdstatus, &cmdstatus);
1744 if (retval)
1745 return retval;
1746 retval = u132_read_pcimem(u132, control, &control);
1747 if (retval)
1748 return retval;
1749 u132_to_hcd(u132)->state = HC_STATE_RUNNING;
1750 retval = u132_write_pcimem(u132, roothub.status, RH_HS_DRWE);
1751 if (retval)
1752 return retval;
1753 retval = u132_write_pcimem(u132, intrstatus, mask);
1754 if (retval)
1755 return retval;
1756 retval = u132_write_pcimem(u132, intrdisable,
1757 OHCI_INTR_MIE | OHCI_INTR_OC | OHCI_INTR_RHSC | OHCI_INTR_FNO |
1758 OHCI_INTR_UE | OHCI_INTR_RD | OHCI_INTR_SF | OHCI_INTR_WDH |
1759 OHCI_INTR_SO);
1760 if (retval)
1761 return retval; /* handle root hub init quirks ... */
1762 retval = u132_read_pcimem(u132, roothub.a, &roothub_a);
1763 if (retval)
1764 return retval;
1765 roothub_a &= ~(RH_A_PSM | RH_A_OCPM);
1766 if (u132->flags & OHCI_QUIRK_SUPERIO) {
1767 roothub_a |= RH_A_NOCP;
1768 roothub_a &= ~(RH_A_POTPGT | RH_A_NPS);
1769 retval = u132_write_pcimem(u132, roothub.a, roothub_a);
1770 if (retval)
1771 return retval;
1772 } else if ((u132->flags & OHCI_QUIRK_AMD756) || distrust_firmware) {
1773 roothub_a |= RH_A_NPS;
1774 retval = u132_write_pcimem(u132, roothub.a, roothub_a);
1775 if (retval)
1776 return retval;
1777 }
1778 retval = u132_write_pcimem(u132, roothub.status, RH_HS_LPSC);
1779 if (retval)
1780 return retval;
1781 retval = u132_write_pcimem(u132, roothub.b,
1782 (roothub_a & RH_A_NPS) ? 0 : RH_B_PPCM);
1783 if (retval)
1784 return retval;
1785 retval = u132_read_pcimem(u132, control, &control);
1786 if (retval)
1787 return retval;
1788 mdelay((roothub_a >> 23) & 0x1fe);
1789 u132_to_hcd(u132)->state = HC_STATE_RUNNING;
1790 return 0;
1791}
1792
1793static void u132_hcd_stop(struct usb_hcd *hcd)
1794{
1795 struct u132 *u132 = hcd_to_u132(hcd);
1796 if (u132->going > 1) {
Tony Olech4b873612006-12-06 13:16:22 +00001797 dev_err(&u132->platform_dev->dev, "u132 device %p(hcd=%p) has b"
1798 "een removed %d\n", u132, hcd, u132->going);
Tony Olechd774efe2006-09-13 11:27:35 +01001799 } else if (u132->going > 0) {
1800 dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov"
1801 "ed\n", hcd);
1802 } else {
1803 down(&u132->sw_lock);
1804 msleep(100);
1805 u132_power(u132, 0);
1806 up(&u132->sw_lock);
1807 }
1808}
1809
1810static int u132_hcd_start(struct usb_hcd *hcd)
1811{
1812 struct u132 *u132 = hcd_to_u132(hcd);
1813 if (u132->going > 1) {
1814 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
1815 , u132->going);
1816 return -ENODEV;
1817 } else if (u132->going > 0) {
1818 dev_err(&u132->platform_dev->dev, "device is being removed\n");
1819 return -ESHUTDOWN;
1820 } else if (hcd->self.controller) {
1821 int retval;
1822 struct platform_device *pdev =
1823 to_platform_device(hcd->self.controller);
1824 u16 vendor = ((struct u132_platform_data *)
1825 (pdev->dev.platform_data))->vendor;
1826 u16 device = ((struct u132_platform_data *)
1827 (pdev->dev.platform_data))->device;
1828 down(&u132->sw_lock);
1829 msleep(10);
1830 if (vendor == PCI_VENDOR_ID_AMD && device == 0x740c) {
1831 u132->flags = OHCI_QUIRK_AMD756;
1832 } else if (vendor == PCI_VENDOR_ID_OPTI && device == 0xc861) {
1833 dev_err(&u132->platform_dev->dev, "WARNING: OPTi workar"
1834 "ounds unavailable\n");
1835 } else if (vendor == PCI_VENDOR_ID_COMPAQ && device == 0xa0f8)
1836 u132->flags |= OHCI_QUIRK_ZFMICRO;
1837 retval = u132_run(u132);
1838 if (retval) {
1839 u132_disable(u132);
1840 u132->going = 1;
1841 }
1842 msleep(100);
1843 up(&u132->sw_lock);
1844 return retval;
1845 } else {
1846 dev_err(&u132->platform_dev->dev, "platform_device missing\n");
1847 return -ENODEV;
1848 }
1849}
1850
1851static int u132_hcd_reset(struct usb_hcd *hcd)
1852{
1853 struct u132 *u132 = hcd_to_u132(hcd);
1854 if (u132->going > 1) {
1855 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
1856 , u132->going);
1857 return -ENODEV;
1858 } else if (u132->going > 0) {
1859 dev_err(&u132->platform_dev->dev, "device is being removed\n");
1860 return -ESHUTDOWN;
1861 } else {
1862 int retval;
1863 down(&u132->sw_lock);
1864 retval = u132_init(u132);
1865 if (retval) {
1866 u132_disable(u132);
1867 u132->going = 1;
1868 }
1869 up(&u132->sw_lock);
1870 return retval;
1871 }
1872}
1873
1874static int create_endpoint_and_queue_int(struct u132 *u132,
1875 struct u132_udev *udev, struct usb_host_endpoint *hep, struct urb *urb,
1876 struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address,
1877 gfp_t mem_flags)
1878{
1879 struct u132_ring *ring;
1880 unsigned long irqs;
1881 u8 endp_number = ++u132->num_endpoints;
1882 struct u132_endp *endp = hep->hcpriv = u132->endp[endp_number - 1] =
1883 kmalloc(sizeof(struct u132_endp), mem_flags);
1884 if (!endp) {
1885 return -ENOMEM;
1886 }
David Howellsc4028952006-11-22 14:57:56 +00001887 INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler);
Tony Olechd774efe2006-09-13 11:27:35 +01001888 spin_lock_init(&endp->queue_lock.slock);
1889 INIT_LIST_HEAD(&endp->urb_more);
1890 ring = endp->ring = &u132->ring[0];
1891 if (ring->curr_endp) {
1892 list_add_tail(&endp->endp_ring, &ring->curr_endp->endp_ring);
1893 } else {
1894 INIT_LIST_HEAD(&endp->endp_ring);
1895 ring->curr_endp = endp;
1896 }
1897 ring->length += 1;
1898 endp->dequeueing = 0;
1899 endp->edset_flush = 0;
1900 endp->active = 0;
1901 endp->delayed = 0;
1902 endp->endp_number = endp_number;
1903 endp->u132 = u132;
1904 endp->hep = hep;
1905 endp->pipetype = usb_pipetype(urb->pipe);
1906 u132_endp_init_kref(u132, endp);
1907 if (usb_pipein(urb->pipe)) {
1908 endp->toggle_bits = 0x2;
1909 usb_settoggle(udev->usb_device, usb_endp, 0, 0);
1910 endp->input = 1;
1911 endp->output = 0;
1912 udev->endp_number_in[usb_endp] = endp_number;
1913 u132_udev_get_kref(u132, udev);
1914 } else {
1915 endp->toggle_bits = 0x2;
1916 usb_settoggle(udev->usb_device, usb_endp, 1, 0);
1917 endp->input = 0;
1918 endp->output = 1;
1919 udev->endp_number_out[usb_endp] = endp_number;
1920 u132_udev_get_kref(u132, udev);
1921 }
1922 urb->hcpriv = u132;
1923 spin_lock_irqsave(&endp->queue_lock.slock, irqs);
1924 endp->delayed = 1;
1925 endp->jiffies = jiffies + msecs_to_jiffies(urb->interval);
1926 endp->udev_number = address;
1927 endp->usb_addr = usb_addr;
1928 endp->usb_endp = usb_endp;
1929 endp->queue_size = 1;
1930 endp->queue_last = 0;
1931 endp->queue_next = 0;
1932 endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb;
1933 spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
1934 u132_endp_queue_work(u132, endp, msecs_to_jiffies(urb->interval));
1935 return 0;
1936}
1937
1938static int queue_int_on_old_endpoint(struct u132 *u132, struct u132_udev *udev,
1939 struct usb_host_endpoint *hep, struct urb *urb,
1940 struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr,
1941 u8 usb_endp, u8 address)
1942{
1943 urb->hcpriv = u132;
1944 endp->delayed = 1;
1945 endp->jiffies = jiffies + msecs_to_jiffies(urb->interval);
1946 if (endp->queue_size++ < ENDP_QUEUE_SIZE) {
1947 endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb;
1948 } else {
1949 struct u132_urbq *urbq = kmalloc(sizeof(struct u132_urbq),
1950 GFP_ATOMIC);
1951 if (urbq == NULL) {
1952 endp->queue_size -= 1;
1953 return -ENOMEM;
1954 } else {
1955 list_add_tail(&urbq->urb_more, &endp->urb_more);
1956 urbq->urb = urb;
1957 }
1958 }
1959 return 0;
1960}
1961
1962static int create_endpoint_and_queue_bulk(struct u132 *u132,
1963 struct u132_udev *udev, struct usb_host_endpoint *hep, struct urb *urb,
1964 struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address,
1965 gfp_t mem_flags)
1966{
1967 int ring_number;
1968 struct u132_ring *ring;
1969 unsigned long irqs;
1970 u8 endp_number = ++u132->num_endpoints;
1971 struct u132_endp *endp = hep->hcpriv = u132->endp[endp_number - 1] =
1972 kmalloc(sizeof(struct u132_endp), mem_flags);
1973 if (!endp) {
1974 return -ENOMEM;
1975 }
David Howellsc4028952006-11-22 14:57:56 +00001976 INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler);
Tony Olechd774efe2006-09-13 11:27:35 +01001977 spin_lock_init(&endp->queue_lock.slock);
1978 INIT_LIST_HEAD(&endp->urb_more);
1979 endp->dequeueing = 0;
1980 endp->edset_flush = 0;
1981 endp->active = 0;
1982 endp->delayed = 0;
1983 endp->endp_number = endp_number;
1984 endp->u132 = u132;
1985 endp->hep = hep;
1986 endp->pipetype = usb_pipetype(urb->pipe);
1987 u132_endp_init_kref(u132, endp);
1988 if (usb_pipein(urb->pipe)) {
1989 endp->toggle_bits = 0x2;
1990 usb_settoggle(udev->usb_device, usb_endp, 0, 0);
1991 ring_number = 3;
1992 endp->input = 1;
1993 endp->output = 0;
1994 udev->endp_number_in[usb_endp] = endp_number;
1995 u132_udev_get_kref(u132, udev);
1996 } else {
1997 endp->toggle_bits = 0x2;
1998 usb_settoggle(udev->usb_device, usb_endp, 1, 0);
1999 ring_number = 2;
2000 endp->input = 0;
2001 endp->output = 1;
2002 udev->endp_number_out[usb_endp] = endp_number;
2003 u132_udev_get_kref(u132, udev);
2004 }
2005 ring = endp->ring = &u132->ring[ring_number - 1];
2006 if (ring->curr_endp) {
2007 list_add_tail(&endp->endp_ring, &ring->curr_endp->endp_ring);
2008 } else {
2009 INIT_LIST_HEAD(&endp->endp_ring);
2010 ring->curr_endp = endp;
2011 }
2012 ring->length += 1;
2013 urb->hcpriv = u132;
2014 spin_lock_irqsave(&endp->queue_lock.slock, irqs);
2015 endp->udev_number = address;
2016 endp->usb_addr = usb_addr;
2017 endp->usb_endp = usb_endp;
2018 endp->queue_size = 1;
2019 endp->queue_last = 0;
2020 endp->queue_next = 0;
2021 endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb;
2022 spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
2023 u132_endp_queue_work(u132, endp, 0);
2024 return 0;
2025}
2026
2027static int queue_bulk_on_old_endpoint(struct u132 *u132, struct u132_udev *udev,
2028 struct usb_host_endpoint *hep, struct urb *urb,
2029 struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr,
2030 u8 usb_endp, u8 address)
2031{
2032 urb->hcpriv = u132;
2033 if (endp->queue_size++ < ENDP_QUEUE_SIZE) {
2034 endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb;
2035 } else {
2036 struct u132_urbq *urbq = kmalloc(sizeof(struct u132_urbq),
2037 GFP_ATOMIC);
2038 if (urbq == NULL) {
2039 endp->queue_size -= 1;
2040 return -ENOMEM;
2041 } else {
2042 list_add_tail(&urbq->urb_more, &endp->urb_more);
2043 urbq->urb = urb;
2044 }
2045 }
2046 return 0;
2047}
2048
2049static int create_endpoint_and_queue_control(struct u132 *u132,
2050 struct usb_host_endpoint *hep, struct urb *urb,
2051 struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp,
2052 gfp_t mem_flags)
2053{
2054 struct u132_ring *ring;
2055 u8 endp_number = ++u132->num_endpoints;
2056 struct u132_endp *endp = hep->hcpriv = u132->endp[endp_number - 1] =
2057 kmalloc(sizeof(struct u132_endp), mem_flags);
2058 if (!endp) {
2059 return -ENOMEM;
2060 }
David Howellsc4028952006-11-22 14:57:56 +00002061 INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler);
Tony Olechd774efe2006-09-13 11:27:35 +01002062 spin_lock_init(&endp->queue_lock.slock);
2063 INIT_LIST_HEAD(&endp->urb_more);
2064 ring = endp->ring = &u132->ring[0];
2065 if (ring->curr_endp) {
2066 list_add_tail(&endp->endp_ring, &ring->curr_endp->endp_ring);
2067 } else {
2068 INIT_LIST_HEAD(&endp->endp_ring);
2069 ring->curr_endp = endp;
2070 }
2071 ring->length += 1;
2072 endp->dequeueing = 0;
2073 endp->edset_flush = 0;
2074 endp->active = 0;
2075 endp->delayed = 0;
2076 endp->endp_number = endp_number;
2077 endp->u132 = u132;
2078 endp->hep = hep;
2079 u132_endp_init_kref(u132, endp);
2080 u132_endp_get_kref(u132, endp);
2081 if (usb_addr == 0) {
2082 unsigned long irqs;
2083 u8 address = u132->addr[usb_addr].address;
2084 struct u132_udev *udev = &u132->udev[address];
2085 endp->udev_number = address;
2086 endp->usb_addr = usb_addr;
2087 endp->usb_endp = usb_endp;
2088 endp->input = 1;
2089 endp->output = 1;
2090 endp->pipetype = usb_pipetype(urb->pipe);
2091 u132_udev_init_kref(u132, udev);
2092 u132_udev_get_kref(u132, udev);
2093 udev->endp_number_in[usb_endp] = endp_number;
2094 udev->endp_number_out[usb_endp] = endp_number;
2095 urb->hcpriv = u132;
2096 spin_lock_irqsave(&endp->queue_lock.slock, irqs);
2097 endp->queue_size = 1;
2098 endp->queue_last = 0;
2099 endp->queue_next = 0;
2100 endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb;
2101 spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
2102 u132_endp_queue_work(u132, endp, 0);
2103 return 0;
2104 } else { /*(usb_addr > 0) */
2105 unsigned long irqs;
2106 u8 address = u132->addr[usb_addr].address;
2107 struct u132_udev *udev = &u132->udev[address];
2108 endp->udev_number = address;
2109 endp->usb_addr = usb_addr;
2110 endp->usb_endp = usb_endp;
2111 endp->input = 1;
2112 endp->output = 1;
2113 endp->pipetype = usb_pipetype(urb->pipe);
2114 u132_udev_get_kref(u132, udev);
2115 udev->enumeration = 2;
2116 udev->endp_number_in[usb_endp] = endp_number;
2117 udev->endp_number_out[usb_endp] = endp_number;
2118 urb->hcpriv = u132;
2119 spin_lock_irqsave(&endp->queue_lock.slock, irqs);
2120 endp->queue_size = 1;
2121 endp->queue_last = 0;
2122 endp->queue_next = 0;
2123 endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb;
2124 spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
2125 u132_endp_queue_work(u132, endp, 0);
2126 return 0;
2127 }
2128}
2129
2130static int queue_control_on_old_endpoint(struct u132 *u132,
2131 struct usb_host_endpoint *hep, struct urb *urb,
2132 struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr,
2133 u8 usb_endp)
2134{
2135 if (usb_addr == 0) {
2136 if (usb_pipein(urb->pipe)) {
2137 urb->hcpriv = u132;
2138 if (endp->queue_size++ < ENDP_QUEUE_SIZE) {
2139 endp->urb_list[ENDP_QUEUE_MASK &
2140 endp->queue_last++] = urb;
2141 } else {
2142 struct u132_urbq *urbq =
2143 kmalloc(sizeof(struct u132_urbq),
2144 GFP_ATOMIC);
2145 if (urbq == NULL) {
2146 endp->queue_size -= 1;
2147 return -ENOMEM;
2148 } else {
2149 list_add_tail(&urbq->urb_more,
2150 &endp->urb_more);
2151 urbq->urb = urb;
2152 }
2153 }
2154 return 0;
2155 } else { /* usb_pipeout(urb->pipe) */
2156 struct u132_addr *addr = &u132->addr[usb_dev->devnum];
2157 int I = MAX_U132_UDEVS;
2158 int i = 0;
2159 while (--I > 0) {
2160 struct u132_udev *udev = &u132->udev[++i];
2161 if (udev->usb_device) {
2162 continue;
2163 } else {
2164 udev->enumeration = 1;
2165 u132->addr[0].address = i;
2166 endp->udev_number = i;
2167 udev->udev_number = i;
2168 udev->usb_addr = usb_dev->devnum;
2169 u132_udev_init_kref(u132, udev);
2170 udev->endp_number_in[usb_endp] =
2171 endp->endp_number;
2172 u132_udev_get_kref(u132, udev);
2173 udev->endp_number_out[usb_endp] =
2174 endp->endp_number;
2175 udev->usb_device = usb_dev;
2176 ((u8 *) (urb->setup_packet))[2] =
2177 addr->address = i;
2178 u132_udev_get_kref(u132, udev);
2179 break;
2180 }
2181 }
2182 if (I == 0) {
2183 dev_err(&u132->platform_dev->dev, "run out of d"
2184 "evice space\n");
2185 return -EINVAL;
2186 }
2187 urb->hcpriv = u132;
2188 if (endp->queue_size++ < ENDP_QUEUE_SIZE) {
2189 endp->urb_list[ENDP_QUEUE_MASK &
2190 endp->queue_last++] = urb;
2191 } else {
2192 struct u132_urbq *urbq =
2193 kmalloc(sizeof(struct u132_urbq),
2194 GFP_ATOMIC);
2195 if (urbq == NULL) {
2196 endp->queue_size -= 1;
2197 return -ENOMEM;
2198 } else {
2199 list_add_tail(&urbq->urb_more,
2200 &endp->urb_more);
2201 urbq->urb = urb;
2202 }
2203 }
2204 return 0;
2205 }
2206 } else { /*(usb_addr > 0) */
2207 u8 address = u132->addr[usb_addr].address;
2208 struct u132_udev *udev = &u132->udev[address];
2209 urb->hcpriv = u132;
2210 if (udev->enumeration == 2) {
2211 } else
2212 udev->enumeration = 2;
2213 if (endp->queue_size++ < ENDP_QUEUE_SIZE) {
2214 endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] =
2215 urb;
2216 } else {
2217 struct u132_urbq *urbq =
2218 kmalloc(sizeof(struct u132_urbq), GFP_ATOMIC);
2219 if (urbq == NULL) {
2220 endp->queue_size -= 1;
2221 return -ENOMEM;
2222 } else {
2223 list_add_tail(&urbq->urb_more, &endp->urb_more);
2224 urbq->urb = urb;
2225 }
2226 }
2227 return 0;
2228 }
2229}
2230
2231static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep,
2232 struct urb *urb, gfp_t mem_flags)
2233{
2234 struct u132 *u132 = hcd_to_u132(hcd);
2235 if (irqs_disabled()) {
2236 if (__GFP_WAIT & mem_flags) {
2237 printk(KERN_ERR "invalid context for function that migh"
2238 "t sleep\n");
2239 return -EINVAL;
2240 }
2241 }
2242 if (u132->going > 1) {
2243 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
2244 , u132->going);
2245 return -ENODEV;
2246 } else if (u132->going > 0) {
2247 dev_err(&u132->platform_dev->dev, "device is being removed urb="
2248 "%p status=%d\n", urb, urb->status);
2249 return -ESHUTDOWN;
2250 } else {
2251 u8 usb_addr = usb_pipedevice(urb->pipe);
2252 u8 usb_endp = usb_pipeendpoint(urb->pipe);
2253 struct usb_device *usb_dev = urb->dev;
2254 if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
2255 u8 address = u132->addr[usb_addr].address;
2256 struct u132_udev *udev = &u132->udev[address];
2257 struct u132_endp *endp = hep->hcpriv;
2258 urb->actual_length = 0;
2259 if (endp) {
2260 unsigned long irqs;
2261 int retval;
2262 spin_lock_irqsave(&endp->queue_lock.slock,
2263 irqs);
2264 retval = queue_int_on_old_endpoint(u132, udev,
2265 hep, urb, usb_dev, endp, usb_addr,
2266 usb_endp, address);
2267 spin_unlock_irqrestore(&endp->queue_lock.slock,
2268 irqs);
2269 if (retval) {
2270 return retval;
2271 } else {
2272 u132_endp_queue_work(u132, endp,
2273 msecs_to_jiffies(urb->interval))
2274 ;
2275 return 0;
2276 }
2277 } else if (u132->num_endpoints == MAX_U132_ENDPS) {
2278 return -EINVAL;
2279 } else { /*(endp == NULL) */
2280 return create_endpoint_and_queue_int(u132, udev,
2281 hep, urb, usb_dev, usb_addr, usb_endp,
2282 address, mem_flags);
2283 }
2284 } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
2285 dev_err(&u132->platform_dev->dev, "the hardware does no"
2286 "t support PIPE_ISOCHRONOUS\n");
2287 return -EINVAL;
2288 } else if (usb_pipetype(urb->pipe) == PIPE_BULK) {
2289 u8 address = u132->addr[usb_addr].address;
2290 struct u132_udev *udev = &u132->udev[address];
2291 struct u132_endp *endp = hep->hcpriv;
2292 urb->actual_length = 0;
2293 if (endp) {
2294 unsigned long irqs;
2295 int retval;
2296 spin_lock_irqsave(&endp->queue_lock.slock,
2297 irqs);
2298 retval = queue_bulk_on_old_endpoint(u132, udev,
2299 hep, urb, usb_dev, endp, usb_addr,
2300 usb_endp, address);
2301 spin_unlock_irqrestore(&endp->queue_lock.slock,
2302 irqs);
2303 if (retval) {
2304 return retval;
2305 } else {
2306 u132_endp_queue_work(u132, endp, 0);
2307 return 0;
2308 }
2309 } else if (u132->num_endpoints == MAX_U132_ENDPS) {
2310 return -EINVAL;
2311 } else
2312 return create_endpoint_and_queue_bulk(u132,
2313 udev, hep, urb, usb_dev, usb_addr,
2314 usb_endp, address, mem_flags);
2315 } else {
2316 struct u132_endp *endp = hep->hcpriv;
2317 u16 urb_size = 8;
2318 u8 *b = urb->setup_packet;
2319 int i = 0;
2320 char data[30 *3 + 4];
2321 char *d = data;
2322 int m = (sizeof(data) - 1) / 3;
2323 int l = 0;
2324 data[0] = 0;
2325 while (urb_size-- > 0) {
2326 if (i > m) {
2327 } else if (i++ < m) {
2328 int w = sprintf(d, " %02X", *b++);
2329 d += w;
2330 l += w;
2331 } else
2332 d += sprintf(d, " ..");
2333 }
2334 if (endp) {
2335 unsigned long irqs;
2336 int retval;
2337 spin_lock_irqsave(&endp->queue_lock.slock,
2338 irqs);
2339 retval = queue_control_on_old_endpoint(u132,
2340 hep, urb, usb_dev, endp, usb_addr,
2341 usb_endp);
2342 spin_unlock_irqrestore(&endp->queue_lock.slock,
2343 irqs);
2344 if (retval) {
2345 return retval;
2346 } else {
2347 u132_endp_queue_work(u132, endp, 0);
2348 return 0;
2349 }
2350 } else if (u132->num_endpoints == MAX_U132_ENDPS) {
2351 return -EINVAL;
2352 } else
2353 return create_endpoint_and_queue_control(u132,
2354 hep, urb, usb_dev, usb_addr, usb_endp,
2355 mem_flags);
2356 }
2357 }
2358}
2359
2360static int dequeue_from_overflow_chain(struct u132 *u132,
2361 struct u132_endp *endp, struct urb *urb)
2362{
2363 struct list_head *scan;
2364 struct list_head *head = &endp->urb_more;
2365 list_for_each(scan, head) {
2366 struct u132_urbq *urbq = list_entry(scan, struct u132_urbq,
2367 urb_more);
2368 if (urbq->urb == urb) {
2369 struct usb_hcd *hcd = u132_to_hcd(u132);
2370 list_del(scan);
2371 endp->queue_size -= 1;
2372 urb->error_count = 0;
2373 urb->hcpriv = NULL;
David Howells7d12e782006-10-05 14:55:46 +01002374 usb_hcd_giveback_urb(hcd, urb);
Tony Olechd774efe2006-09-13 11:27:35 +01002375 return 0;
2376 } else
2377 continue;
2378 }
2379 dev_err(&u132->platform_dev->dev, "urb=%p not found in endp[%d]=%p ring"
2380 "[%d] %c%c usb_endp=%d usb_addr=%d size=%d next=%04X last=%04X"
2381 "\n", urb, endp->endp_number, endp, endp->ring->number,
2382 endp->input ? 'I' : ' ', endp->output ? 'O' : ' ',
2383 endp->usb_endp, endp->usb_addr, endp->queue_size,
2384 endp->queue_next, endp->queue_last);
2385 return -EINVAL;
2386}
2387
2388static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp,
2389 struct urb *urb)
2390{
2391 unsigned long irqs;
2392 spin_lock_irqsave(&endp->queue_lock.slock, irqs);
2393 if (endp->queue_size == 0) {
2394 dev_err(&u132->platform_dev->dev, "urb=%p not found in endp[%d]"
2395 "=%p ring[%d] %c%c usb_endp=%d usb_addr=%d\n", urb,
2396 endp->endp_number, endp, endp->ring->number,
2397 endp->input ? 'I' : ' ', endp->output ? 'O' : ' ',
2398 endp->usb_endp, endp->usb_addr);
2399 spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
2400 return -EINVAL;
2401 }
2402 if (urb == endp->urb_list[ENDP_QUEUE_MASK & endp->queue_next]) {
2403 if (endp->active) {
2404 endp->dequeueing = 1;
2405 endp->edset_flush = 1;
2406 u132_endp_queue_work(u132, endp, 0);
2407 spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
2408 urb->hcpriv = NULL;
2409 return 0;
2410 } else {
2411 spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
2412 u132_hcd_abandon_urb(u132, endp, urb, urb->status);
2413 return 0;
2414 }
2415 } else {
2416 u16 queue_list = 0;
2417 u16 queue_size = endp->queue_size;
2418 u16 queue_scan = endp->queue_next;
2419 struct urb **urb_slot = NULL;
2420 while (++queue_list < ENDP_QUEUE_SIZE && --queue_size > 0) {
2421 if (urb == endp->urb_list[ENDP_QUEUE_MASK &
2422 ++queue_scan]) {
2423 urb_slot = &endp->urb_list[ENDP_QUEUE_MASK &
2424 queue_scan];
2425 break;
2426 } else
2427 continue;
2428 }
2429 while (++queue_list < ENDP_QUEUE_SIZE && --queue_size > 0) {
2430 *urb_slot = endp->urb_list[ENDP_QUEUE_MASK &
2431 ++queue_scan];
2432 urb_slot = &endp->urb_list[ENDP_QUEUE_MASK &
2433 queue_scan];
2434 }
2435 if (urb_slot) {
2436 struct usb_hcd *hcd = u132_to_hcd(u132);
2437 endp->queue_size -= 1;
2438 if (list_empty(&endp->urb_more)) {
2439 spin_unlock_irqrestore(&endp->queue_lock.slock,
2440 irqs);
2441 } else {
2442 struct list_head *next = endp->urb_more.next;
2443 struct u132_urbq *urbq = list_entry(next,
2444 struct u132_urbq, urb_more);
2445 list_del(next);
2446 *urb_slot = urbq->urb;
2447 spin_unlock_irqrestore(&endp->queue_lock.slock,
2448 irqs);
2449 kfree(urbq);
2450 } urb->error_count = 0;
2451 urb->hcpriv = NULL;
David Howells7d12e782006-10-05 14:55:46 +01002452 usb_hcd_giveback_urb(hcd, urb);
Tony Olechd774efe2006-09-13 11:27:35 +01002453 return 0;
2454 } else if (list_empty(&endp->urb_more)) {
2455 dev_err(&u132->platform_dev->dev, "urb=%p not found in "
2456 "endp[%d]=%p ring[%d] %c%c usb_endp=%d usb_addr"
2457 "=%d size=%d next=%04X last=%04X\n", urb,
2458 endp->endp_number, endp, endp->ring->number,
2459 endp->input ? 'I' : ' ',
2460 endp->output ? 'O' : ' ', endp->usb_endp,
2461 endp->usb_addr, endp->queue_size,
2462 endp->queue_next, endp->queue_last);
2463 spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
2464 return -EINVAL;
2465 } else {
2466 int retval = dequeue_from_overflow_chain(u132, endp,
2467 urb);
2468 spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
2469 return retval;
2470 }
2471 }
2472}
2473
2474static int u132_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
2475{
2476 struct u132 *u132 = hcd_to_u132(hcd);
2477 if (u132->going > 2) {
2478 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
2479 , u132->going);
2480 return -ENODEV;
2481 } else {
2482 u8 usb_addr = usb_pipedevice(urb->pipe);
2483 u8 usb_endp = usb_pipeendpoint(urb->pipe);
2484 u8 address = u132->addr[usb_addr].address;
2485 struct u132_udev *udev = &u132->udev[address];
2486 if (usb_pipein(urb->pipe)) {
2487 u8 endp_number = udev->endp_number_in[usb_endp];
2488 struct u132_endp *endp = u132->endp[endp_number - 1];
2489 return u132_endp_urb_dequeue(u132, endp, urb);
2490 } else {
2491 u8 endp_number = udev->endp_number_out[usb_endp];
2492 struct u132_endp *endp = u132->endp[endp_number - 1];
2493 return u132_endp_urb_dequeue(u132, endp, urb);
2494 }
2495 }
2496}
2497
2498static void u132_endpoint_disable(struct usb_hcd *hcd,
2499 struct usb_host_endpoint *hep)
2500{
2501 struct u132 *u132 = hcd_to_u132(hcd);
2502 if (u132->going > 2) {
Tony Olech4b873612006-12-06 13:16:22 +00002503 dev_err(&u132->platform_dev->dev, "u132 device %p(hcd=%p hep=%p"
2504 ") has been removed %d\n", u132, hcd, hep,
2505 u132->going);
Tony Olechd774efe2006-09-13 11:27:35 +01002506 } else {
2507 struct u132_endp *endp = hep->hcpriv;
2508 if (endp)
2509 u132_endp_put_kref(u132, endp);
2510 }
2511}
2512
2513static int u132_get_frame(struct usb_hcd *hcd)
2514{
2515 struct u132 *u132 = hcd_to_u132(hcd);
2516 if (u132->going > 1) {
2517 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
2518 , u132->going);
2519 return -ENODEV;
2520 } else if (u132->going > 0) {
2521 dev_err(&u132->platform_dev->dev, "device is being removed\n");
2522 return -ESHUTDOWN;
2523 } else {
2524 int frame = 0;
2525 dev_err(&u132->platform_dev->dev, "TODO: u132_get_frame\n");
2526 msleep(100);
2527 return frame;
2528 }
2529}
2530
2531static int u132_roothub_descriptor(struct u132 *u132,
2532 struct usb_hub_descriptor *desc)
2533{
2534 int retval;
2535 u16 temp;
2536 u32 rh_a = -1;
2537 u32 rh_b = -1;
2538 retval = u132_read_pcimem(u132, roothub.a, &rh_a);
2539 if (retval)
2540 return retval;
2541 desc->bDescriptorType = 0x29;
2542 desc->bPwrOn2PwrGood = (rh_a & RH_A_POTPGT) >> 24;
2543 desc->bHubContrCurrent = 0;
2544 desc->bNbrPorts = u132->num_ports;
2545 temp = 1 + (u132->num_ports / 8);
2546 desc->bDescLength = 7 + 2 *temp;
2547 temp = 0;
2548 if (rh_a & RH_A_NPS)
2549 temp |= 0x0002;
2550 if (rh_a & RH_A_PSM)
2551 temp |= 0x0001;
2552 if (rh_a & RH_A_NOCP) {
2553 temp |= 0x0010;
2554 } else if (rh_a & RH_A_OCPM)
2555 temp |= 0x0008;
2556 desc->wHubCharacteristics = cpu_to_le16(temp);
2557 retval = u132_read_pcimem(u132, roothub.b, &rh_b);
2558 if (retval)
2559 return retval;
2560 memset(desc->bitmap, 0xff, sizeof(desc->bitmap));
2561 desc->bitmap[0] = rh_b & RH_B_DR;
2562 if (u132->num_ports > 7) {
2563 desc->bitmap[1] = (rh_b & RH_B_DR) >> 8;
2564 desc->bitmap[2] = 0xff;
2565 } else
2566 desc->bitmap[1] = 0xff;
2567 return 0;
2568}
2569
2570static int u132_roothub_status(struct u132 *u132, __le32 *desc)
2571{
2572 u32 rh_status = -1;
2573 int ret_status = u132_read_pcimem(u132, roothub.status, &rh_status);
2574 *desc = cpu_to_le32(rh_status);
2575 return ret_status;
2576}
2577
2578static int u132_roothub_portstatus(struct u132 *u132, __le32 *desc, u16 wIndex)
2579{
2580 if (wIndex == 0 || wIndex > u132->num_ports) {
2581 return -EINVAL;
2582 } else {
2583 int port = wIndex - 1;
2584 u32 rh_portstatus = -1;
2585 int ret_portstatus = u132_read_pcimem(u132,
2586 roothub.portstatus[port], &rh_portstatus);
2587 *desc = cpu_to_le32(rh_portstatus);
2588 if (*(u16 *) (desc + 2)) {
2589 dev_info(&u132->platform_dev->dev, "Port %d Status Chan"
2590 "ge = %08X\n", port, *desc);
2591 }
2592 return ret_portstatus;
2593 }
2594}
2595
2596
2597/* this timer value might be vendor-specific ... */
2598#define PORT_RESET_HW_MSEC 10
2599#define PORT_RESET_MSEC 10
2600/* wrap-aware logic morphed from <linux/jiffies.h> */
2601#define tick_before(t1, t2) ((s16)(((s16)(t1))-((s16)(t2))) < 0)
2602static int u132_roothub_portreset(struct u132 *u132, int port_index)
2603{
2604 int retval;
2605 u32 fmnumber;
2606 u16 now;
2607 u16 reset_done;
2608 retval = u132_read_pcimem(u132, fmnumber, &fmnumber);
2609 if (retval)
2610 return retval;
2611 now = fmnumber;
2612 reset_done = now + PORT_RESET_MSEC;
2613 do {
2614 u32 portstat;
2615 do {
2616 retval = u132_read_pcimem(u132,
2617 roothub.portstatus[port_index], &portstat);
2618 if (retval)
2619 return retval;
2620 if (RH_PS_PRS & portstat) {
2621 continue;
2622 } else
2623 break;
2624 } while (tick_before(now, reset_done));
2625 if (RH_PS_PRS & portstat)
2626 return -ENODEV;
2627 if (RH_PS_CCS & portstat) {
2628 if (RH_PS_PRSC & portstat) {
2629 retval = u132_write_pcimem(u132,
2630 roothub.portstatus[port_index],
2631 RH_PS_PRSC);
2632 if (retval)
2633 return retval;
2634 }
2635 } else
2636 break; /* start the next reset,
2637 sleep till it's probably done */
2638 retval = u132_write_pcimem(u132, roothub.portstatus[port_index],
2639 RH_PS_PRS);
2640 if (retval)
2641 return retval;
2642 msleep(PORT_RESET_HW_MSEC);
2643 retval = u132_read_pcimem(u132, fmnumber, &fmnumber);
2644 if (retval)
2645 return retval;
2646 now = fmnumber;
2647 } while (tick_before(now, reset_done));
2648 return 0;
2649}
2650
2651static int u132_roothub_setportfeature(struct u132 *u132, u16 wValue,
2652 u16 wIndex)
2653{
2654 if (wIndex == 0 || wIndex > u132->num_ports) {
2655 return -EINVAL;
2656 } else {
2657 int retval;
2658 int port_index = wIndex - 1;
2659 struct u132_port *port = &u132->port[port_index];
2660 port->Status &= ~(1 << wValue);
2661 switch (wValue) {
2662 case USB_PORT_FEAT_SUSPEND:
2663 retval = u132_write_pcimem(u132,
2664 roothub.portstatus[port_index], RH_PS_PSS);
2665 if (retval)
2666 return retval;
2667 return 0;
2668 case USB_PORT_FEAT_POWER:
2669 retval = u132_write_pcimem(u132,
2670 roothub.portstatus[port_index], RH_PS_PPS);
2671 if (retval)
2672 return retval;
2673 return 0;
2674 case USB_PORT_FEAT_RESET:
2675 retval = u132_roothub_portreset(u132, port_index);
2676 if (retval)
2677 return retval;
2678 return 0;
2679 default:
2680 return -EPIPE;
2681 }
2682 }
2683}
2684
2685static int u132_roothub_clearportfeature(struct u132 *u132, u16 wValue,
2686 u16 wIndex)
2687{
2688 if (wIndex == 0 || wIndex > u132->num_ports) {
2689 return -EINVAL;
2690 } else {
2691 int port_index = wIndex - 1;
2692 u32 temp;
2693 int retval;
2694 struct u132_port *port = &u132->port[port_index];
2695 port->Status &= ~(1 << wValue);
2696 switch (wValue) {
2697 case USB_PORT_FEAT_ENABLE:
2698 temp = RH_PS_CCS;
2699 break;
2700 case USB_PORT_FEAT_C_ENABLE:
2701 temp = RH_PS_PESC;
2702 break;
2703 case USB_PORT_FEAT_SUSPEND:
2704 temp = RH_PS_POCI;
2705 if ((u132->hc_control & OHCI_CTRL_HCFS)
2706 != OHCI_USB_OPER) {
2707 dev_err(&u132->platform_dev->dev, "TODO resume_"
2708 "root_hub\n");
2709 }
2710 break;
2711 case USB_PORT_FEAT_C_SUSPEND:
2712 temp = RH_PS_PSSC;
2713 break;
2714 case USB_PORT_FEAT_POWER:
2715 temp = RH_PS_LSDA;
2716 break;
2717 case USB_PORT_FEAT_C_CONNECTION:
2718 temp = RH_PS_CSC;
2719 break;
2720 case USB_PORT_FEAT_C_OVER_CURRENT:
2721 temp = RH_PS_OCIC;
2722 break;
2723 case USB_PORT_FEAT_C_RESET:
2724 temp = RH_PS_PRSC;
2725 break;
2726 default:
2727 return -EPIPE;
2728 }
2729 retval = u132_write_pcimem(u132, roothub.portstatus[port_index],
2730 temp);
2731 if (retval)
2732 return retval;
2733 return 0;
2734 }
2735}
2736
2737
2738/* the virtual root hub timer IRQ checks for hub status*/
2739static int u132_hub_status_data(struct usb_hcd *hcd, char *buf)
2740{
2741 struct u132 *u132 = hcd_to_u132(hcd);
2742 if (u132->going > 1) {
2743 dev_err(&u132->platform_dev->dev, "device hcd=%p has been remov"
2744 "ed %d\n", hcd, u132->going);
2745 return -ENODEV;
2746 } else if (u132->going > 0) {
2747 dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov"
2748 "ed\n", hcd);
Tony Olechd774efe2006-09-13 11:27:35 +01002749 return -ESHUTDOWN;
2750 } else {
2751 int i, changed = 0, length = 1;
2752 if (u132->flags & OHCI_QUIRK_AMD756) {
2753 if ((u132->hc_roothub_a & RH_A_NDP) > MAX_ROOT_PORTS) {
2754 dev_err(&u132->platform_dev->dev, "bogus NDP, r"
2755 "ereads as NDP=%d\n",
2756 u132->hc_roothub_a & RH_A_NDP);
2757 goto done;
2758 }
2759 }
2760 if (u132->hc_roothub_status & (RH_HS_LPSC | RH_HS_OCIC)) {
2761 buf[0] = changed = 1;
2762 } else
2763 buf[0] = 0;
2764 if (u132->num_ports > 7) {
2765 buf[1] = 0;
2766 length++;
2767 }
2768 for (i = 0; i < u132->num_ports; i++) {
2769 if (u132->hc_roothub_portstatus[i] & (RH_PS_CSC |
2770 RH_PS_PESC | RH_PS_PSSC | RH_PS_OCIC |
2771 RH_PS_PRSC)) {
2772 changed = 1;
2773 if (i < 7) {
2774 buf[0] |= 1 << (i + 1);
2775 } else
2776 buf[1] |= 1 << (i - 7);
2777 continue;
2778 }
2779 if (!(u132->hc_roothub_portstatus[i] & RH_PS_CCS)) {
2780 continue;
2781 }
2782 if ((u132->hc_roothub_portstatus[i] & RH_PS_PSS)) {
2783 continue;
2784 }
2785 }
2786 done:return changed ? length : 0;
2787 }
2788}
2789
2790static int u132_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
2791 u16 wIndex, char *buf, u16 wLength)
2792{
2793 struct u132 *u132 = hcd_to_u132(hcd);
2794 if (u132->going > 1) {
2795 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
2796 , u132->going);
2797 return -ENODEV;
2798 } else if (u132->going > 0) {
2799 dev_err(&u132->platform_dev->dev, "device is being removed\n");
2800 return -ESHUTDOWN;
2801 } else {
2802 int retval = 0;
2803 down(&u132->sw_lock);
2804 switch (typeReq) {
2805 case ClearHubFeature:
2806 switch (wValue) {
2807 case C_HUB_OVER_CURRENT:
2808 case C_HUB_LOCAL_POWER:
2809 break;
2810 default:
2811 goto stall;
2812 }
2813 break;
2814 case SetHubFeature:
2815 switch (wValue) {
2816 case C_HUB_OVER_CURRENT:
2817 case C_HUB_LOCAL_POWER:
2818 break;
2819 default:
2820 goto stall;
2821 }
2822 break;
2823 case ClearPortFeature:{
2824 retval = u132_roothub_clearportfeature(u132,
2825 wValue, wIndex);
2826 if (retval)
2827 goto error;
2828 break;
2829 }
2830 case GetHubDescriptor:{
2831 retval = u132_roothub_descriptor(u132,
2832 (struct usb_hub_descriptor *)buf);
2833 if (retval)
2834 goto error;
2835 break;
2836 }
2837 case GetHubStatus:{
2838 retval = u132_roothub_status(u132,
2839 (__le32 *) buf);
2840 if (retval)
2841 goto error;
2842 break;
2843 }
2844 case GetPortStatus:{
2845 retval = u132_roothub_portstatus(u132,
2846 (__le32 *) buf, wIndex);
2847 if (retval)
2848 goto error;
2849 break;
2850 }
2851 case SetPortFeature:{
2852 retval = u132_roothub_setportfeature(u132,
2853 wValue, wIndex);
2854 if (retval)
2855 goto error;
2856 break;
2857 }
2858 default:
2859 goto stall;
2860 error:u132_disable(u132);
2861 u132->going = 1;
2862 break;
2863 stall:retval = -EPIPE;
2864 break;
2865 }
2866 up(&u132->sw_lock);
2867 return retval;
2868 }
2869}
2870
2871static int u132_start_port_reset(struct usb_hcd *hcd, unsigned port_num)
2872{
2873 struct u132 *u132 = hcd_to_u132(hcd);
2874 if (u132->going > 1) {
2875 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
2876 , u132->going);
2877 return -ENODEV;
2878 } else if (u132->going > 0) {
2879 dev_err(&u132->platform_dev->dev, "device is being removed\n");
2880 return -ESHUTDOWN;
2881 } else
2882 return 0;
2883}
2884
2885static void u132_hub_irq_enable(struct usb_hcd *hcd)
2886{
2887 struct u132 *u132 = hcd_to_u132(hcd);
2888 if (u132->going > 1) {
2889 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
2890 , u132->going);
2891 } else if (u132->going > 0)
2892 dev_err(&u132->platform_dev->dev, "device is being removed\n");
2893}
2894
2895
2896#ifdef CONFIG_PM
2897static int u132_hcd_suspend(struct usb_hcd *hcd, pm_message_t message)
2898{
2899 struct u132 *u132 = hcd_to_u132(hcd);
2900 if (u132->going > 1) {
2901 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
2902 , u132->going);
2903 return -ENODEV;
2904 } else if (u132->going > 0) {
2905 dev_err(&u132->platform_dev->dev, "device is being removed\n");
2906 return -ESHUTDOWN;
2907 } else
2908 return 0;
2909}
2910
2911static int u132_hcd_resume(struct usb_hcd *hcd)
2912{
2913 struct u132 *u132 = hcd_to_u132(hcd);
2914 if (u132->going > 1) {
2915 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
2916 , u132->going);
2917 return -ENODEV;
2918 } else if (u132->going > 0) {
2919 dev_err(&u132->platform_dev->dev, "device is being removed\n");
2920 return -ESHUTDOWN;
2921 } else
2922 return 0;
2923}
2924
2925static int u132_bus_suspend(struct usb_hcd *hcd)
2926{
2927 struct u132 *u132 = hcd_to_u132(hcd);
2928 if (u132->going > 1) {
2929 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
2930 , u132->going);
2931 return -ENODEV;
2932 } else if (u132->going > 0) {
2933 dev_err(&u132->platform_dev->dev, "device is being removed\n");
2934 return -ESHUTDOWN;
2935 } else
2936 return 0;
2937}
2938
2939static int u132_bus_resume(struct usb_hcd *hcd)
2940{
2941 struct u132 *u132 = hcd_to_u132(hcd);
2942 if (u132->going > 1) {
2943 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
2944 , u132->going);
2945 return -ENODEV;
2946 } else if (u132->going > 0) {
2947 dev_err(&u132->platform_dev->dev, "device is being removed\n");
2948 return -ESHUTDOWN;
2949 } else
2950 return 0;
2951}
2952
2953#else
2954#define u132_hcd_suspend NULL
2955#define u132_hcd_resume NULL
2956#define u132_bus_suspend NULL
2957#define u132_bus_resume NULL
2958#endif
2959static struct hc_driver u132_hc_driver = {
2960 .description = hcd_name,
2961 .hcd_priv_size = sizeof(struct u132),
2962 .irq = NULL,
2963 .flags = HCD_USB11 | HCD_MEMORY,
2964 .reset = u132_hcd_reset,
2965 .start = u132_hcd_start,
2966 .suspend = u132_hcd_suspend,
2967 .resume = u132_hcd_resume,
2968 .stop = u132_hcd_stop,
2969 .urb_enqueue = u132_urb_enqueue,
2970 .urb_dequeue = u132_urb_dequeue,
2971 .endpoint_disable = u132_endpoint_disable,
2972 .get_frame_number = u132_get_frame,
2973 .hub_status_data = u132_hub_status_data,
2974 .hub_control = u132_hub_control,
2975 .bus_suspend = u132_bus_suspend,
2976 .bus_resume = u132_bus_resume,
2977 .start_port_reset = u132_start_port_reset,
2978 .hub_irq_enable = u132_hub_irq_enable,
2979};
2980
2981/*
2982* This function may be called by the USB core whilst the "usb_all_devices_rwsem"
2983* is held for writing, thus this module must not call usb_remove_hcd()
2984* synchronously - but instead should immediately stop activity to the
Matt LaPlante0779bf22006-11-30 05:24:39 +01002985* device and asynchronously call usb_remove_hcd()
Tony Olechd774efe2006-09-13 11:27:35 +01002986*/
2987static int __devexit u132_remove(struct platform_device *pdev)
2988{
2989 struct usb_hcd *hcd = platform_get_drvdata(pdev);
2990 if (hcd) {
2991 struct u132 *u132 = hcd_to_u132(hcd);
Tony Olechd774efe2006-09-13 11:27:35 +01002992 if (u132->going++ > 1) {
Tony Olech4b873612006-12-06 13:16:22 +00002993 dev_err(&u132->platform_dev->dev, "already being remove"
2994 "d\n");
Tony Olechd774efe2006-09-13 11:27:35 +01002995 return -ENODEV;
2996 } else {
2997 int rings = MAX_U132_RINGS;
2998 int endps = MAX_U132_ENDPS;
Tony Olech4b873612006-12-06 13:16:22 +00002999 dev_err(&u132->platform_dev->dev, "removing device u132"
3000 ".%d\n", u132->sequence_num);
Tony Olechd774efe2006-09-13 11:27:35 +01003001 msleep(100);
3002 down(&u132->sw_lock);
3003 u132_monitor_cancel_work(u132);
3004 while (rings-- > 0) {
3005 struct u132_ring *ring = &u132->ring[rings];
3006 u132_ring_cancel_work(u132, ring);
3007 } while (endps-- > 0) {
3008 struct u132_endp *endp = u132->endp[endps];
3009 if (endp)
3010 u132_endp_cancel_work(u132, endp);
3011 }
3012 u132->going += 1;
3013 printk(KERN_INFO "removing device u132.%d\n",
3014 u132->sequence_num);
3015 up(&u132->sw_lock);
3016 usb_remove_hcd(hcd);
3017 u132_u132_put_kref(u132);
3018 return 0;
3019 }
3020 } else
3021 return 0;
3022}
3023
3024static void u132_initialise(struct u132 *u132, struct platform_device *pdev)
3025{
3026 int rings = MAX_U132_RINGS;
3027 int ports = MAX_U132_PORTS;
3028 int addrs = MAX_U132_ADDRS;
3029 int udevs = MAX_U132_UDEVS;
3030 int endps = MAX_U132_ENDPS;
3031 u132->board = pdev->dev.platform_data;
3032 u132->platform_dev = pdev;
3033 u132->power = 0;
3034 u132->reset = 0;
3035 init_MUTEX(&u132->sw_lock);
3036 init_MUTEX(&u132->scheduler_lock);
3037 while (rings-- > 0) {
3038 struct u132_ring *ring = &u132->ring[rings];
3039 ring->u132 = u132;
3040 ring->number = rings + 1;
3041 ring->length = 0;
3042 ring->curr_endp = NULL;
David Howellsc4028952006-11-22 14:57:56 +00003043 INIT_DELAYED_WORK(&ring->scheduler,
3044 u132_hcd_ring_work_scheduler);
Tony Olechd774efe2006-09-13 11:27:35 +01003045 } down(&u132->sw_lock);
David Howellsc4028952006-11-22 14:57:56 +00003046 INIT_DELAYED_WORK(&u132->monitor, u132_hcd_monitor_work);
Tony Olechd774efe2006-09-13 11:27:35 +01003047 while (ports-- > 0) {
3048 struct u132_port *port = &u132->port[ports];
3049 port->u132 = u132;
3050 port->reset = 0;
3051 port->enable = 0;
3052 port->power = 0;
3053 port->Status = 0;
3054 } while (addrs-- > 0) {
3055 struct u132_addr *addr = &u132->addr[addrs];
3056 addr->address = 0;
3057 } while (udevs-- > 0) {
3058 struct u132_udev *udev = &u132->udev[udevs];
3059 int i = ARRAY_SIZE(udev->endp_number_in);
3060 int o = ARRAY_SIZE(udev->endp_number_out);
3061 udev->usb_device = NULL;
3062 udev->udev_number = 0;
3063 udev->usb_addr = 0;
3064 udev->portnumber = 0;
3065 while (i-- > 0) {
3066 udev->endp_number_in[i] = 0;
3067 }
3068 while (o-- > 0) {
3069 udev->endp_number_out[o] = 0;
3070 }
3071 }
3072 while (endps-- > 0) {
3073 u132->endp[endps] = NULL;
3074 }
3075 up(&u132->sw_lock);
3076 return;
3077}
3078
3079static int __devinit u132_probe(struct platform_device *pdev)
3080{
3081 struct usb_hcd *hcd;
Tony Olech4b873612006-12-06 13:16:22 +00003082 int retval;
3083 u32 control;
3084 u32 rh_a = -1;
3085 u32 num_ports;
Tony Olechd774efe2006-09-13 11:27:35 +01003086 msleep(100);
3087 if (u132_exiting > 0) {
3088 return -ENODEV;
Tony Olech4b873612006-12-06 13:16:22 +00003089 }
3090 retval = ftdi_write_pcimem(pdev, intrdisable, OHCI_INTR_MIE);
3091 if (retval)
3092 return retval;
3093 retval = ftdi_read_pcimem(pdev, control, &control);
3094 if (retval)
3095 return retval;
3096 retval = ftdi_read_pcimem(pdev, roothub.a, &rh_a);
3097 if (retval)
3098 return retval;
3099 num_ports = rh_a & RH_A_NDP; /* refuse to confuse usbcore */
Tony Olechd774efe2006-09-13 11:27:35 +01003100 if (pdev->dev.dma_mask) {
3101 return -EINVAL;
3102 }
3103 hcd = usb_create_hcd(&u132_hc_driver, &pdev->dev, pdev->dev.bus_id);
3104 if (!hcd) {
3105 printk(KERN_ERR "failed to create the usb hcd struct for U132\n"
3106 );
3107 ftdi_elan_gone_away(pdev);
3108 return -ENOMEM;
3109 } else {
3110 int retval = 0;
3111 struct u132 *u132 = hcd_to_u132(hcd);
3112 hcd->rsrc_start = 0;
3113 down(&u132_module_lock);
3114 list_add_tail(&u132->u132_list, &u132_static_list);
3115 u132->sequence_num = ++u132_instances;
3116 up(&u132_module_lock);
3117 u132_u132_init_kref(u132);
3118 u132_initialise(u132, pdev);
3119 hcd->product_desc = "ELAN U132 Host Controller";
3120 retval = usb_add_hcd(hcd, 0, 0);
3121 if (retval != 0) {
3122 dev_err(&u132->platform_dev->dev, "init error %d\n",
3123 retval);
3124 u132_u132_put_kref(u132);
3125 return retval;
3126 } else {
3127 u132_monitor_queue_work(u132, 100);
3128 return 0;
3129 }
3130 }
3131}
3132
3133
3134#ifdef CONFIG_PM
3135/* for this device there's no useful distinction between the controller
3136* and its root hub, except that the root hub only gets direct PM calls
3137* when CONFIG_USB_SUSPEND is enabled.
3138*/
3139static int u132_suspend(struct platform_device *pdev, pm_message_t state)
3140{
3141 struct usb_hcd *hcd = platform_get_drvdata(pdev);
3142 struct u132 *u132 = hcd_to_u132(hcd);
3143 if (u132->going > 1) {
3144 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
3145 , u132->going);
3146 return -ENODEV;
3147 } else if (u132->going > 0) {
3148 dev_err(&u132->platform_dev->dev, "device is being removed\n");
3149 return -ESHUTDOWN;
3150 } else {
3151 int retval = 0;
3152 if (state.event == PM_EVENT_FREEZE) {
3153 retval = u132_bus_suspend(hcd);
3154 } else if (state.event == PM_EVENT_SUSPEND) {
3155 int ports = MAX_U132_PORTS;
3156 while (ports-- > 0) {
3157 port_power(u132, ports, 0);
3158 }
3159 }
3160 if (retval == 0)
3161 pdev->dev.power.power_state = state;
3162 return retval;
3163 }
3164}
3165
3166static int u132_resume(struct platform_device *pdev)
3167{
3168 struct usb_hcd *hcd = platform_get_drvdata(pdev);
3169 struct u132 *u132 = hcd_to_u132(hcd);
3170 if (u132->going > 1) {
3171 dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
3172 , u132->going);
3173 return -ENODEV;
3174 } else if (u132->going > 0) {
3175 dev_err(&u132->platform_dev->dev, "device is being removed\n");
3176 return -ESHUTDOWN;
3177 } else {
3178 int retval = 0;
3179 if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
3180 int ports = MAX_U132_PORTS;
3181 while (ports-- > 0) {
3182 port_power(u132, ports, 1);
3183 }
3184 retval = 0;
3185 } else {
3186 pdev->dev.power.power_state = PMSG_ON;
3187 retval = u132_bus_resume(hcd);
3188 }
3189 return retval;
3190 }
3191}
3192
3193#else
3194#define u132_suspend NULL
3195#define u132_resume NULL
3196#endif
3197/*
Matt LaPlante0779bf22006-11-30 05:24:39 +01003198* this driver is loaded explicitly by ftdi_u132
Tony Olechd774efe2006-09-13 11:27:35 +01003199*
3200* the platform_driver struct is static because it is per type of module
3201*/
3202static struct platform_driver u132_platform_driver = {
3203 .probe = u132_probe,
3204 .remove = __devexit_p(u132_remove),
3205 .suspend = u132_suspend,
3206 .resume = u132_resume,
3207 .driver = {
3208 .name = (char *)hcd_name,
3209 .owner = THIS_MODULE,
3210 },
3211};
3212static int __init u132_hcd_init(void)
3213{
3214 int retval;
3215 INIT_LIST_HEAD(&u132_static_list);
3216 u132_instances = 0;
3217 u132_exiting = 0;
3218 init_MUTEX(&u132_module_lock);
3219 if (usb_disabled())
3220 return -ENODEV;
3221 printk(KERN_INFO "driver %s built at %s on %s\n", hcd_name, __TIME__,
3222 __DATE__);
3223 workqueue = create_singlethread_workqueue("u132");
3224 retval = platform_driver_register(&u132_platform_driver);
3225 return retval;
3226}
3227
3228
3229module_init(u132_hcd_init);
3230static void __exit u132_hcd_exit(void)
3231{
3232 struct u132 *u132;
3233 struct u132 *temp;
3234 down(&u132_module_lock);
3235 u132_exiting += 1;
3236 up(&u132_module_lock);
3237 list_for_each_entry_safe(u132, temp, &u132_static_list, u132_list) {
3238 platform_device_unregister(u132->platform_dev);
3239 } platform_driver_unregister(&u132_platform_driver);
3240 printk(KERN_INFO "u132-hcd driver deregistered\n");
3241 wait_event(u132_hcd_wait, u132_instances == 0);
3242 flush_workqueue(workqueue);
3243 destroy_workqueue(workqueue);
3244}
3245
3246
3247module_exit(u132_hcd_exit);
3248MODULE_LICENSE("GPL");