Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / SLOF / lib / libusb / usb-ehci.c
1 /*****************************************************************************
2  * Copyright (c) 2013 IBM Corporation
3  * All rights reserved.
4  * This program and the accompanying materials
5  * are made available under the terms of the BSD License
6  * which accompanies this distribution, and is available at
7  * http://www.opensource.org/licenses/bsd-license.php
8  *
9  * Contributors:
10  *     IBM Corporation - initial implementation
11  *****************************************************************************/
12
13 #include <string.h>
14 #include "usb.h"
15 #include "usb-core.h"
16 #include "usb-ehci.h"
17 #include "tools.h"
18 #include "paflof.h"
19
20 #undef EHCI_DEBUG
21 //#define EHCI_DEBUG
22 #ifdef EHCI_DEBUG
23 #define dprintf(_x ...) do { printf(_x); } while(0)
24 #else
25 #define dprintf(_x ...)
26 #endif
27
28 #ifdef EHCI_DEBUG
29 static void dump_ehci_regs(struct ehci_hcd *ehcd)
30 {
31         struct ehci_cap_regs *cap_regs;
32         struct ehci_op_regs *op_regs;
33
34         cap_regs = ehcd->cap_regs;
35         op_regs = ehcd->op_regs;
36
37         dprintf("\n - CAPLENGTH           %02X", read_reg8(&cap_regs->caplength));
38         dprintf("\n - HCIVERSION          %04X", read_reg16(&cap_regs->hciversion));
39         dprintf("\n - HCSPARAMS           %08X", read_reg32(&cap_regs->hcsparams));
40         dprintf("\n - HCCPARAMS           %08X", read_reg32(&cap_regs->hccparams));
41         dprintf("\n - HCSP_PORTROUTE      %016llX", read_reg64(&cap_regs->portroute));
42         dprintf("\n");
43
44         dprintf("\n - USBCMD              %08X", read_reg32(&op_regs->usbcmd));
45         dprintf("\n - USBSTS              %08X", read_reg32(&op_regs->usbsts));
46         dprintf("\n - USBINTR             %08X", read_reg32(&op_regs->usbintr));
47         dprintf("\n - FRINDEX             %08X", read_reg32(&op_regs->frindex));
48         dprintf("\n - CTRLDSSEGMENT       %08X", read_reg32(&op_regs->ctrldssegment));
49         dprintf("\n - PERIODICLISTBASE    %08X", read_reg32(&op_regs->periodiclistbase));
50         dprintf("\n - ASYNCLISTADDR       %08X", read_reg32(&op_regs->asynclistaddr));
51         dprintf("\n - CONFIGFLAG          %08X", read_reg32(&op_regs->configflag));
52         dprintf("\n - PORTSC              %08X", read_reg32(&op_regs->portsc[0]));
53         dprintf("\n");
54 }
55 #endif
56
57 static int ehci_hub_check_ports(struct ehci_hcd *ehcd)
58 {
59         uint32_t num_ports, portsc, i;
60         struct usb_dev *dev;
61
62         dprintf("%s: enter\n", __func__);
63         num_ports = read_reg32(&ehcd->cap_regs->hcsparams) & HCS_NPORTS_MASK;
64         for (i = 0; i < num_ports; i++) {
65                 dprintf("%s: device %d\n", __func__, i);
66                 portsc = read_reg32(&ehcd->op_regs->portsc[i]);
67                 if (portsc & PORT_CONNECT) { /* Device present */
68                         dprintf("usb-ehci: Device present on port %d\n", i);
69                         /* Reset the port */
70                         portsc = read_reg32(&ehcd->op_regs->portsc[i]);
71                         portsc = (portsc & ~PORT_PE) | PORT_RESET;
72                         write_reg32(&ehcd->op_regs->portsc[i], portsc);
73                         SLOF_msleep(20);
74                         portsc = read_reg32(&ehcd->op_regs->portsc[i]);
75                         portsc &= ~PORT_RESET;
76                         write_reg32(&ehcd->op_regs->portsc[i], portsc);
77                         SLOF_msleep(20);
78                         dev = usb_devpool_get();
79                         dprintf("usb-ehci: allocated device %p\n", dev);
80                         dev->hcidev = ehcd->hcidev;
81                         dev->speed = USB_HIGH_SPEED; /* TODO: Check for Low/Full speed device */
82                         if (!setup_new_device(dev, i))
83                                 printf("usb-ehci: unable to setup device on port %d\n", i);
84                 }
85         }
86         dprintf("%s: exit\n", __func__);
87         return 0;
88 }
89
90 static int ehci_hcd_init(struct ehci_hcd *ehcd)
91 {
92         uint32_t usbcmd;
93         uint32_t time;
94         struct ehci_framelist *fl;
95         struct ehci_qh *qh_intr, *qh_async;
96         int i;
97         long fl_phys = 0, qh_intr_phys = 0, qh_async_phys;
98
99         /* Reset the host controller */
100         time = SLOF_GetTimer() + 250;
101         usbcmd = read_reg32(&ehcd->op_regs->usbcmd);
102         write_reg32(&ehcd->op_regs->usbcmd, (usbcmd & ~(CMD_PSE | CMD_ASE)) | CMD_HCRESET);
103         while (time > SLOF_GetTimer())
104                 cpu_relax();
105         usbcmd = read_reg32(&ehcd->op_regs->usbcmd);
106         if (usbcmd & CMD_HCRESET) {
107                 printf("usb-ehci: reset failed\n");
108                 return -1;
109         }
110
111         /* Initialize periodic list */
112         fl = SLOF_dma_alloc(sizeof(*fl));
113         if (!fl) {
114                 printf("usb-ehci: Unable to allocate frame list\n");
115                 goto fail;
116         }
117         fl_phys = SLOF_dma_map_in(fl, sizeof(*fl), true);
118         dprintf("fl %p, fl_phys %lx\n", fl, fl_phys);
119
120         /* TODO: allocate qh pool */
121         qh_intr = SLOF_dma_alloc(sizeof(*qh_intr));
122         if (!qh_intr) {
123                 printf("usb-ehci: Unable to allocate interrupt queue head\n");
124                 goto fail_qh_intr;
125         }
126         qh_intr_phys = SLOF_dma_map_in(qh_intr, sizeof(*qh_intr), true);
127         dprintf("qh_intr %p, qh_intr_phys %lx\n", qh_intr, qh_intr_phys);
128
129         memset(qh_intr, 0, sizeof(*qh_intr));
130         qh_intr->qh_ptr = QH_PTR_TERM;
131         qh_intr->ep_cap2 = cpu_to_le32(0x01 << QH_SMASK_SHIFT);
132         qh_intr->next_qtd = qh_intr->alt_next_qtd = QH_PTR_TERM;
133         qh_intr->token = cpu_to_le32(QH_STS_HALTED);
134         for (i = 0; i < FL_SIZE; i++)
135                 fl->fl_ptr[i] = cpu_to_le32(qh_intr_phys | EHCI_TYP_QH);
136         write_reg32(&ehcd->op_regs->periodiclistbase, fl_phys);
137
138         /* Initialize async list */
139         qh_async = SLOF_dma_alloc(sizeof(*qh_async));
140         if (!qh_async) {
141                 printf("usb-ehci: Unable to allocate async queue head\n");
142                 goto fail_qh_async;
143         }
144         qh_async_phys = SLOF_dma_map_in(qh_async, sizeof(*qh_async), true);
145         dprintf("qh_async %p, qh_async_phys %lx\n", qh_async, qh_async_phys);
146
147         memset(qh_async, 0, sizeof(*qh_async));
148         qh_async->qh_ptr = cpu_to_le32(qh_async_phys | EHCI_TYP_QH);
149         qh_async->ep_cap1 = cpu_to_le32(QH_CAP_H);
150         qh_async->next_qtd = qh_async->alt_next_qtd = QH_PTR_TERM;
151         qh_async->token = cpu_to_le32(QH_STS_HALTED);
152         write_reg32(&ehcd->op_regs->asynclistaddr, qh_async_phys);
153         ehcd->qh_async = qh_async;
154         ehcd->qh_async_phys = qh_async_phys;
155         ehcd->qh_intr = qh_intr;
156         ehcd->qh_intr_phys = qh_intr_phys;
157         ehcd->fl = fl;
158         ehcd->fl_phys = fl_phys;
159
160         write_reg32(&ehcd->op_regs->usbcmd, usbcmd | CMD_ASE | CMD_RUN);
161         write_reg32(&ehcd->op_regs->configflag, 1);
162
163         return 0;
164
165 fail_qh_async:
166         SLOF_dma_map_out(qh_intr_phys, qh_intr, sizeof(*qh_intr));
167         SLOF_dma_free(qh_intr, sizeof(*qh_intr));
168 fail_qh_intr:
169         SLOF_dma_map_out(fl_phys, fl, sizeof(*fl));
170         SLOF_dma_free(fl, sizeof(*fl));
171 fail:
172         return -1;
173 }
174
175 static int ehci_hcd_exit(struct ehci_hcd *ehcd)
176 {
177         uint32_t usbcmd;
178
179         if (!ehcd) {
180                 dprintf("NULL pointer\n");
181                 return false;
182         }
183
184         usbcmd = read_reg32(&ehcd->op_regs->usbcmd);
185         write_reg32(&ehcd->op_regs->usbcmd, usbcmd | ~CMD_RUN);
186         write_reg32(&ehcd->op_regs->periodiclistbase, 0);
187
188         if (ehcd->pool) {
189                 SLOF_dma_map_out(ehcd->pool_phys, ehcd->pool, EHCI_PIPE_POOL_SIZE);
190                 SLOF_dma_free(ehcd->pool, EHCI_PIPE_POOL_SIZE);
191         }
192         if (ehcd->qh_intr) {
193                 SLOF_dma_map_out(ehcd->qh_intr_phys, ehcd->qh_intr, sizeof(struct ehci_qh));
194                 SLOF_dma_free(ehcd->qh_intr, sizeof(struct ehci_qh));
195         }
196         if (ehcd->qh_async) {
197                 SLOF_dma_map_out(ehcd->qh_async_phys, ehcd->qh_async, sizeof(struct ehci_qh));
198                 SLOF_dma_free(ehcd->qh_async, sizeof(struct ehci_qh));
199         }
200         if (ehcd->fl) {
201                 SLOF_dma_map_out(ehcd->fl_phys, ehcd->fl, sizeof(struct ehci_framelist));
202                 SLOF_dma_free(ehcd->fl, sizeof(struct ehci_framelist));
203         }
204         return true;
205 }
206
207 static int ehci_alloc_pipe_pool(struct ehci_hcd *ehcd)
208 {
209         struct ehci_pipe *epipe, *curr, *prev;
210         unsigned int i, count;
211         long epipe_phys = 0;
212
213         count = EHCI_PIPE_POOL_SIZE/sizeof(*epipe);
214         ehcd->pool = epipe = SLOF_dma_alloc(EHCI_PIPE_POOL_SIZE);
215         if (!epipe)
216                 return -1;
217         ehcd->pool_phys = epipe_phys = SLOF_dma_map_in(epipe, EHCI_PIPE_POOL_SIZE, true);
218         dprintf("%s: epipe %p, epipe_phys %lx\n", __func__, epipe, epipe_phys);
219
220         /* Although an array, link them */
221         for (i = 0, curr = epipe, prev = NULL; i < count; i++, curr++) {
222                 if (prev)
223                         prev->pipe.next = &curr->pipe;
224                 curr->pipe.next = NULL;
225                 prev = curr;
226                 curr->qh_phys = epipe_phys + (curr - epipe) * sizeof(*curr) +
227                         offset_of(struct ehci_pipe, qh);
228                 dprintf("%s - %d: qh %p, qh_phys %lx\n", __func__,
229                         i, &curr->qh, curr->qh_phys);
230         }
231
232         if (!ehcd->freelist)
233                 ehcd->freelist = &epipe->pipe;
234         else
235                 ehcd->end->next = &epipe->pipe;
236         ehcd->end = &prev->pipe;
237
238         return 0;
239 }
240
241 static void ehci_init(struct usb_hcd_dev *hcidev)
242 {
243         struct ehci_hcd *ehcd;
244
245         printf("  EHCI: Initializing\n");
246         dprintf("%s: device base address %p\n", __func__, hcidev->base);
247
248         ehcd = SLOF_alloc_mem(sizeof(*ehcd));
249         if (!ehcd) {
250                 printf("usb-ehci: Unable to allocate memory\n");
251                 return;
252         }
253         memset(ehcd, 0, sizeof(*ehcd));
254
255         hcidev->nextaddr = 1;
256         hcidev->priv = ehcd;
257         ehcd->hcidev = hcidev;
258         ehcd->cap_regs = (struct ehci_cap_regs *)(hcidev->base);
259         ehcd->op_regs = (struct ehci_op_regs *)(hcidev->base +
260                                                 read_reg8(&ehcd->cap_regs->caplength));
261 #ifdef EHCI_DEBUG
262         dump_ehci_regs(ehcd);
263 #endif
264         ehci_hcd_init(ehcd);
265         ehci_hub_check_ports(ehcd);
266 }
267
268 static void ehci_exit(struct usb_hcd_dev *hcidev)
269 {
270         struct ehci_hcd *ehcd;
271         static int count = 0;
272
273         dprintf("%s: enter \n", __func__);
274
275         if (!hcidev && !hcidev->priv) {
276                 return;
277         }
278         count++;
279         if (count > 1) {
280                 printf("%s: already called once \n", __func__);
281                 return;
282         }
283         ehcd = hcidev->priv;
284         ehci_hcd_exit(ehcd);
285         SLOF_free_mem(ehcd, sizeof(*ehcd));
286         hcidev->priv = NULL;
287 }
288
289 static void ehci_detect(void)
290 {
291
292 }
293
294 static void ehci_disconnect(void)
295 {
296
297 }
298
299 static int ehci_handshake(struct ehci_hcd *ehcd, uint32_t timeout)
300 {
301         uint32_t usbsts = 0, time;
302         uint32_t usbcmd;
303         mb();
304         usbcmd = read_reg32(&ehcd->op_regs->usbcmd);
305         /* Ring a doorbell */
306         write_reg32(&ehcd->op_regs->usbcmd, usbcmd | CMD_IAAD);
307         mb();
308         time = SLOF_GetTimer() + timeout;
309         while ((time > SLOF_GetTimer())) {
310                 /* Wait for controller to confirm */
311                 usbsts = read_reg32(&ehcd->op_regs->usbsts);
312                 if (usbsts & STS_IAA) {
313                         /* Acknowledge it, for next doorbell to work */
314                         write_reg32(&ehcd->op_regs->usbsts, STS_IAA);
315                         return true;
316                 }
317                 cpu_relax();
318         }
319         return false;
320 }
321
322 static int fill_qtd_buff(struct ehci_qtd *qtd, long data, uint32_t size)
323 {
324         long i, rem;
325         long pos = (data + 0x1000) & ~0xfff;
326
327         qtd->buffer[0] = cpu_to_le32(PTR_U32(data));
328         for (i = 1; i < 5; i++) {
329                 if ((data + size - 1) >= pos) {
330                         //dprintf("data spans page boundary: %d, %p\n", i, pos);
331                         qtd->buffer[i] = cpu_to_le32(pos);
332                         pos += 0x1000;
333                 } else
334                         break;
335         }
336         if ((data + size) > pos)
337                 rem = data + size - pos;
338         else
339                 rem = 0;
340         return rem;
341 }
342
343 static int ehci_send_ctrl(struct usb_pipe *pipe, struct usb_dev_req *req, void *data)
344 {
345         struct ehci_hcd *ehcd;
346         struct ehci_qtd *qtd, *qtds, *qtds_phys;
347         struct ehci_pipe *epipe;
348         uint32_t transfer_size = sizeof(*req);
349         uint32_t datalen, pid;
350         uint32_t time;
351         long req_phys = 0, data_phys = 0;
352         int ret = true;
353
354         if (pipe->type != USB_EP_TYPE_CONTROL) {
355                 printf("usb-ehci: Not a control pipe.\n");
356                 return false;
357         }
358
359         ehcd = pipe->dev->hcidev->priv;
360         qtds = qtd = SLOF_dma_alloc(sizeof(*qtds) * 3);
361         if (!qtds) {
362                 printf("Error allocating qTDs.\n");
363                 return false;
364         }
365         qtds_phys = (struct ehci_qtd *)SLOF_dma_map_in(qtds, sizeof(*qtds) * 3, true);
366         memset(qtds, 0, sizeof(*qtds) * 3);
367         req_phys = SLOF_dma_map_in(req, sizeof(struct usb_dev_req), true);
368         qtd->next_qtd = cpu_to_le32(PTR_U32(&qtds_phys[1]));
369         qtd->alt_next_qtd = QH_PTR_TERM;
370         qtd->token = cpu_to_le32((transfer_size << TOKEN_TBTT_SHIFT) |
371                         (3 << TOKEN_CERR_SHIFT) |
372                         (PID_SETUP << TOKEN_PID_SHIFT) |
373                         (QH_STS_ACTIVE << TOKEN_STATUS_SHIFT));
374         fill_qtd_buff(qtd, req_phys, sizeof(*req));
375
376         qtd++;
377         datalen = cpu_to_le16(req->wLength);
378         pid = (req->bmRequestType & REQT_DIR_IN) ? PID_IN : PID_OUT;
379         if (datalen) {
380                 data_phys = SLOF_dma_map_in(data, datalen, true);
381                 qtd->next_qtd = cpu_to_le32(PTR_U32(&qtds_phys[2]));
382                 qtd->alt_next_qtd = QH_PTR_TERM;
383                 qtd->token = cpu_to_le32((1 << TOKEN_DT_SHIFT) |
384                                 (datalen << TOKEN_TBTT_SHIFT) |
385                                 (3 << TOKEN_CERR_SHIFT) |
386                                 (pid << TOKEN_PID_SHIFT) |
387                                 (QH_STS_ACTIVE << TOKEN_STATUS_SHIFT));
388                 fill_qtd_buff(qtd, data_phys, datalen);
389                 qtd++;
390         }
391
392         if (pid == PID_IN)
393                 pid = PID_OUT;
394         else
395                 pid = PID_IN;
396         qtd->next_qtd = QH_PTR_TERM;
397         qtd->alt_next_qtd = QH_PTR_TERM;
398         qtd->token = cpu_to_le32((1 << TOKEN_DT_SHIFT) |
399                         (3 << TOKEN_CERR_SHIFT) |
400                         (pid << TOKEN_PID_SHIFT) |
401                         (QH_STS_ACTIVE << TOKEN_STATUS_SHIFT));
402
403         /* link qtd to qh and attach to ehcd */
404         mb();
405         epipe = container_of(pipe, struct ehci_pipe, pipe);
406         epipe->qh.next_qtd = cpu_to_le32(PTR_U32(qtds_phys));
407         epipe->qh.qh_ptr = cpu_to_le32(ehcd->qh_async_phys | EHCI_TYP_QH);
408         epipe->qh.ep_cap1 = cpu_to_le32((pipe->mps << QH_MPS_SHIFT) |
409                                 (pipe->speed << QH_EPS_SHIFT) |
410                                 (pipe->epno << QH_EP_SHIFT) |
411                                 (pipe->dev->addr << QH_DEV_ADDR_SHIFT));
412         mb();
413
414         ehcd->qh_async->qh_ptr = cpu_to_le32(epipe->qh_phys | EHCI_TYP_QH);
415
416         /* transfer data */
417         mb();
418         qtd = &qtds[0];
419         time = SLOF_GetTimer() + USB_TIMEOUT;
420         do {
421                 if (le32_to_cpu(qtd->token) & (QH_STS_ACTIVE << TOKEN_STATUS_SHIFT))
422                         mb();
423                 else
424                         qtd++;
425
426                 if (time < SLOF_GetTimer()) { /* timed out */
427                         printf("usb-ehci: control transfer timed out_\n");
428                         ret = false;
429                         break;
430                 }
431         } while (qtd->next_qtd != QH_PTR_TERM);
432
433         ehcd->qh_async->qh_ptr = cpu_to_le32(ehcd->qh_async_phys | EHCI_TYP_QH);
434         mb();
435         if (!ehci_handshake(ehcd, USB_TIMEOUT)) {
436                 printf("%s: handshake failed\n", __func__);
437                 ret = false;
438         }
439
440         SLOF_dma_map_out(req_phys, req, sizeof(struct usb_dev_req));
441         SLOF_dma_map_out(data_phys, data, datalen);
442         SLOF_dma_map_out(PTR_U32(qtds_phys), qtds, sizeof(*qtds) * 3);
443         SLOF_dma_free(qtds, sizeof(*qtds) * 3);
444
445         return ret;
446 }
447
448 static int ehci_transfer_bulk(struct usb_pipe *pipe, void *td, void *td_phys,
449                         void *data_phys, int size)
450 {
451         struct ehci_hcd *ehcd;
452         struct ehci_qtd *qtd, *qtd_phys;
453         struct ehci_pipe *epipe;
454         uint32_t pid;
455         int i, rem, ret = true;
456         uint32_t time;
457         long ptr;
458
459         dprintf("usb-ehci: bulk transfer: data %p, size %d, td %p, td_phys %p\n",
460                 data_phys, size, td, td_phys);
461
462         if (pipe->type != USB_EP_TYPE_BULK) {
463                 printf("usb-ehci: Not a bulk pipe.\n");
464                 return false;
465         }
466
467         if (size > QTD_MAX_TRANSFER_LEN) {
468                 printf("usb-ehci: bulk transfer size too big\n");
469                 return false;
470         }
471
472         ehcd = pipe->dev->hcidev->priv;
473         pid = (pipe->dir == USB_PIPE_OUT) ? PID_OUT : PID_IN;
474         qtd = (struct ehci_qtd *)td;
475         qtd_phys = (struct ehci_qtd *)td_phys;
476         ptr = (long)data_phys;
477         for (i = 0; i < NUM_BULK_QTDS; i++) {
478                 memset(qtd, 0, sizeof(*qtd));
479                 rem = fill_qtd_buff(qtd, ptr, size);
480                 qtd->token = cpu_to_le32((1 << TOKEN_DT_SHIFT) |
481                                 ((size - rem) << TOKEN_TBTT_SHIFT) |
482                                 (3 << TOKEN_CERR_SHIFT) |
483                                 (pid << TOKEN_PID_SHIFT) |
484                                 (QH_STS_ACTIVE << TOKEN_STATUS_SHIFT));
485                 if (rem) {
486                         qtd->next_qtd = cpu_to_le32(PTR_U32(&qtd_phys[i+1]));
487                         qtd->alt_next_qtd = QH_PTR_TERM;
488                         ptr += size - rem;
489                         size = rem;
490                         qtd++;
491                 } else {
492                         qtd->next_qtd = qtd->alt_next_qtd = QH_PTR_TERM;
493                         break; /* no more data */
494                 }
495         }
496
497         /* link qtd to qh and attach to ehcd */
498         mb();
499         epipe = container_of(pipe, struct ehci_pipe, pipe);
500         epipe->qh.next_qtd = cpu_to_le32(PTR_U32(qtd_phys));
501         epipe->qh.qh_ptr = cpu_to_le32(ehcd->qh_async_phys | EHCI_TYP_QH);
502         epipe->qh.ep_cap1 = cpu_to_le32((pipe->mps << QH_MPS_SHIFT) |
503                                 (pipe->speed << QH_EPS_SHIFT) |
504                                 (pipe->epno << QH_EP_SHIFT) |
505                                 (pipe->dev->addr << QH_DEV_ADDR_SHIFT));
506         mb();
507
508         ehcd->qh_async->qh_ptr = cpu_to_le32(epipe->qh_phys | EHCI_TYP_QH);
509
510         /* transfer data */
511         mb();
512         qtd = (struct ehci_qtd *)td;
513         for (i = 0; i < NUM_BULK_QTDS; i++) {
514                 time = SLOF_GetTimer() + USB_TIMEOUT;
515                 while ((time > SLOF_GetTimer()) &&
516                         (le32_to_cpu(qtd->token) & (QH_STS_ACTIVE << TOKEN_STATUS_SHIFT)))
517                         cpu_relax();
518                 mb();
519                 if (qtd->next_qtd == QH_PTR_TERM)
520                         break;
521
522                 if (le32_to_cpu(qtd->token) & (QH_STS_ACTIVE << TOKEN_STATUS_SHIFT)) {
523                         printf("usb-ehci: bulk transfer timed out_\n");
524                         ret = false;
525                         break;
526                 }
527                 qtd++;
528         }
529
530         ehcd->qh_async->qh_ptr = cpu_to_le32(ehcd->qh_async_phys | EHCI_TYP_QH);
531         mb();
532         if (!ehci_handshake(ehcd, USB_TIMEOUT)) {
533                 printf("%s: handshake failed\n", __func__);
534                 ret = false;
535         }
536         return ret;
537 }
538
539 static struct usb_pipe *ehci_get_pipe(struct usb_dev *dev, struct usb_ep_descr *ep,
540                                 char *buf, size_t len)
541 {
542         struct ehci_hcd *ehcd;
543         struct usb_pipe *new = NULL;
544
545         if (!dev)
546                 return NULL;
547
548         ehcd = (struct ehci_hcd *)dev->hcidev->priv;
549         if (!ehcd->freelist) {
550                 dprintf("usb-ehci: %s allocating pool\n", __func__);
551                 if (ehci_alloc_pipe_pool(ehcd))
552                         return NULL;
553         }
554
555         new = ehcd->freelist;
556         ehcd->freelist = ehcd->freelist->next;
557         if (!ehcd->freelist)
558                 ehcd->end = NULL;
559
560         memset(new, 0, sizeof(*new));
561         new->dev = dev;
562         new->next = NULL;
563         new->type = ep->bmAttributes & USB_EP_TYPE_MASK;
564         new->speed = dev->speed;
565         new->mps = ep->wMaxPacketSize;
566         new->dir = (ep->bEndpointAddress & 0x80) >> 7;
567         new->epno = ep->bEndpointAddress & 0x0f;
568
569         return new;
570 }
571
572 static void ehci_put_pipe(struct usb_pipe *pipe)
573 {
574         struct ehci_hcd *ehcd;
575
576         dprintf("usb-ehci: %s enter - %p\n", __func__, pipe);
577         if (!pipe || !pipe->dev)
578                 return;
579         ehcd = pipe->dev->hcidev->priv;
580         if (ehcd->end)
581                 ehcd->end->next = pipe;
582         else
583                 ehcd->freelist = pipe;
584
585         ehcd->end = pipe;
586         pipe->next = NULL;
587         pipe->dev = NULL;
588         memset(pipe, 0, sizeof(*pipe));
589         dprintf("usb-ehci: %s exit\n", __func__);
590 }
591
592 struct usb_hcd_ops ehci_ops = {
593         .name          = "ehci-hcd",
594         .init          = ehci_init,
595         .exit          = ehci_exit,
596         .detect        = ehci_detect,
597         .disconnect    = ehci_disconnect,
598         .get_pipe      = ehci_get_pipe,
599         .put_pipe      = ehci_put_pipe,
600         .send_ctrl     = ehci_send_ctrl,
601         .transfer_bulk = ehci_transfer_bulk,
602         .usb_type      = USB_EHCI,
603         .next          = NULL,
604 };
605
606 void usb_ehci_register(void)
607 {
608         usb_hcd_register(&ehci_ops);
609 }