7b7061f5335425252cb3f3bafe733e2cb35ab46b
[grub.git] / grub-core / bus / usb / ehci.c
1 /* ehci.c - EHCI Support.  */
2 /*
3  *  GRUB  --  GRand Unified Bootloader
4  *  Copyright (C) 2011  Free Software Foundation, Inc.
5  *
6  *  GRUB is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  GRUB is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <grub/dl.h>
21 #include <grub/mm.h>
22 #include <grub/usb.h>
23 #include <grub/usbtrans.h>
24 #include <grub/misc.h>
25 #include <grub/time.h>
26 #include <grub/loader.h>
27 #include <grub/disk.h>
28 #include <grub/dma.h>
29 #include <grub/cache.h>
30
31 GRUB_MOD_LICENSE ("GPLv3+");
32
33 /* This simple GRUB implementation of EHCI driver:
34  *      - assumes no IRQ
35  *      - is not supporting isochronous transfers (iTD, siTD)
36  *      - is not supporting interrupt transfers
37  */
38
39 /* Capability registers offsets */
40 enum
41 {
42   GRUB_EHCI_EHCC_CAPLEN = 0x00, /* byte */
43   GRUB_EHCI_EHCC_VERSION = 0x02,        /* word */
44   GRUB_EHCI_EHCC_SPARAMS = 0x04,        /* dword */
45   GRUB_EHCI_EHCC_CPARAMS = 0x08,        /* dword */
46   GRUB_EHCI_EHCC_PROUTE = 0x0c, /* 60 bits */
47 };
48
49 #define GRUB_EHCI_EECP_MASK     (0xff << 8)
50 #define GRUB_EHCI_EECP_SHIFT    8
51
52 #define GRUB_EHCI_POINTER_MASK  (~0x1f)
53
54 /* Capability register SPARAMS bits */
55 enum
56 {
57   GRUB_EHCI_SPARAMS_N_PORTS = (0xf << 0),
58   GRUB_EHCI_SPARAMS_PPC = (1 << 4),     /* Power port control */
59   GRUB_EHCI_SPARAMS_PRR = (1 << 7),     /* Port routing rules */
60   GRUB_EHCI_SPARAMS_N_PCC = (0xf << 8), /* No of ports per comp. */
61   GRUB_EHCI_SPARAMS_NCC = (0xf << 12),  /* No of com. controllers */
62   GRUB_EHCI_SPARAMS_P_IND = (1 << 16),  /* Port indicators present */
63   GRUB_EHCI_SPARAMS_DEBUG_P = (0xf << 20)       /* Debug port */
64 };
65
66 #define GRUB_EHCI_MAX_N_PORTS     15    /* Max. number of ports */
67
68 /* Capability register CPARAMS bits */
69 enum
70 {
71   GRUB_EHCI_CPARAMS_64BIT = (1 << 0),
72   GRUB_EHCI_CPARAMS_PROG_FRAMELIST = (1 << 1),
73   GRUB_EHCI_CPARAMS_PARK_CAP = (1 << 2)
74 };
75
76 #define GRUB_EHCI_N_FRAMELIST   1024
77 #define GRUB_EHCI_N_QH  256
78 #define GRUB_EHCI_N_TD  640
79
80 #define GRUB_EHCI_QH_EMPTY 1
81
82 /* Operational registers offsets */
83 enum
84 {
85   GRUB_EHCI_COMMAND = 0x00,
86   GRUB_EHCI_STATUS = 0x04,
87   GRUB_EHCI_INTERRUPT = 0x08,
88   GRUB_EHCI_FRAME_INDEX = 0x0c,
89   GRUB_EHCI_64BIT_SEL = 0x10,
90   GRUB_EHCI_FL_BASE = 0x14,
91   GRUB_EHCI_CUR_AL_ADDR = 0x18,
92   GRUB_EHCI_CONFIG_FLAG = 0x40,
93   GRUB_EHCI_PORT_STAT_CMD = 0x44
94 };
95
96 /* Operational register COMMAND bits */
97 enum
98 {
99   GRUB_EHCI_CMD_RUNSTOP = (1 << 0),
100   GRUB_EHCI_CMD_HC_RESET = (1 << 1),
101   GRUB_EHCI_CMD_FL_SIZE = (3 << 2),
102   GRUB_EHCI_CMD_PS_ENABL = (1 << 4),
103   GRUB_EHCI_CMD_AS_ENABL = (1 << 5),
104   GRUB_EHCI_CMD_AS_ADV_D = (1 << 6),
105   GRUB_EHCI_CMD_L_HC_RES = (1 << 7),
106   GRUB_EHCI_CMD_AS_PARKM = (3 << 8),
107   GRUB_EHCI_CMD_AS_PARKE = (1 << 11),
108   GRUB_EHCI_CMD_INT_THRS = (0xff << 16)
109 };
110
111 /* Operational register STATUS bits */
112 enum
113 {
114   GRUB_EHCI_ST_INTERRUPT = (1 << 0),
115   GRUB_EHCI_ST_ERROR_INT = (1 << 1),
116   GRUB_EHCI_ST_PORT_CHG = (1 << 2),
117   GRUB_EHCI_ST_FL_ROLLOVR = (1 << 3),
118   GRUB_EHCI_ST_HS_ERROR = (1 << 4),
119   GRUB_EHCI_ST_AS_ADVANCE = (1 << 5),
120   GRUB_EHCI_ST_HC_HALTED = (1 << 12),
121   GRUB_EHCI_ST_RECLAM = (1 << 13),
122   GRUB_EHCI_ST_PS_STATUS = (1 << 14),
123   GRUB_EHCI_ST_AS_STATUS = (1 << 15)
124 };
125
126 /* Operational register PORT_STAT_CMD bits */
127 enum
128 {
129   GRUB_EHCI_PORT_CONNECT = (1 << 0),
130   GRUB_EHCI_PORT_CONNECT_CH = (1 << 1),
131   GRUB_EHCI_PORT_ENABLED = (1 << 2),
132   GRUB_EHCI_PORT_ENABLED_CH = (1 << 3),
133   GRUB_EHCI_PORT_OVERCUR = (1 << 4),
134   GRUB_EHCI_PORT_OVERCUR_CH = (1 << 5),
135   GRUB_EHCI_PORT_RESUME = (1 << 6),
136   GRUB_EHCI_PORT_SUSPEND = (1 << 7),
137   GRUB_EHCI_PORT_RESET = (1 << 8),
138   GRUB_EHCI_PORT_LINE_STAT = (3 << 10),
139   GRUB_EHCI_PORT_POWER = (1 << 12),
140   GRUB_EHCI_PORT_OWNER = (1 << 13),
141   GRUB_EHCI_PORT_INDICATOR = (3 << 14),
142   GRUB_EHCI_PORT_TEST = (0xf << 16),
143   GRUB_EHCI_PORT_WON_CONN_E = (1 << 20),
144   GRUB_EHCI_PORT_WON_DISC_E = (1 << 21),
145   GRUB_EHCI_PORT_WON_OVER_E = (1 << 22),
146
147   GRUB_EHCI_PORT_LINE_SE0 = (0 << 10),
148   GRUB_EHCI_PORT_LINE_K = (1 << 10),
149   GRUB_EHCI_PORT_LINE_J = (2 << 10),
150   GRUB_EHCI_PORT_LINE_UNDEF = (3 << 10),
151   GRUB_EHCI_PORT_LINE_LOWSP = GRUB_EHCI_PORT_LINE_K,    /* K state means low speed */
152   GRUB_EHCI_PORT_WMASK = ~(GRUB_EHCI_PORT_CONNECT_CH
153                            | GRUB_EHCI_PORT_ENABLED_CH
154                            | GRUB_EHCI_PORT_OVERCUR_CH)
155 };
156
157 /* Operational register CONFIGFLAGS bits */
158 enum
159 {
160   GRUB_EHCI_CF_EHCI_OWNER = (1 << 0)
161 };
162
163 /* Queue Head & Transfer Descriptor constants */
164 #define GRUB_EHCI_HPTR_OFF       5      /* Horiz. pointer bit offset */
165 enum
166 {
167   GRUB_EHCI_HPTR_TYPE_MASK = (3 << 1),
168   GRUB_EHCI_HPTR_TYPE_ITD = (0 << 1),
169   GRUB_EHCI_HPTR_TYPE_QH = (1 << 1),
170   GRUB_EHCI_HPTR_TYPE_SITD = (2 << 1),
171   GRUB_EHCI_HPTR_TYPE_FSTN = (3 << 1)
172 };
173
174 enum
175 {
176   GRUB_EHCI_C = (1 << 27),
177   GRUB_EHCI_MAXPLEN_MASK = (0x7ff << 16),
178   GRUB_EHCI_H = (1 << 15),
179   GRUB_EHCI_DTC = (1 << 14),
180   GRUB_EHCI_SPEED_MASK = (3 << 12),
181   GRUB_EHCI_SPEED_FULL = (0 << 12),
182   GRUB_EHCI_SPEED_LOW = (1 << 12),
183   GRUB_EHCI_SPEED_HIGH = (2 << 12),
184   GRUB_EHCI_SPEED_RESERVED = (3 << 12),
185   GRUB_EHCI_EP_NUM_MASK = (0xf << 8),
186   GRUB_EHCI_DEVADDR_MASK = 0x7f,
187   GRUB_EHCI_TARGET_MASK = (GRUB_EHCI_EP_NUM_MASK | GRUB_EHCI_DEVADDR_MASK)
188 };
189
190 enum
191 {
192   GRUB_EHCI_MAXPLEN_OFF = 16,
193   GRUB_EHCI_SPEED_OFF = 12,
194   GRUB_EHCI_EP_NUM_OFF = 8
195 };
196
197 enum
198 {
199   GRUB_EHCI_MULT_MASK = (3 << 30),
200   GRUB_EHCI_MULT_RESERVED = (0 << 30),
201   GRUB_EHCI_MULT_ONE = (1 << 30),
202   GRUB_EHCI_MULT_TWO = (2 << 30),
203   GRUB_EHCI_MULT_THREE = (3 << 30),
204   GRUB_EHCI_DEVPORT_MASK = (0x7f << 23),
205   GRUB_EHCI_HUBADDR_MASK = (0x7f << 16),
206   GRUB_EHCI_CMASK_MASK = (0xff << 8),
207   GRUB_EHCI_SMASK_MASK = (0xff << 0),
208 };
209
210 enum
211 {
212   GRUB_EHCI_MULT_OFF = 30,
213   GRUB_EHCI_DEVPORT_OFF = 23,
214   GRUB_EHCI_HUBADDR_OFF = 16,
215   GRUB_EHCI_CMASK_OFF = 8,
216   GRUB_EHCI_SMASK_OFF = 0,
217 };
218
219 #define GRUB_EHCI_TERMINATE      (1<<0)
220
221 #define GRUB_EHCI_TOGGLE         (1<<31)
222
223 enum
224 {
225   GRUB_EHCI_TOTAL_MASK = (0x7fff << 16),
226   GRUB_EHCI_CERR_MASK = (3 << 10),
227   GRUB_EHCI_CERR_0 = (0 << 10),
228   GRUB_EHCI_CERR_1 = (1 << 10),
229   GRUB_EHCI_CERR_2 = (2 << 10),
230   GRUB_EHCI_CERR_3 = (3 << 10),
231   GRUB_EHCI_PIDCODE_OUT = (0 << 8),
232   GRUB_EHCI_PIDCODE_IN = (1 << 8),
233   GRUB_EHCI_PIDCODE_SETUP = (2 << 8),
234   GRUB_EHCI_STATUS_MASK = 0xff,
235   GRUB_EHCI_STATUS_ACTIVE = (1 << 7),
236   GRUB_EHCI_STATUS_HALTED = (1 << 6),
237   GRUB_EHCI_STATUS_BUFERR = (1 << 5),
238   GRUB_EHCI_STATUS_BABBLE = (1 << 4),
239   GRUB_EHCI_STATUS_TRANERR = (1 << 3),
240   GRUB_EHCI_STATUS_MISSDMF = (1 << 2),
241   GRUB_EHCI_STATUS_SPLITST = (1 << 1),
242   GRUB_EHCI_STATUS_PINGERR = (1 << 0)
243 };
244
245 enum
246 {
247   GRUB_EHCI_TOTAL_OFF = 16,
248   GRUB_EHCI_CERR_OFF = 10
249 };
250
251 #define GRUB_EHCI_BUFPTR_MASK    (0xfffff<<12)
252 #define GRUB_EHCI_QHTDPTR_MASK   0xffffffe0
253
254 #define GRUB_EHCI_TD_BUF_PAGES   5
255
256 #define GRUB_EHCI_BUFPAGELEN     0x1000
257 #define GRUB_EHCI_MAXBUFLEN      0x5000
258
259 struct grub_ehci_td;
260 struct grub_ehci_qh;
261 typedef volatile struct grub_ehci_td *grub_ehci_td_t;
262 typedef volatile struct grub_ehci_qh *grub_ehci_qh_t;
263
264 /* EHCI Isochronous Transfer Descriptor */
265 /* Currently not supported */
266
267 /* EHCI Split Transaction Isochronous Transfer Descriptor */
268 /* Currently not supported */
269
270 /* EHCI Queue Element Transfer Descriptor (qTD) */
271 /* Align to 32-byte boundaries */
272 struct grub_ehci_td
273 {
274   /* EHCI HW part */
275   grub_uint32_t next_td;        /* Pointer to next qTD */
276   grub_uint32_t alt_next_td;    /* Pointer to alternate next qTD */
277   grub_uint32_t token;          /* Toggle, Len, Interrupt, Page, Error, PID, Status */
278   grub_uint32_t buffer_page[GRUB_EHCI_TD_BUF_PAGES];    /* Buffer pointer (+ cur. offset in page 0 */
279   /* 64-bits part */
280   grub_uint32_t buffer_page_high[GRUB_EHCI_TD_BUF_PAGES];
281   /* EHCI driver part */
282   grub_uint32_t link_td;        /* pointer to next free/chained TD */
283   grub_uint32_t size;
284   grub_uint32_t pad[1];         /* padding to some multiple of 32 bytes */
285 };
286
287 /* EHCI Queue Head */
288 /* Align to 32-byte boundaries */
289 /* QH allocation is made in the similar/same way as in OHCI driver,
290  * because unlninking QH from the Asynchronous list is not so
291  * trivial as on UHCI (at least it is time consuming) */
292 struct grub_ehci_qh
293 {
294   /* EHCI HW part */
295   grub_uint32_t qh_hptr;        /* Horiz. pointer & Terminate */
296   grub_uint32_t ep_char;        /* EP characteristics */
297   grub_uint32_t ep_cap;         /* EP capabilities */
298   grub_uint32_t td_current;     /* current TD link pointer  */
299   struct grub_ehci_td td_overlay;       /* TD overlay area = 64 bytes */
300   /* EHCI driver part */
301   grub_uint32_t pad[4];         /* padding to some multiple of 32 bytes */
302 };
303
304 /* EHCI Periodic Frame Span Traversal Node */
305 /* Currently not supported */
306
307 struct grub_ehci
308 {
309   volatile grub_uint32_t *iobase_ehcc;  /* Capability registers */
310   volatile grub_uint32_t *iobase;       /* Operational registers */
311   struct grub_pci_dma_chunk *framelist_chunk;   /* Currently not used */
312   volatile grub_uint32_t *framelist_virt;
313   grub_uint32_t framelist_phys;
314   struct grub_pci_dma_chunk *qh_chunk;  /* GRUB_EHCI_N_QH Queue Heads */
315   grub_ehci_qh_t qh_virt;
316   grub_uint32_t qh_phys;
317   struct grub_pci_dma_chunk *td_chunk;  /* GRUB_EHCI_N_TD Transfer Descriptors */
318   grub_ehci_td_t td_virt;
319   grub_uint32_t td_phys;
320   grub_ehci_td_t tdfree_virt;   /* Free Transfer Descriptors */
321   int flag64;
322   grub_uint32_t reset;          /* bits 1-15 are flags if port was reset from connected time or not */
323   struct grub_ehci *next;
324 };
325
326 static struct grub_ehci *ehci;
327
328 static void
329 sync_all_caches (struct grub_ehci *e)
330 {
331   if (!e)
332     return;
333   if (e->td_virt)
334     grub_arch_sync_dma_caches (e->td_virt, sizeof (struct grub_ehci_td) *
335                                GRUB_EHCI_N_TD);
336   if (e->qh_virt)
337     grub_arch_sync_dma_caches (e->qh_virt, sizeof (struct grub_ehci_qh) *
338                                GRUB_EHCI_N_QH);
339   if (e->framelist_virt)
340     grub_arch_sync_dma_caches (e->framelist_virt, 4096);
341 }
342
343 /* EHCC registers access functions */
344 static inline grub_uint32_t
345 grub_ehci_ehcc_read32 (struct grub_ehci *e, grub_uint32_t addr)
346 {
347   return
348     grub_le_to_cpu32 (*((volatile grub_uint32_t *) e->iobase_ehcc +
349                        (addr / sizeof (grub_uint32_t))));
350 }
351
352 static inline grub_uint16_t
353 grub_ehci_ehcc_read16 (struct grub_ehci *e, grub_uint32_t addr)
354 {
355   return
356     grub_le_to_cpu16 (*((volatile grub_uint16_t *) e->iobase_ehcc +
357                        (addr / sizeof (grub_uint16_t))));
358 }
359
360 static inline grub_uint8_t
361 grub_ehci_ehcc_read8 (struct grub_ehci *e, grub_uint32_t addr)
362 {
363   return *((volatile grub_uint8_t *) e->iobase_ehcc + addr);
364 }
365
366 /* Operational registers access functions */
367 static inline grub_uint32_t
368 grub_ehci_oper_read32 (struct grub_ehci *e, grub_uint32_t addr)
369 {
370   return
371     grub_le_to_cpu32 (*
372                       ((volatile grub_uint32_t *) e->iobase +
373                        (addr / sizeof (grub_uint32_t))));
374 }
375
376 static inline void
377 grub_ehci_oper_write32 (struct grub_ehci *e, grub_uint32_t addr,
378                         grub_uint32_t value)
379 {
380   *((volatile grub_uint32_t *) e->iobase + (addr / sizeof (grub_uint32_t))) =
381     grub_cpu_to_le32 (value);
382 }
383
384 static inline grub_uint32_t
385 grub_ehci_port_read (struct grub_ehci *e, grub_uint32_t port)
386 {
387   return grub_ehci_oper_read32 (e, GRUB_EHCI_PORT_STAT_CMD + port * 4);
388 }
389
390 static inline void
391 grub_ehci_port_resbits (struct grub_ehci *e, grub_uint32_t port,
392                         grub_uint32_t bits)
393 {
394   grub_ehci_oper_write32 (e, GRUB_EHCI_PORT_STAT_CMD + port * 4,
395                           grub_ehci_port_read (e,
396                                                port) & GRUB_EHCI_PORT_WMASK &
397                           ~(bits));
398   grub_ehci_port_read (e, port);
399 }
400
401 static inline void
402 grub_ehci_port_setbits (struct grub_ehci *e, grub_uint32_t port,
403                         grub_uint32_t bits)
404 {
405   grub_ehci_oper_write32 (e, GRUB_EHCI_PORT_STAT_CMD + port * 4,
406                           (grub_ehci_port_read (e, port) &
407                            GRUB_EHCI_PORT_WMASK) | bits);
408   grub_ehci_port_read (e, port);
409 }
410
411 /* Halt if EHCI HC not halted */
412 static grub_usb_err_t
413 grub_ehci_halt (struct grub_ehci *e)
414 {
415   grub_uint64_t maxtime;
416
417   if ((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS) & GRUB_EHCI_ST_HC_HALTED) == 0)      /* EHCI is not halted */
418     {
419       /* Halt EHCI */
420       grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
421                               ~GRUB_EHCI_CMD_RUNSTOP
422                               & grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
423       /* Ensure command is written */
424       grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND);
425       maxtime = grub_get_time_ms () + 1000;     /* Fix: Should be 2ms ! */
426       while (((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS)
427                & GRUB_EHCI_ST_HC_HALTED) == 0)
428              && (grub_get_time_ms () < maxtime));
429       if ((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS)
430            & GRUB_EHCI_ST_HC_HALTED) == 0)
431         return GRUB_USB_ERR_TIMEOUT;
432     }
433
434   return GRUB_USB_ERR_NONE;
435 }
436
437 /* EHCI HC reset */
438 static grub_usb_err_t
439 grub_ehci_reset (struct grub_ehci *e)
440 {
441   grub_uint64_t maxtime;
442
443   sync_all_caches (e);
444
445   grub_dprintf ("ehci", "reset\n");
446
447   grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
448                           GRUB_EHCI_CMD_HC_RESET);
449   /* Ensure command is written */
450   grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND);
451   /* XXX: How long time could take reset of HC ? */
452   maxtime = grub_get_time_ms () + 1000;
453   while (((grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)
454            & GRUB_EHCI_CMD_HC_RESET) != 0)
455          && (grub_get_time_ms () < maxtime));
456   if ((grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)
457        & GRUB_EHCI_CMD_HC_RESET) != 0)
458     return GRUB_USB_ERR_TIMEOUT;
459
460   return GRUB_USB_ERR_NONE;
461 }
462
463 /* PCI iteration function... */
464 void
465 grub_ehci_init_device (volatile void *regs)
466 {
467   struct grub_ehci *e;
468   grub_uint32_t fp;
469   int i;
470   grub_uint32_t n_ports;
471   grub_uint8_t caplen;
472
473   /* Allocate memory for the controller and fill basic values. */
474   e = grub_zalloc (sizeof (*e));
475   if (!e)
476     return;
477   e->framelist_chunk = NULL;
478   e->td_chunk = NULL;
479   e->qh_chunk = NULL;
480   e->iobase_ehcc = regs;
481
482   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CAPLEN: %02x\n",
483                 grub_ehci_ehcc_read8 (e, GRUB_EHCI_EHCC_CAPLEN));
484   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: VERSION: %04x\n",
485                 grub_ehci_ehcc_read16 (e, GRUB_EHCI_EHCC_VERSION));
486   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: SPARAMS: %08x\n",
487                 grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_SPARAMS));
488   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CPARAMS: %08x\n",
489                 grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_CPARAMS));
490
491   /* Determine base address of EHCI operational registers */
492   caplen = grub_ehci_ehcc_read8 (e, GRUB_EHCI_EHCC_CAPLEN);
493 #ifndef GRUB_HAVE_UNALIGNED_ACCESS
494   if (caplen & (sizeof (grub_uint32_t) - 1))
495     {
496       grub_dprintf ("ehci", "Unaligned caplen\n");
497       return;
498     }
499   e->iobase = ((volatile grub_uint32_t *) e->iobase_ehcc
500                + (caplen / sizeof (grub_uint32_t)));
501 #else  
502   e->iobase = (volatile grub_uint32_t *) 
503     ((grub_uint8_t *) e->iobase_ehcc + caplen);
504 #endif
505
506   grub_dprintf ("ehci",
507                 "EHCI grub_ehci_pci_iter: iobase of oper. regs: %08llxx\n",
508                 (unsigned long long) e->iobase_ehcc + caplen);
509   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: COMMAND: %08x\n",
510                 grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
511   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: STATUS: %08x\n",
512                 grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS));
513   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: INTERRUPT: %08x\n",
514                 grub_ehci_oper_read32 (e, GRUB_EHCI_INTERRUPT));
515   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: FRAME_INDEX: %08x\n",
516                 grub_ehci_oper_read32 (e, GRUB_EHCI_FRAME_INDEX));
517   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: FL_BASE: %08x\n",
518                 grub_ehci_oper_read32 (e, GRUB_EHCI_FL_BASE));
519   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CUR_AL_ADDR: %08x\n",
520                 grub_ehci_oper_read32 (e, GRUB_EHCI_CUR_AL_ADDR));
521   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CONFIG_FLAG: %08x\n",
522                 grub_ehci_oper_read32 (e, GRUB_EHCI_CONFIG_FLAG));
523
524   /* Check format of data structures requested by EHCI */
525   /* XXX: In fact it is not used at any place, it is prepared for future
526    * This implementation uses 32-bits pointers only */
527   e->flag64 = ((grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_CPARAMS)
528                 & GRUB_EHCI_CPARAMS_64BIT) != 0);
529
530   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: flag64=%d\n", e->flag64);
531
532   /* Reserve a page for the frame list - it is accurate for max.
533    * possible size of framelist. But currently it is not used. */
534   e->framelist_chunk = grub_memalign_dma32 (4096, 4096);
535   if (!e->framelist_chunk)
536     goto fail;
537   e->framelist_virt = grub_dma_get_virt (e->framelist_chunk);
538   e->framelist_phys = grub_dma_get_phys (e->framelist_chunk);
539   grub_memset ((void *) e->framelist_virt, 0, 4096);
540
541   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: framelist mem=%p. OK\n",
542                 e->framelist_virt);
543
544   /* Allocate memory for the QHs and register it in "e".  */
545   e->qh_chunk = grub_memalign_dma32 (4096,
546                                      sizeof (struct grub_ehci_qh) *
547                                      GRUB_EHCI_N_QH);
548   if (!e->qh_chunk)
549     goto fail;
550   e->qh_virt = (grub_ehci_qh_t) grub_dma_get_virt (e->qh_chunk);
551   e->qh_phys = grub_dma_get_phys (e->qh_chunk);
552   grub_memset ((void *) e->qh_virt, 0,
553                sizeof (struct grub_ehci_qh) * GRUB_EHCI_N_QH);
554
555   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: QH mem=%p. OK\n",
556                 e->qh_virt);
557
558   /* Allocate memory for the TDs and register it in "e".  */
559   e->td_chunk = grub_memalign_dma32 (4096,
560                                      sizeof (struct grub_ehci_td) *
561                                      GRUB_EHCI_N_TD);
562   if (!e->td_chunk)
563     goto fail;
564   e->td_virt = (grub_ehci_td_t) grub_dma_get_virt (e->td_chunk);
565   e->td_phys = grub_dma_get_phys (e->td_chunk);
566   grub_memset ((void *) e->td_virt, 0,
567                sizeof (struct grub_ehci_td) * GRUB_EHCI_N_TD);
568
569   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: TD mem=%p. OK\n",
570                 e->td_virt);
571
572   /* Setup all frame list pointers. Since no isochronous transfers
573      are supported, they all point to the (same!) queue
574      head with index 0. */
575   fp = grub_cpu_to_le32 ((e->qh_phys & GRUB_EHCI_POINTER_MASK)
576                          | GRUB_EHCI_HPTR_TYPE_QH);
577   for (i = 0; i < GRUB_EHCI_N_FRAMELIST; i++)
578     e->framelist_virt[i] = fp;
579   /* Prepare chain of all TDs and set Terminate in all TDs */
580   for (i = 0; i < (GRUB_EHCI_N_TD - 1); i++)
581     {
582       e->td_virt[i].link_td = e->td_phys + (i + 1) * sizeof (struct grub_ehci_td);
583       e->td_virt[i].next_td = grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE);
584       e->td_virt[i].alt_next_td = grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE);
585     }
586   e->td_virt[GRUB_EHCI_N_TD - 1].next_td =
587     grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE);
588   e->td_virt[GRUB_EHCI_N_TD - 1].alt_next_td =
589     grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE);
590   e->tdfree_virt = e->td_virt;
591   /* Set Terminate in first QH, which is used in framelist */
592   e->qh_virt[0].qh_hptr = grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE | GRUB_EHCI_HPTR_TYPE_QH);
593   e->qh_virt[0].td_overlay.next_td = grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE);
594   e->qh_virt[0].td_overlay.alt_next_td =
595     grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE);
596   /* Also set Halted bit in token */
597   e->qh_virt[0].td_overlay.token = grub_cpu_to_le32_compile_time (GRUB_EHCI_STATUS_HALTED);
598   /* Set the H bit in first QH used for AL */
599   e->qh_virt[1].ep_char = grub_cpu_to_le32_compile_time (GRUB_EHCI_H);
600   /* Set Terminate into TD in rest of QHs and set horizontal link
601    * pointer to itself - these QHs will be used for asynchronous
602    * schedule and they should have valid value in horiz. link */
603   for (i = 1; i < GRUB_EHCI_N_QH; i++)
604     {
605       e->qh_virt[i].qh_hptr =
606         grub_cpu_to_le32 ((grub_dma_virt2phys (&e->qh_virt[i],
607                                                 e->qh_chunk) &
608                            GRUB_EHCI_POINTER_MASK) | GRUB_EHCI_HPTR_TYPE_QH);
609       e->qh_virt[i].td_overlay.next_td =
610         grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE);
611       e->qh_virt[i].td_overlay.alt_next_td =
612         grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE);
613       /* Also set Halted bit in token */
614       e->qh_virt[i].td_overlay.token =
615         grub_cpu_to_le32_compile_time (GRUB_EHCI_STATUS_HALTED);
616     }
617
618   /* Note: QH 0 and QH 1 are reserved and must not be used anywhere.
619    * QH 0 is used as empty QH for framelist
620    * QH 1 is used as starting empty QH for asynchronous schedule
621    * QH 1 must exist at any time because at least one QH linked to
622    * itself must exist in asynchronous schedule
623    * QH 1 has the H flag set to one */
624
625   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: QH/TD init. OK\n");
626
627   /* Now we can setup EHCI (maybe...) */
628
629   /* Check if EHCI is halted and halt it if not */
630   if (grub_ehci_halt (e) != GRUB_USB_ERR_NONE)
631     {
632       grub_error (GRUB_ERR_TIMEOUT,
633                   "EHCI grub_ehci_pci_iter: EHCI halt timeout");
634       goto fail;
635     }
636
637   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: halted OK\n");
638
639   /* Reset EHCI */
640   if (grub_ehci_reset (e) != GRUB_USB_ERR_NONE)
641     {
642       grub_error (GRUB_ERR_TIMEOUT,
643                   "EHCI grub_ehci_pci_iter: EHCI reset timeout");
644       goto fail;
645     }
646
647   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: reset OK\n");
648
649   /* Setup list address registers */
650   grub_ehci_oper_write32 (e, GRUB_EHCI_FL_BASE, e->framelist_phys);
651   grub_ehci_oper_write32 (e, GRUB_EHCI_CUR_AL_ADDR,
652                           grub_dma_virt2phys (&e->qh_virt[1],
653                                                e->qh_chunk));
654
655   /* Set ownership of root hub ports to EHCI */
656   grub_ehci_oper_write32 (e, GRUB_EHCI_CONFIG_FLAG, GRUB_EHCI_CF_EHCI_OWNER);
657
658   /* Enable both lists */
659   grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
660                           GRUB_EHCI_CMD_AS_ENABL
661                           | GRUB_EHCI_CMD_PS_ENABL
662                           | grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
663
664   /* Now should be possible to power-up and enumerate ports etc. */
665   if ((grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_SPARAMS)
666        & GRUB_EHCI_SPARAMS_PPC) != 0)
667     {                           /* EHCI has port powering control */
668       /* Power on all ports */
669       n_ports = grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_SPARAMS)
670         & GRUB_EHCI_SPARAMS_N_PORTS;
671       for (i = 0; i < (int) n_ports; i++)
672         grub_ehci_oper_write32 (e, GRUB_EHCI_PORT_STAT_CMD + i * 4,
673                                 GRUB_EHCI_PORT_POWER
674                                 | grub_ehci_oper_read32 (e,
675                                                          GRUB_EHCI_PORT_STAT_CMD
676                                                          + i * 4));
677     }
678
679   /* Ensure all commands are written */
680   grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND);
681
682   /* Enable EHCI */
683   grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
684                           GRUB_EHCI_CMD_RUNSTOP
685                           | grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
686
687   /* Ensure command is written */
688   grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND);
689
690   /* Link to ehci now that initialisation is successful.  */
691   e->next = ehci;
692   ehci = e;
693
694   sync_all_caches (e);
695
696   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: OK at all\n");
697
698   grub_dprintf ("ehci",
699                 "EHCI grub_ehci_pci_iter: iobase of oper. regs: %08llx\n",
700                 (unsigned long long) regs);
701   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: COMMAND: %08x\n",
702                 grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
703   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: STATUS: %08x\n",
704                 grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS));
705   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: INTERRUPT: %08x\n",
706                 grub_ehci_oper_read32 (e, GRUB_EHCI_INTERRUPT));
707   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: FRAME_INDEX: %08x\n",
708                 grub_ehci_oper_read32 (e, GRUB_EHCI_FRAME_INDEX));
709   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: FL_BASE: %08x\n",
710                 grub_ehci_oper_read32 (e, GRUB_EHCI_FL_BASE));
711   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CUR_AL_ADDR: %08x\n",
712                 grub_ehci_oper_read32 (e, GRUB_EHCI_CUR_AL_ADDR));
713   grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CONFIG_FLAG: %08x\n",
714                 grub_ehci_oper_read32 (e, GRUB_EHCI_CONFIG_FLAG));
715
716   return;
717
718 fail:
719   if (e)
720     {
721       if (e->td_chunk)
722         grub_dma_free ((void *) e->td_chunk);
723       if (e->qh_chunk)
724         grub_dma_free ((void *) e->qh_chunk);
725       if (e->framelist_chunk)
726         grub_dma_free (e->framelist_chunk);
727     }
728   grub_free (e);
729
730   return;
731 }
732
733 static int
734 grub_ehci_iterate (grub_usb_controller_iterate_hook_t hook, void *hook_data)
735 {
736   struct grub_ehci *e;
737   struct grub_usb_controller dev;
738
739   for (e = ehci; e; e = e->next)
740     {
741       dev.data = e;
742       if (hook (&dev, hook_data))
743         return 1;
744     }
745
746   return 0;
747 }
748
749 static void
750 grub_ehci_setup_qh (grub_ehci_qh_t qh, grub_usb_transfer_t transfer)
751 {
752   grub_uint32_t ep_char = 0;
753   grub_uint32_t ep_cap = 0;
754
755   /* Note: Another part of code is responsible to this QH is
756    * Halted ! But it can be linked in AL, so we cannot erase or
757    * change qh_hptr ! */
758   /* We will not change any TD field because they should/must be
759    * in safe state from previous use. */
760
761   /* EP characteristic setup */
762   /* Currently not used NAK counter (RL=0),
763    * C bit set if EP is not HIGH speed and is control,
764    * Max Packet Length is taken from transfer structure,
765    * H bit = 0 (because QH[1] has this bit set),
766    * DTC bit set to 1 because we are using our own toggle bit control,
767    * SPEED is selected according to value from transfer structure,
768    * EP number is taken from transfer structure
769    * "I" bit must not be set,
770    * Device Address is taken from transfer structure
771    * */
772   if ((transfer->dev->speed != GRUB_USB_SPEED_HIGH)
773       && (transfer->type == GRUB_USB_TRANSACTION_TYPE_CONTROL))
774     ep_char |= GRUB_EHCI_C;
775   ep_char |= (transfer->max << GRUB_EHCI_MAXPLEN_OFF)
776     & GRUB_EHCI_MAXPLEN_MASK;
777   ep_char |= GRUB_EHCI_DTC;
778   switch (transfer->dev->speed)
779     {
780     case GRUB_USB_SPEED_LOW:
781       ep_char |= GRUB_EHCI_SPEED_LOW;
782       break;
783     case GRUB_USB_SPEED_FULL:
784       ep_char |= GRUB_EHCI_SPEED_FULL;
785       break;
786     case GRUB_USB_SPEED_HIGH:
787     default:
788       ep_char |= GRUB_EHCI_SPEED_HIGH;
789       /* XXX: How we will handle unknown value of speed? */
790     }
791   ep_char |= (transfer->endpoint << GRUB_EHCI_EP_NUM_OFF)
792     & GRUB_EHCI_EP_NUM_MASK;
793   ep_char |= transfer->devaddr & GRUB_EHCI_DEVADDR_MASK;
794   qh->ep_char = grub_cpu_to_le32 (ep_char);
795   /* EP capabilities setup */
796   /* MULT field - we try to use max. number
797    * PortNumber - included now in device structure referenced
798    *              inside transfer structure
799    * HubAddress - included now in device structure referenced
800    *              inside transfer structure
801    * SplitCompletionMask - AFAIK it is ignored in asynchronous list,
802    * InterruptScheduleMask - AFAIK it should be zero in async. list */
803   ep_cap |= GRUB_EHCI_MULT_THREE;
804   ep_cap |= (transfer->dev->split_hubport << GRUB_EHCI_DEVPORT_OFF)
805     & GRUB_EHCI_DEVPORT_MASK;
806   ep_cap |= (transfer->dev->split_hubaddr << GRUB_EHCI_HUBADDR_OFF)
807     & GRUB_EHCI_HUBADDR_MASK;
808   if (transfer->dev->speed == GRUB_USB_SPEED_LOW
809       && transfer->type != GRUB_USB_TRANSACTION_TYPE_CONTROL)
810   {
811     ep_cap |= (1<<0) << GRUB_EHCI_SMASK_OFF;
812     ep_cap |= (7<<2) << GRUB_EHCI_CMASK_OFF;
813   }
814   qh->ep_cap = grub_cpu_to_le32 (ep_cap);
815
816   grub_dprintf ("ehci", "setup_qh: qh=%p, not changed: qh_hptr=%08x\n",
817                 qh, grub_le_to_cpu32 (qh->qh_hptr));
818   grub_dprintf ("ehci", "setup_qh: ep_char=%08x, ep_cap=%08x\n",
819                 ep_char, ep_cap);
820   grub_dprintf ("ehci", "setup_qh: end\n");
821   grub_dprintf ("ehci", "setup_qh: not changed: td_current=%08x\n",
822                 grub_le_to_cpu32 (qh->td_current));
823   grub_dprintf ("ehci", "setup_qh: not changed: next_td=%08x\n",
824                 grub_le_to_cpu32 (qh->td_overlay.next_td));
825   grub_dprintf ("ehci", "setup_qh: not changed: alt_next_td=%08x\n",
826                 grub_le_to_cpu32 (qh->td_overlay.alt_next_td));
827   grub_dprintf ("ehci", "setup_qh: not changed: token=%08x\n",
828                 grub_le_to_cpu32 (qh->td_overlay.token));
829 }
830
831 static grub_ehci_qh_t
832 grub_ehci_find_qh (struct grub_ehci *e, grub_usb_transfer_t transfer)
833 {
834   grub_uint32_t target, mask;
835   int i;
836   grub_ehci_qh_t qh = e->qh_virt;
837   grub_ehci_qh_t head;
838   grub_uint32_t qh_phys;
839   grub_uint32_t qh_terminate =
840     GRUB_EHCI_TERMINATE | GRUB_EHCI_HPTR_TYPE_QH;
841   grub_ehci_qh_t qh_iter;
842
843   /* Prepare part of EP Characteristic to find existing QH */
844   target = ((transfer->endpoint << GRUB_EHCI_EP_NUM_OFF) |
845             transfer->devaddr) & GRUB_EHCI_TARGET_MASK;
846   target = grub_cpu_to_le32 (target);
847   mask = grub_cpu_to_le32_compile_time (GRUB_EHCI_TARGET_MASK);
848
849   /* low speed interrupt transfers are linked to the periodic */
850   /* schedule, everything else to the asynchronous schedule */
851   if (transfer->dev->speed == GRUB_USB_SPEED_LOW
852       && transfer->type != GRUB_USB_TRANSACTION_TYPE_CONTROL)
853     head = &qh[0];
854   else
855     head = &qh[1];
856
857   /* First try to find existing QH with proper target in proper list */
858   qh_phys = grub_le_to_cpu32( head->qh_hptr );
859   if (qh_phys != qh_terminate)
860     qh_iter = grub_dma_phys2virt ( qh_phys & GRUB_EHCI_QHTDPTR_MASK,
861       e->qh_chunk );
862   else
863     qh_iter = NULL;
864
865   for (
866     i = 0;
867     (qh_phys != qh_terminate) && (qh_iter != NULL) &&
868     (qh_iter != head) && (i < GRUB_EHCI_N_QH);
869     i++ )
870     {
871       if (target == (qh_iter->ep_char & mask))
872         {               
873           /* Found proper existing (and linked) QH, do setup of QH */
874           grub_dprintf ("ehci", "find_qh: found, QH=%p\n", qh_iter);
875           grub_ehci_setup_qh (qh_iter, transfer);
876           sync_all_caches (e);
877           return qh_iter;
878         }
879
880       qh_phys = grub_le_to_cpu32( qh_iter->qh_hptr );
881       if (qh_phys != qh_terminate)
882         qh_iter = grub_dma_phys2virt ( qh_phys & GRUB_EHCI_QHTDPTR_MASK,
883           e->qh_chunk );
884       else
885         qh_iter = NULL;
886     }
887
888   /* variable "i" should be never equal to GRUB_EHCI_N_QH here */
889   if (i >= GRUB_EHCI_N_QH)
890     { /* Something very bad happened in QH list(s) ! */
891       grub_dprintf ("ehci", "find_qh: Mismatch in QH list! head=%p\n",
892         head);
893     }
894
895   /* QH with target_addr does not exist, we have to find and add it */
896   for (i = 2; i < GRUB_EHCI_N_QH; i++) /* We ignore zero and first QH */
897     {
898       if (!qh[i].ep_char)
899         break;               /* Found first not-allocated QH, finish */
900     }
901
902   /* Have we any free QH in array ? */
903   if (i >= GRUB_EHCI_N_QH)      /* No. */
904     {
905       grub_dprintf ("ehci", "find_qh: end - no free QH\n");
906       return NULL;
907     }
908   grub_dprintf ("ehci", "find_qh: new, i=%d, QH=%p\n",
909                 i, &qh[i]);
910   /* Currently we simply take next (current) QH in array, no allocation
911    * function is used. It should be no problem until we will need to
912    * de-allocate QHs of unplugged devices. */
913   /* We should preset new QH and link it into AL */
914   grub_ehci_setup_qh (&qh[i], transfer);
915
916   /* Linking - this new (last) QH will copy the QH from the head QH */
917   qh[i].qh_hptr = head->qh_hptr;
918   /* Linking - the head QH will point to this new QH */
919   head->qh_hptr = grub_cpu_to_le32 (GRUB_EHCI_HPTR_TYPE_QH
920                                     | grub_dma_virt2phys (&qh[i],
921                                                           e->qh_chunk));
922
923   return &qh[i];
924 }
925
926 static grub_ehci_td_t
927 grub_ehci_alloc_td (struct grub_ehci *e)
928 {
929   grub_ehci_td_t ret;
930
931   /* Check if there is a Transfer Descriptor available.  */
932   if (!e->tdfree_virt)
933     {
934       grub_dprintf ("ehci", "alloc_td: end - no free TD\n");
935       return NULL;
936     }
937
938   ret = e->tdfree_virt;         /* Take current free TD */
939   /* Advance to next free TD in chain */
940   if (ret->link_td)
941     e->tdfree_virt = grub_dma_phys2virt (ret->link_td, e->td_chunk);
942   else
943     e->tdfree_virt = NULL;
944   ret->link_td = 0;             /* Reset link_td in allocated TD */
945   return ret;
946 }
947
948 static void
949 grub_ehci_free_td (struct grub_ehci *e, grub_ehci_td_t td)
950 {
951   /* Chain new free TD & rest */
952   if (e->tdfree_virt)
953     td->link_td = grub_dma_virt2phys (e->tdfree_virt, e->td_chunk);
954   else
955     td->link_td = 0;
956   e->tdfree_virt = td;          /* Change address of first free TD */
957 }
958
959 static void
960 grub_ehci_free_tds (struct grub_ehci *e, grub_ehci_td_t td,
961                     grub_usb_transfer_t transfer, grub_size_t * actual)
962 {
963   int i;                        /* Index of TD in transfer */
964   grub_uint32_t token, to_transfer;
965
966   /* Note: Another part of code is responsible to this QH is
967    * INACTIVE ! */
968   *actual = 0;
969
970   /* Free the TDs in this queue and set last_trans.  */
971   for (i = 0; td; i++)
972     {
973       grub_ehci_td_t tdprev;
974
975       token = grub_le_to_cpu32 (td->token);
976       to_transfer = (token & GRUB_EHCI_TOTAL_MASK) >> GRUB_EHCI_TOTAL_OFF;
977
978       /* Check state of TD - if it did not transfer
979        * whole data then set last_trans - it should be last executed TD
980        * in case when something went wrong. */
981       if (transfer && (td->size != to_transfer))
982         transfer->last_trans = i;
983
984       *actual += td->size - to_transfer;
985
986       /* Unlink the TD */
987       tdprev = td;
988       if (td->link_td)
989         td = grub_dma_phys2virt (td->link_td, e->td_chunk);
990       else
991         td = NULL;
992
993       /* Free the TD.  */
994       grub_ehci_free_td (e, tdprev);
995     }
996
997   /* Check if last_trans was set. If not and something was
998    * transferred (it should be all data in this case), set it
999    * to index of last TD, i.e. i-1 */
1000   if (transfer && (transfer->last_trans < 0) && (*actual != 0))
1001     transfer->last_trans = i - 1;
1002
1003   /* XXX: Fix it: last_trans may be set to bad index.
1004    * Probably we should test more error flags to distinguish
1005    * if TD was at least partialy executed or not at all.
1006    * Generaly, we still could have problem with toggling because
1007    * EHCI can probably split transactions into smaller parts then
1008    * we defined in transaction even if we did not exceed MaxFrame
1009    * length - it probably could happen at the end of microframe (?)
1010    * and if the buffer is crossing page boundary (?). */
1011 }
1012
1013 static grub_ehci_td_t
1014 grub_ehci_transaction (struct grub_ehci *e,
1015                        grub_transfer_type_t type,
1016                        unsigned int toggle, grub_size_t size,
1017                        grub_uint32_t data, grub_ehci_td_t td_alt)
1018 {
1019   grub_ehci_td_t td;
1020   grub_uint32_t token;
1021   grub_uint32_t bufadr;
1022   int i;
1023
1024   /* Test of transfer size, it can be:
1025    * <= GRUB_EHCI_MAXBUFLEN if data aligned to page boundary
1026    * <= GRUB_EHCI_MAXBUFLEN - GRUB_EHCI_BUFPAGELEN if not aligned
1027    *    (worst case)
1028    */
1029   if ((((data % GRUB_EHCI_BUFPAGELEN) == 0)
1030        && (size > GRUB_EHCI_MAXBUFLEN))
1031       ||
1032       (((data % GRUB_EHCI_BUFPAGELEN) != 0)
1033        && (size > (GRUB_EHCI_MAXBUFLEN - GRUB_EHCI_BUFPAGELEN))))
1034     {
1035       grub_error (GRUB_ERR_OUT_OF_MEMORY,
1036                   "too long data buffer for EHCI transaction");
1037       return 0;
1038     }
1039
1040   /* Grab a free Transfer Descriptor and initialize it.  */
1041   td = grub_ehci_alloc_td (e);
1042   if (!td)
1043     {
1044       grub_error (GRUB_ERR_OUT_OF_MEMORY,
1045                   "no transfer descriptors available for EHCI transfer");
1046       return 0;
1047     }
1048
1049   grub_dprintf ("ehci",
1050                 "transaction: type=%d, toggle=%d, size=%lu data=0x%x td=%p\n",
1051                 type, toggle, (unsigned long) size, data, td);
1052
1053   /* Fill whole TD by zeros */
1054   grub_memset ((void *) td, 0, sizeof (struct grub_ehci_td));
1055
1056   /* Don't point to any TD yet, just terminate.  */
1057   td->next_td = grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE);
1058   /* Set alternate pointer. When short packet occurs, alternate TD
1059    * will not be really fetched because it is not active. But don't
1060    * forget, EHCI will try to fetch alternate TD every scan of AL
1061    * until QH is halted. */
1062   td->alt_next_td = grub_cpu_to_le32 (grub_dma_virt2phys (td_alt,
1063                                                            e->td_chunk));
1064   /* token:
1065    * TOGGLE - according to toggle
1066    * TOTAL SIZE = size
1067    * Interrupt On Complete = FALSE, we don't need IRQ
1068    * Current Page = 0
1069    * Error Counter = max. value = 3
1070    * PID Code - according to type
1071    * STATUS:
1072    *  ACTIVE bit should be set to one
1073    *  SPLIT TRANS. STATE bit should be zero. It is ignored
1074    *   in HIGH speed transaction, and should be zero for LOW/FULL
1075    *   speed to indicate state Do Split Transaction */
1076   token = toggle ? GRUB_EHCI_TOGGLE : 0;
1077   token |= (size << GRUB_EHCI_TOTAL_OFF) & GRUB_EHCI_TOTAL_MASK;
1078   token |= GRUB_EHCI_CERR_3;
1079   switch (type)
1080     {
1081     case GRUB_USB_TRANSFER_TYPE_IN:
1082       token |= GRUB_EHCI_PIDCODE_IN;
1083       break;
1084     case GRUB_USB_TRANSFER_TYPE_OUT:
1085       token |= GRUB_EHCI_PIDCODE_OUT;
1086       break;
1087     case GRUB_USB_TRANSFER_TYPE_SETUP:
1088       token |= GRUB_EHCI_PIDCODE_SETUP;
1089       break;
1090     default:                    /* XXX: Should not happen, but what to do if it does ? */
1091       break;
1092     }
1093   token |= GRUB_EHCI_STATUS_ACTIVE;
1094   td->token = grub_cpu_to_le32 (token);
1095
1096   /* Fill buffer pointers according to size */
1097   bufadr = data;
1098   td->buffer_page[0] = grub_cpu_to_le32 (bufadr);
1099   bufadr = ((bufadr / GRUB_EHCI_BUFPAGELEN) + 1) * GRUB_EHCI_BUFPAGELEN;
1100   for (i = 1; ((bufadr - data) < size) && (i < GRUB_EHCI_TD_BUF_PAGES); i++)
1101     {
1102       td->buffer_page[i] = grub_cpu_to_le32 (bufadr & GRUB_EHCI_BUFPTR_MASK);
1103       bufadr = ((bufadr / GRUB_EHCI_BUFPAGELEN) + 1) * GRUB_EHCI_BUFPAGELEN;
1104     }
1105
1106   /* Remember data size for future use... */
1107   td->size = (grub_uint32_t) size;
1108
1109   grub_dprintf ("ehci", "td=%p\n", td);
1110   grub_dprintf ("ehci", "HW: next_td=%08x, alt_next_td=%08x\n",
1111                 grub_le_to_cpu32 (td->next_td),
1112                 grub_le_to_cpu32 (td->alt_next_td));
1113   grub_dprintf ("ehci", "HW: token=%08x, buffer[0]=%08x\n",
1114                 grub_le_to_cpu32 (td->token),
1115                 grub_le_to_cpu32 (td->buffer_page[0]));
1116   grub_dprintf ("ehci", "HW: buffer[1]=%08x, buffer[2]=%08x\n",
1117                 grub_le_to_cpu32 (td->buffer_page[1]),
1118                 grub_le_to_cpu32 (td->buffer_page[2]));
1119   grub_dprintf ("ehci", "HW: buffer[3]=%08x, buffer[4]=%08x\n",
1120                 grub_le_to_cpu32 (td->buffer_page[3]),
1121                 grub_le_to_cpu32 (td->buffer_page[4]));
1122   grub_dprintf ("ehci", "link_td=%08x, size=%08x\n",
1123                 td->link_td, td->size);
1124
1125   return td;
1126 }
1127
1128 struct grub_ehci_transfer_controller_data
1129 {
1130   grub_ehci_qh_t qh_virt;
1131   grub_ehci_td_t td_first_virt;
1132   grub_ehci_td_t td_alt_virt;
1133   grub_ehci_td_t td_last_virt;
1134   grub_uint32_t td_last_phys;
1135 };
1136
1137 static grub_usb_err_t
1138 grub_ehci_setup_transfer (grub_usb_controller_t dev,
1139                           grub_usb_transfer_t transfer)
1140 {
1141   struct grub_ehci *e = (struct grub_ehci *) dev->data;
1142   grub_ehci_td_t td = NULL;
1143   grub_ehci_td_t td_prev = NULL;
1144   int i;
1145   struct grub_ehci_transfer_controller_data *cdata;
1146   grub_uint32_t status;
1147
1148   sync_all_caches (e);
1149
1150   /* Check if EHCI is running and AL is enabled */
1151   status = grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS);
1152   if ((status & GRUB_EHCI_ST_HC_HALTED) != 0)
1153     /* XXX: Fix it: Currently we don't do anything to restart EHCI */
1154     {
1155       grub_dprintf ("ehci", "setup_transfer: halted, status = 0x%x\n",
1156                     status);
1157       return GRUB_USB_ERR_INTERNAL;
1158     }
1159   status = grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS);
1160   if ((status
1161        & (GRUB_EHCI_ST_AS_STATUS | GRUB_EHCI_ST_PS_STATUS)) == 0)
1162     /* XXX: Fix it: Currently we don't do anything to restart EHCI */
1163     {
1164       grub_dprintf ("ehci", "setup_transfer: no AS/PS, status = 0x%x\n",
1165                     status);
1166       return GRUB_USB_ERR_INTERNAL;
1167     }
1168
1169   /* Allocate memory for controller transfer data.  */
1170   cdata = grub_malloc (sizeof (*cdata));
1171   if (!cdata)
1172     return GRUB_USB_ERR_INTERNAL;
1173   cdata->td_first_virt = NULL;
1174
1175   /* Allocate a queue head for the transfer queue.  */
1176   cdata->qh_virt = grub_ehci_find_qh (e, transfer);
1177   if (!cdata->qh_virt)
1178     {
1179       grub_dprintf ("ehci", "setup_transfer: no QH\n");
1180       grub_free (cdata);
1181       return GRUB_USB_ERR_INTERNAL;
1182     }
1183
1184   /* To detect short packet we need some additional "alternate" TD,
1185    * allocate it first. */
1186   cdata->td_alt_virt = grub_ehci_alloc_td (e);
1187   if (!cdata->td_alt_virt)
1188     {
1189       grub_dprintf ("ehci", "setup_transfer: no TDs\n");
1190       grub_free (cdata);
1191       return GRUB_USB_ERR_INTERNAL;
1192     }
1193   /* Fill whole alternate TD by zeros (= inactive) and set
1194    * Terminate bits and Halt bit */
1195   grub_memset ((void *) cdata->td_alt_virt, 0, sizeof (struct grub_ehci_td));
1196   cdata->td_alt_virt->next_td = grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE);
1197   cdata->td_alt_virt->alt_next_td = grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE);
1198   cdata->td_alt_virt->token = grub_cpu_to_le32_compile_time (GRUB_EHCI_STATUS_HALTED);
1199
1200   /* Allocate appropriate number of TDs and set */
1201   for (i = 0; i < transfer->transcnt; i++)
1202     {
1203       grub_usb_transaction_t tr = &transfer->transactions[i];
1204
1205       td = grub_ehci_transaction (e, tr->pid, tr->toggle, tr->size,
1206                                   tr->data, cdata->td_alt_virt);
1207
1208       if (!td)                  /* de-allocate and free all */
1209         {
1210           grub_size_t actual = 0;
1211
1212           if (cdata->td_first_virt)
1213             grub_ehci_free_tds (e, cdata->td_first_virt, NULL, &actual);
1214
1215           grub_free (cdata);
1216           grub_dprintf ("ehci", "setup_transfer: no TD\n");
1217           return GRUB_USB_ERR_INTERNAL;
1218         }
1219
1220       /* Register new TD in cdata or previous TD */
1221       if (!cdata->td_first_virt)
1222         cdata->td_first_virt = td;
1223       else
1224         {
1225           td_prev->link_td = grub_dma_virt2phys (td, e->td_chunk);
1226           td_prev->next_td =
1227             grub_cpu_to_le32 (grub_dma_virt2phys (td, e->td_chunk));
1228         }
1229       td_prev = td;
1230     }
1231
1232   /* Remember last TD */
1233   cdata->td_last_virt = td;
1234   cdata->td_last_phys = grub_dma_virt2phys (td, e->td_chunk);
1235   /* Last TD should not have set alternate TD */
1236   cdata->td_last_virt->alt_next_td = grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE);
1237
1238   grub_dprintf ("ehci", "setup_transfer: cdata=%p, qh=%p\n",
1239                 cdata,cdata->qh_virt);
1240   grub_dprintf ("ehci", "setup_transfer: td_first=%p, td_alt=%p\n",
1241                 cdata->td_first_virt,
1242                 cdata->td_alt_virt);
1243   grub_dprintf ("ehci", "setup_transfer: td_last=%p\n",
1244                 cdata->td_last_virt);
1245
1246   /* Start transfer: */
1247   /* Unlink possible alternate pointer in QH */
1248   cdata->qh_virt->td_overlay.alt_next_td =
1249     grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE);
1250   /* Link new TDs with QH via next_td */
1251   cdata->qh_virt->td_overlay.next_td =
1252     grub_cpu_to_le32 (grub_dma_virt2phys
1253                       (cdata->td_first_virt, e->td_chunk));
1254   /* Reset Active and Halted bits in QH to activate Advance Queue,
1255    * i.e. reset token */
1256   cdata->qh_virt->td_overlay.token = grub_cpu_to_le32_compile_time (0);
1257
1258   sync_all_caches (e);
1259
1260   /* Finito */
1261   transfer->controller_data = cdata;
1262
1263   return GRUB_USB_ERR_NONE;
1264 }
1265
1266 /* This function expects QH is not active.
1267  * Function set Halt bit in QH TD overlay and possibly prints
1268  * necessary debug information. */
1269 static void
1270 grub_ehci_pre_finish_transfer (grub_usb_transfer_t transfer)
1271 {
1272   struct grub_ehci_transfer_controller_data *cdata =
1273     transfer->controller_data;
1274
1275   /* Collect debug data here if necessary */
1276
1277   /* Set Halt bit in not active QH. AL will not attempt to do
1278    * Advance Queue on QH with Halt bit set, i.e., we can then
1279    * safely manipulate with QH TD part. */
1280   cdata->qh_virt->td_overlay.token = (cdata->qh_virt->td_overlay.token
1281                                       |
1282                                       grub_cpu_to_le32_compile_time
1283                                       (GRUB_EHCI_STATUS_HALTED)) &
1284     grub_cpu_to_le32_compile_time (~GRUB_EHCI_STATUS_ACTIVE);
1285
1286   /* Print debug data here if necessary */
1287
1288 }
1289
1290 static grub_usb_err_t
1291 grub_ehci_parse_notrun (grub_usb_controller_t dev,
1292                         grub_usb_transfer_t transfer, grub_size_t * actual)
1293 {
1294   struct grub_ehci *e = dev->data;
1295   struct grub_ehci_transfer_controller_data *cdata =
1296     transfer->controller_data;
1297
1298   grub_dprintf ("ehci", "parse_notrun: info\n");
1299
1300   /* QH can be in any state in this case. */
1301   /* But EHCI or AL is not running, so QH is surely not active
1302    * even if it has Active bit set... */
1303   grub_ehci_pre_finish_transfer (transfer);
1304   grub_ehci_free_tds (e, cdata->td_first_virt, transfer, actual);
1305   grub_ehci_free_td (e, cdata->td_alt_virt);
1306   grub_free (cdata);
1307
1308   sync_all_caches (e);
1309
1310   /* Additionally, do something with EHCI to make it running (what?) */
1311   /* Try enable EHCI and AL */
1312   grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
1313                           GRUB_EHCI_CMD_RUNSTOP | GRUB_EHCI_CMD_AS_ENABL
1314                           | GRUB_EHCI_CMD_PS_ENABL
1315                           | grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
1316   /* Ensure command is written */
1317   grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND);
1318
1319   return GRUB_USB_ERR_UNRECOVERABLE;
1320 }
1321
1322 static grub_usb_err_t
1323 grub_ehci_parse_halt (grub_usb_controller_t dev,
1324                       grub_usb_transfer_t transfer, grub_size_t * actual)
1325 {
1326   struct grub_ehci *e = dev->data;
1327   struct grub_ehci_transfer_controller_data *cdata =
1328     transfer->controller_data;
1329   grub_uint32_t token;
1330   grub_usb_err_t err = GRUB_USB_ERR_NAK;
1331
1332   /* QH should be halted and not active in this case. */
1333
1334   grub_dprintf ("ehci", "parse_halt: info\n");
1335
1336   /* Remember token before call pre-finish function */
1337   token = grub_le_to_cpu32 (cdata->qh_virt->td_overlay.token);
1338
1339   /* Do things like in normal finish */
1340   grub_ehci_pre_finish_transfer (transfer);
1341   grub_ehci_free_tds (e, cdata->td_first_virt, transfer, actual);
1342   grub_ehci_free_td (e, cdata->td_alt_virt);
1343   grub_free (cdata);
1344
1345   sync_all_caches (e);
1346
1347   /* Evaluation of error code - currently we don't have GRUB USB error
1348    * codes for some EHCI states, GRUB_USB_ERR_DATA is used for them.
1349    * Order of evaluation is critical, specially bubble/stall. */
1350   if ((token & GRUB_EHCI_STATUS_BABBLE) != 0)
1351     err = GRUB_USB_ERR_BABBLE;
1352   else if ((token & GRUB_EHCI_CERR_MASK) != 0)
1353     err = GRUB_USB_ERR_STALL;
1354   else if ((token & GRUB_EHCI_STATUS_TRANERR) != 0)
1355     err = GRUB_USB_ERR_DATA;
1356   else if ((token & GRUB_EHCI_STATUS_BUFERR) != 0)
1357     err = GRUB_USB_ERR_DATA;
1358   else if ((token & GRUB_EHCI_STATUS_MISSDMF) != 0)
1359     err = GRUB_USB_ERR_DATA;
1360
1361   return err;
1362 }
1363
1364 static grub_usb_err_t
1365 grub_ehci_parse_success (grub_usb_controller_t dev,
1366                          grub_usb_transfer_t transfer, grub_size_t * actual)
1367 {
1368   struct grub_ehci *e = dev->data;
1369   struct grub_ehci_transfer_controller_data *cdata =
1370     transfer->controller_data;
1371
1372   grub_dprintf ("ehci", "parse_success: info\n");
1373
1374   /* QH should be not active in this case, but it is not halted. */
1375   grub_ehci_pre_finish_transfer (transfer);
1376   grub_ehci_free_tds (e, cdata->td_first_virt, transfer, actual);
1377   grub_ehci_free_td (e, cdata->td_alt_virt);
1378   grub_free (cdata);
1379
1380   sync_all_caches (e);
1381
1382   return GRUB_USB_ERR_NONE;
1383 }
1384
1385
1386 static grub_usb_err_t
1387 grub_ehci_check_transfer (grub_usb_controller_t dev,
1388                           grub_usb_transfer_t transfer, grub_size_t * actual)
1389 {
1390   struct grub_ehci *e = dev->data;
1391   struct grub_ehci_transfer_controller_data *cdata =
1392     transfer->controller_data;
1393   grub_uint32_t token, token_ftd;
1394
1395   sync_all_caches (e);
1396
1397   grub_dprintf ("ehci",
1398                 "check_transfer: EHCI STATUS=%08x, cdata=%p, qh=%p\n",
1399                 grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS),
1400                 cdata, cdata->qh_virt);
1401   grub_dprintf ("ehci", "check_transfer: qh_hptr=%08x, ep_char=%08x\n",
1402                 grub_le_to_cpu32 (cdata->qh_virt->qh_hptr),
1403                 grub_le_to_cpu32 (cdata->qh_virt->ep_char));
1404   grub_dprintf ("ehci", "check_transfer: ep_cap=%08x, td_current=%08x\n",
1405                 grub_le_to_cpu32 (cdata->qh_virt->ep_cap),
1406                 grub_le_to_cpu32 (cdata->qh_virt->td_current));
1407   grub_dprintf ("ehci", "check_transfer: next_td=%08x, alt_next_td=%08x\n",
1408                 grub_le_to_cpu32 (cdata->qh_virt->td_overlay.next_td),
1409                 grub_le_to_cpu32 (cdata->qh_virt->td_overlay.alt_next_td));
1410   grub_dprintf ("ehci", "check_transfer: token=%08x, buffer[0]=%08x\n",
1411                 grub_le_to_cpu32 (cdata->qh_virt->td_overlay.token),
1412                 grub_le_to_cpu32 (cdata->qh_virt->td_overlay.buffer_page[0]));
1413
1414   /* Check if EHCI is running and AL is enabled */
1415   if ((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS)
1416        & GRUB_EHCI_ST_HC_HALTED) != 0)
1417     return grub_ehci_parse_notrun (dev, transfer, actual);
1418   if ((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS)
1419        & (GRUB_EHCI_ST_AS_STATUS | GRUB_EHCI_ST_PS_STATUS)) == 0)
1420     return grub_ehci_parse_notrun (dev, transfer, actual);
1421
1422   token = grub_le_to_cpu32 (cdata->qh_virt->td_overlay.token);
1423   /* If the transfer consist from only one TD, we should check */
1424   /* if the TD was really executed and deactivated - to prevent */
1425   /* false detection of transfer finish. */
1426   token_ftd = grub_le_to_cpu32 (cdata->td_first_virt->token);
1427
1428   /* Detect QH halted */
1429   if ((token & GRUB_EHCI_STATUS_HALTED) != 0)
1430     return grub_ehci_parse_halt (dev, transfer, actual);
1431
1432   /* Detect QH not active - QH is not active and no next TD */
1433   if (token && ((token & GRUB_EHCI_STATUS_ACTIVE) == 0)
1434         && ((token_ftd & GRUB_EHCI_STATUS_ACTIVE) == 0))
1435     {
1436       /* It could be finish at all or short packet condition */
1437       if ((grub_le_to_cpu32 (cdata->qh_virt->td_overlay.next_td)
1438            & GRUB_EHCI_TERMINATE) &&
1439           ((grub_le_to_cpu32 (cdata->qh_virt->td_current)
1440             & GRUB_EHCI_QHTDPTR_MASK) == cdata->td_last_phys))
1441         /* Normal finish */
1442         return grub_ehci_parse_success (dev, transfer, actual);
1443       else if ((token & GRUB_EHCI_TOTAL_MASK) != 0)
1444         /* Short packet condition */
1445         /* But currently we don't handle it - higher level will do it */
1446         return grub_ehci_parse_success (dev, transfer, actual);
1447     }
1448
1449   return GRUB_USB_ERR_WAIT;
1450 }
1451
1452 static grub_usb_err_t
1453 grub_ehci_cancel_transfer (grub_usb_controller_t dev,
1454                            grub_usb_transfer_t transfer)
1455 {
1456   struct grub_ehci *e = dev->data;
1457   struct grub_ehci_transfer_controller_data *cdata =
1458     transfer->controller_data;
1459   grub_size_t actual;
1460   int i;
1461   grub_uint64_t maxtime;
1462   grub_uint32_t qh_phys;
1463
1464   sync_all_caches (e);
1465
1466   grub_uint32_t interrupt =
1467     cdata->qh_virt->ep_cap & GRUB_EHCI_SMASK_MASK;
1468
1469   /* QH can be active and should be de-activated and halted */
1470
1471   grub_dprintf ("ehci", "cancel_transfer: begin\n");
1472
1473   /* First check if EHCI is running - if not, there is no problem */
1474   /* to cancel any transfer. Or, if transfer is asynchronous, check */
1475   /* if AL is enabled - if not, transfer can be canceled also. */
1476   if (((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS) &
1477       GRUB_EHCI_ST_HC_HALTED) != 0) ||
1478     (!interrupt && ((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS) &
1479       (GRUB_EHCI_ST_AS_STATUS | GRUB_EHCI_ST_PS_STATUS)) == 0)))
1480     {
1481       grub_ehci_pre_finish_transfer (transfer);
1482       grub_ehci_free_tds (e, cdata->td_first_virt, transfer, &actual);
1483       grub_ehci_free_td (e, cdata->td_alt_virt);
1484       grub_free (cdata);
1485       sync_all_caches (e);
1486       grub_dprintf ("ehci", "cancel_transfer: end - EHCI not running\n");
1487       return GRUB_USB_ERR_NONE;
1488     }
1489
1490   /* EHCI and (AL or SL) are running. What to do? */
1491   /* Try to Halt QH via de-scheduling QH. */
1492   /* Find index of previous QH */
1493   qh_phys = grub_dma_virt2phys(cdata->qh_virt, e->qh_chunk);
1494   for (i = 0; i < GRUB_EHCI_N_QH; i++)
1495     {
1496       if ((grub_le_to_cpu32(e->qh_virt[i].qh_hptr)
1497         & GRUB_EHCI_QHTDPTR_MASK) == qh_phys)
1498         break;
1499     }
1500   if (i == GRUB_EHCI_N_QH)
1501     {
1502       grub_printf ("%s: prev not found, queues are corrupt\n", __func__);
1503       return GRUB_USB_ERR_UNRECOVERABLE;
1504     }
1505   /* Unlink QH from AL */
1506   e->qh_virt[i].qh_hptr = cdata->qh_virt->qh_hptr;
1507
1508   sync_all_caches (e);
1509
1510   /* If this is an interrupt transfer, we just wait for the periodic
1511    * schedule to advance a few times and then assume that the EHCI
1512    * controller has read the updated QH. */
1513   if (cdata->qh_virt->ep_cap & GRUB_EHCI_SMASK_MASK)
1514     {
1515       grub_millisleep(20);
1516     }
1517   else
1518     {
1519       /* For the asynchronous schedule we use the advance doorbell to find
1520        * out when the EHCI controller has read the updated QH. */
1521
1522       /* Ring the doorbell */
1523       grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
1524                               GRUB_EHCI_CMD_AS_ADV_D
1525                               | grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
1526       /* Ensure command is written */
1527       grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND);
1528       /* Wait answer with timeout */
1529       maxtime = grub_get_time_ms () + 2;
1530       while (((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS)
1531                & GRUB_EHCI_ST_AS_ADVANCE) == 0)
1532              && (grub_get_time_ms () < maxtime));
1533
1534       /* We do not detect the timeout because if timeout occurs, it most
1535        * probably means something wrong with EHCI - maybe stopped etc. */
1536
1537       /* Shut up the doorbell */
1538       grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
1539                               ~GRUB_EHCI_CMD_AS_ADV_D
1540                               & grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
1541       grub_ehci_oper_write32 (e, GRUB_EHCI_STATUS,
1542                               GRUB_EHCI_ST_AS_ADVANCE
1543                               | grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS));
1544       /* Ensure command is written */
1545       grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS);
1546     }
1547
1548   /* Now is QH out of AL and we can do anything with it... */
1549   grub_ehci_pre_finish_transfer (transfer);
1550   grub_ehci_free_tds (e, cdata->td_first_virt, transfer, &actual);
1551   grub_ehci_free_td (e, cdata->td_alt_virt);
1552
1553   /* "Free" the QH - link it to itself */
1554   cdata->qh_virt->ep_char = 0;
1555   cdata->qh_virt->qh_hptr =
1556     grub_cpu_to_le32 ((grub_dma_virt2phys (cdata->qh_virt,
1557                                            e->qh_chunk)
1558                        & GRUB_EHCI_POINTER_MASK) | GRUB_EHCI_HPTR_TYPE_QH);
1559
1560   grub_free (cdata);
1561
1562   grub_dprintf ("ehci", "cancel_transfer: end\n");
1563
1564   sync_all_caches (e);
1565
1566   return GRUB_USB_ERR_NONE;
1567 }
1568
1569 static int
1570 grub_ehci_hubports (grub_usb_controller_t dev)
1571 {
1572   struct grub_ehci *e = (struct grub_ehci *) dev->data;
1573   grub_uint32_t portinfo;
1574
1575   portinfo = grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_SPARAMS)
1576     & GRUB_EHCI_SPARAMS_N_PORTS;
1577   grub_dprintf ("ehci", "root hub ports=%d\n", portinfo);
1578   return portinfo;
1579 }
1580
1581 static grub_usb_err_t
1582 grub_ehci_portstatus (grub_usb_controller_t dev,
1583                       unsigned int port, unsigned int enable)
1584 {
1585   struct grub_ehci *e = (struct grub_ehci *) dev->data;
1586   grub_uint64_t endtime;
1587
1588   grub_dprintf ("ehci", "portstatus: EHCI STATUS: %08x\n",
1589                 grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS));
1590   grub_dprintf ("ehci",
1591                 "portstatus: begin, iobase=%p, port=%d, status=0x%02x\n",
1592                 e->iobase, port, grub_ehci_port_read (e, port));
1593
1594   /* In any case we need to disable port:
1595    * - if enable==false - we should disable port
1596    * - if enable==true we will do the reset and the specification says
1597    *   PortEnable should be FALSE in such case */
1598   /* Disable the port and wait for it. */
1599   grub_ehci_port_resbits (e, port, GRUB_EHCI_PORT_ENABLED);
1600   endtime = grub_get_time_ms () + 1000;
1601   while (grub_ehci_port_read (e, port) & GRUB_EHCI_PORT_ENABLED)
1602     if (grub_get_time_ms () > endtime)
1603       return GRUB_USB_ERR_TIMEOUT;
1604
1605   if (!enable)                  /* We don't need reset port */
1606     {
1607       grub_dprintf ("ehci", "portstatus: Disabled.\n");
1608       grub_dprintf ("ehci", "portstatus: end, status=0x%02x\n",
1609                     grub_ehci_port_read (e, port));
1610       return GRUB_USB_ERR_NONE;
1611     }
1612
1613   grub_dprintf ("ehci", "portstatus: enable\n");
1614
1615   grub_boot_time ("Resetting port %d", port);
1616
1617   /* Now we will do reset - if HIGH speed device connected, it will
1618    * result in Enabled state, otherwise port remains disabled. */
1619   /* Set RESET bit for 50ms */
1620   grub_ehci_port_setbits (e, port, GRUB_EHCI_PORT_RESET);
1621   grub_millisleep (50);
1622
1623   /* Reset RESET bit and wait for the end of reset */
1624   grub_ehci_port_resbits (e, port, GRUB_EHCI_PORT_RESET);
1625   endtime = grub_get_time_ms () + 1000;
1626   while (grub_ehci_port_read (e, port) & GRUB_EHCI_PORT_RESET)
1627     if (grub_get_time_ms () > endtime)
1628       return GRUB_USB_ERR_TIMEOUT;
1629   grub_boot_time ("Port %d reset", port);
1630   /* Remember "we did the reset" - needed by detect_dev */
1631   e->reset |= (1 << port);
1632   /* Test if port enabled, i.e. HIGH speed device connected */
1633   if ((grub_ehci_port_read (e, port) & GRUB_EHCI_PORT_ENABLED) != 0)    /* yes! */
1634     {
1635       grub_dprintf ("ehci", "portstatus: Enabled!\n");
1636       /* "Reset recovery time" (USB spec.) */
1637       grub_millisleep (10);
1638     }
1639   else                          /* no... */
1640     {
1641       /* FULL speed device connected - change port ownership.
1642        * It results in disconnected state of this EHCI port. */
1643       grub_ehci_port_setbits (e, port, GRUB_EHCI_PORT_OWNER);
1644       return GRUB_USB_ERR_BADDEVICE;
1645     }
1646
1647   /* XXX: Fix it! There is possible problem - we can say to calling
1648    * function that we lost device if it is FULL speed onlu via
1649    * return value <> GRUB_ERR_NONE. It (maybe) displays also error
1650    * message on screen - but this situation is not error, it is normal
1651    * state! */
1652
1653   grub_dprintf ("ehci", "portstatus: end, status=0x%02x\n",
1654                 grub_ehci_port_read (e, port));
1655
1656   return GRUB_USB_ERR_NONE;
1657 }
1658
1659 static grub_usb_speed_t
1660 grub_ehci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
1661 {
1662   struct grub_ehci *e = (struct grub_ehci *) dev->data;
1663   grub_uint32_t status, line_state;
1664
1665   status = grub_ehci_port_read (e, port);
1666
1667   /* Connect Status Change bit - it detects change of connection */
1668   if (status & GRUB_EHCI_PORT_CONNECT_CH)
1669     {
1670       *changed = 1;
1671       /* Reset bit Connect Status Change */
1672       grub_ehci_port_setbits (e, port, GRUB_EHCI_PORT_CONNECT_CH);
1673     }
1674   else
1675     *changed = 0;
1676
1677   if (!(status & GRUB_EHCI_PORT_CONNECT))
1678     {                           /* We should reset related "reset" flag in not connected state */
1679       e->reset &= ~(1 << port);
1680       return GRUB_USB_SPEED_NONE;
1681     }
1682   /* Detected connected state, so we should return speed.
1683    * But we can detect only LOW speed device and only at connection
1684    * time when PortEnabled=FALSE. FULL / HIGH speed detection is made
1685    * later by EHCI-specific reset procedure.
1686    * Another thing - if detected speed is LOW at connection time,
1687    * we should change port ownership to companion controller.
1688    * So:
1689    * 1. If we detect connected and enabled and EHCI-owned port,
1690    * we can say it is HIGH speed.
1691    * 2. If we detect connected and not EHCI-owned port, we can say
1692    * NONE speed, because such devices are not handled by EHCI.
1693    * 3. If we detect connected, not enabled but reset port, we can say
1694    * NONE speed, because it means FULL device connected to port and
1695    * such devices are not handled by EHCI.
1696    * 4. If we detect connected, not enabled and not reset port, which
1697    * has line state != "K", we will say HIGH - it could be FULL or HIGH
1698    * device, we will see it later after end of EHCI-specific reset
1699    * procedure.
1700    * 5. If we detect connected, not enabled and not reset port, which
1701    * has line state == "K", we can say NONE speed, because LOW speed
1702    * device is connected and we should change port ownership. */
1703   if ((status & GRUB_EHCI_PORT_ENABLED) != 0)   /* Port already enabled, return high speed. */
1704     return GRUB_USB_SPEED_HIGH;
1705   if ((status & GRUB_EHCI_PORT_OWNER) != 0)     /* EHCI is not port owner */
1706     return GRUB_USB_SPEED_NONE; /* EHCI driver is ignoring this port. */
1707   if ((e->reset & (1 << port)) != 0)    /* Port reset was done = FULL speed */
1708     return GRUB_USB_SPEED_NONE; /* EHCI driver is ignoring this port. */
1709   else                          /* Port connected but not enabled - test port speed. */
1710     {
1711       line_state = status & GRUB_EHCI_PORT_LINE_STAT;
1712       if (line_state != GRUB_EHCI_PORT_LINE_LOWSP)
1713         return GRUB_USB_SPEED_HIGH;
1714       /* Detected LOW speed device, we should change
1715        * port ownership.
1716        * XXX: Fix it!: There should be test if related companion
1717        * controler is available ! And what to do if it does not exist ? */
1718       grub_ehci_port_setbits (e, port, GRUB_EHCI_PORT_OWNER);
1719       return GRUB_USB_SPEED_NONE;       /* Ignore this port */
1720       /* Note: Reset of PORT_OWNER bit is done by EHCI HW when
1721        * device is really disconnected from port.
1722        * Don't do PORT_OWNER bit reset by SW when not connected signal
1723        * is detected in port register ! */
1724     }
1725 }
1726
1727 static grub_err_t
1728 grub_ehci_restore_hw (void)
1729 {
1730   struct grub_ehci *e;
1731   grub_uint32_t n_ports;
1732   int i;
1733
1734   /* We should re-enable all EHCI HW similarly as on inithw */
1735   for (e = ehci; e; e = e->next)
1736     {
1737       /* Check if EHCI is halted and halt it if not */
1738       if (grub_ehci_halt (e) != GRUB_USB_ERR_NONE)
1739         grub_error (GRUB_ERR_TIMEOUT, "restore_hw: EHCI halt timeout");
1740
1741       /* Reset EHCI */
1742       if (grub_ehci_reset (e) != GRUB_USB_ERR_NONE)
1743         grub_error (GRUB_ERR_TIMEOUT, "restore_hw: EHCI reset timeout");
1744
1745       /* Setup some EHCI registers and enable EHCI */
1746       grub_ehci_oper_write32 (e, GRUB_EHCI_FL_BASE, e->framelist_phys);
1747       grub_ehci_oper_write32 (e, GRUB_EHCI_CUR_AL_ADDR,
1748                               grub_dma_virt2phys (&e->qh_virt[1],
1749                                                    e->qh_chunk));
1750       grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
1751                               GRUB_EHCI_CMD_RUNSTOP |
1752                               grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
1753
1754       /* Set ownership of root hub ports to EHCI */
1755       grub_ehci_oper_write32 (e, GRUB_EHCI_CONFIG_FLAG,
1756                               GRUB_EHCI_CF_EHCI_OWNER);
1757
1758       /* Enable asynchronous list */
1759       grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
1760                               GRUB_EHCI_CMD_AS_ENABL
1761                               | GRUB_EHCI_CMD_PS_ENABL
1762                               | grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
1763
1764       /* Now should be possible to power-up and enumerate ports etc. */
1765       if ((grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_SPARAMS)
1766            & GRUB_EHCI_SPARAMS_PPC) != 0)
1767         {                       /* EHCI has port powering control */
1768           /* Power on all ports */
1769           n_ports = grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_SPARAMS)
1770             & GRUB_EHCI_SPARAMS_N_PORTS;
1771           for (i = 0; i < (int) n_ports; i++)
1772             grub_ehci_oper_write32 (e, GRUB_EHCI_PORT_STAT_CMD + i * 4,
1773                                     GRUB_EHCI_PORT_POWER
1774                                     | grub_ehci_oper_read32 (e,
1775                                                              GRUB_EHCI_PORT_STAT_CMD
1776                                                              + i * 4));
1777         }
1778     }
1779
1780   return GRUB_ERR_NONE;
1781 }
1782
1783 static grub_err_t
1784 grub_ehci_fini_hw (int noreturn __attribute__ ((unused)))
1785 {
1786   struct grub_ehci *e;
1787
1788   /* We should disable all EHCI HW to prevent any DMA access etc. */
1789   for (e = ehci; e; e = e->next)
1790     {
1791       /* Disable both lists */
1792       grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
1793         ~(GRUB_EHCI_CMD_AS_ENABL | GRUB_EHCI_CMD_PS_ENABL)
1794         & grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
1795
1796       /* Check if EHCI is halted and halt it if not */
1797       grub_ehci_halt (e);
1798
1799       /* Reset EHCI */
1800       grub_ehci_reset (e);
1801     }
1802
1803   return GRUB_ERR_NONE;
1804 }
1805
1806 static struct grub_usb_controller_dev usb_controller = {
1807   .name = "ehci",
1808   .iterate = grub_ehci_iterate,
1809   .setup_transfer = grub_ehci_setup_transfer,
1810   .check_transfer = grub_ehci_check_transfer,
1811   .cancel_transfer = grub_ehci_cancel_transfer,
1812   .hubports = grub_ehci_hubports,
1813   .portstatus = grub_ehci_portstatus,
1814   .detect_dev = grub_ehci_detect_dev,
1815   /* estimated max. count of TDs for one bulk transfer */
1816   .max_bulk_tds = GRUB_EHCI_N_TD * 3 / 4 
1817 };
1818
1819 GRUB_MOD_INIT (ehci)
1820 {
1821   COMPILE_TIME_ASSERT (sizeof (struct grub_ehci_td) == 64);
1822   COMPILE_TIME_ASSERT (sizeof (struct grub_ehci_qh) == 96);
1823
1824   grub_stop_disk_firmware ();
1825
1826   grub_boot_time ("Initing EHCI hardware");
1827   grub_ehci_pci_scan ();
1828   grub_boot_time ("Registering EHCI driver");
1829   grub_usb_controller_dev_register (&usb_controller);
1830   grub_boot_time ("EHCI driver registered");
1831   grub_loader_register_preboot_hook (grub_ehci_fini_hw, grub_ehci_restore_hw,
1832                                      GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK);
1833 }
1834
1835 GRUB_MOD_FINI (ehci)
1836 {
1837   grub_ehci_fini_hw (0);
1838   grub_usb_controller_dev_unregister (&usb_controller);
1839 }