ehci.c 61 KB

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