I2cBus.c 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492
  1. /** @file
  2. This file implements I2C IO Protocol which enables the user to manipulate a single
  3. I2C device independent of the host controller and I2C design.
  4. Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include "I2cDxe.h"
  8. //
  9. // EFI_DRIVER_BINDING_PROTOCOL instance
  10. //
  11. EFI_DRIVER_BINDING_PROTOCOL gI2cBusDriverBinding = {
  12. I2cBusDriverSupported,
  13. I2cBusDriverStart,
  14. I2cBusDriverStop,
  15. 0x10,
  16. NULL,
  17. NULL
  18. };
  19. //
  20. // Template for I2C Bus Child Device.
  21. //
  22. I2C_DEVICE_CONTEXT gI2cDeviceContextTemplate = {
  23. I2C_DEVICE_SIGNATURE,
  24. NULL,
  25. { // I2cIo Protocol
  26. I2cBusQueueRequest, // QueueRequest
  27. NULL, // DeviceGuid
  28. 0, // DeviceIndex
  29. 0, // HardwareRevision
  30. NULL // I2cControllerCapabilities
  31. },
  32. NULL, // DevicePath
  33. NULL, // I2cDevice
  34. NULL, // I2cBusContext
  35. };
  36. //
  37. // Template for controller device path node.
  38. //
  39. CONTROLLER_DEVICE_PATH gControllerDevicePathTemplate = {
  40. {
  41. HARDWARE_DEVICE_PATH,
  42. HW_CONTROLLER_DP,
  43. {
  44. (UINT8) (sizeof (CONTROLLER_DEVICE_PATH)),
  45. (UINT8) ((sizeof (CONTROLLER_DEVICE_PATH)) >> 8)
  46. }
  47. },
  48. 0
  49. };
  50. //
  51. // Template for vendor device path node.
  52. //
  53. VENDOR_DEVICE_PATH gVendorDevicePathTemplate = {
  54. {
  55. HARDWARE_DEVICE_PATH,
  56. HW_VENDOR_DP,
  57. {
  58. (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
  59. (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
  60. }
  61. },
  62. { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }}
  63. };
  64. //
  65. // Driver name table
  66. //
  67. GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mI2cBusDriverNameTable[] = {
  68. { "eng;en", (CHAR16 *) L"I2C Bus Driver" },
  69. { NULL , NULL }
  70. };
  71. //
  72. // EFI Component Name Protocol
  73. //
  74. GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gI2cBusComponentName = {
  75. (EFI_COMPONENT_NAME_GET_DRIVER_NAME) I2cBusComponentNameGetDriverName,
  76. (EFI_COMPONENT_NAME_GET_CONTROLLER_NAME) I2cBusComponentNameGetControllerName,
  77. "eng"
  78. };
  79. //
  80. // EFI Component Name 2 Protocol
  81. //
  82. GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gI2cBusComponentName2 = {
  83. I2cBusComponentNameGetDriverName,
  84. I2cBusComponentNameGetControllerName,
  85. "en"
  86. };
  87. /**
  88. Retrieves a Unicode string that is the user readable name of the driver.
  89. This function retrieves the user readable name of a driver in the form of a
  90. Unicode string. If the driver specified by This has a user readable name in
  91. the language specified by Language, then a pointer to the driver name is
  92. returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
  93. by This does not support the language specified by Language,
  94. then EFI_UNSUPPORTED is returned.
  95. @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
  96. EFI_COMPONENT_NAME_PROTOCOL instance.
  97. @param Language[in] A pointer to a Null-terminated ASCII string
  98. array indicating the language. This is the
  99. language of the driver name that the caller is
  100. requesting, and it must match one of the
  101. languages specified in SupportedLanguages. The
  102. number of languages supported by a driver is up
  103. to the driver writer. Language is specified
  104. in RFC 4646 or ISO 639-2 language code format.
  105. @param DriverName[out] A pointer to the Unicode string to return.
  106. This Unicode string is the name of the
  107. driver specified by This in the language
  108. specified by Language.
  109. @retval EFI_SUCCESS The Unicode string for the Driver specified by
  110. This and the language specified by Language was
  111. returned in DriverName.
  112. @retval EFI_INVALID_PARAMETER Language is NULL.
  113. @retval EFI_INVALID_PARAMETER DriverName is NULL.
  114. @retval EFI_UNSUPPORTED The driver specified by This does not support
  115. the language specified by Language.
  116. **/
  117. EFI_STATUS
  118. EFIAPI
  119. I2cBusComponentNameGetDriverName (
  120. IN EFI_COMPONENT_NAME2_PROTOCOL *This,
  121. IN CHAR8 *Language,
  122. OUT CHAR16 **DriverName
  123. )
  124. {
  125. return LookupUnicodeString2 (
  126. Language,
  127. This->SupportedLanguages,
  128. mI2cBusDriverNameTable,
  129. DriverName,
  130. (BOOLEAN)(This != &gI2cBusComponentName2)
  131. );
  132. }
  133. /**
  134. Retrieves a Unicode string that is the user readable name of the controller
  135. that is being managed by a driver.
  136. This function retrieves the user readable name of the controller specified by
  137. ControllerHandle and ChildHandle in the form of a Unicode string. If the
  138. driver specified by This has a user readable name in the language specified by
  139. Language, then a pointer to the controller name is returned in ControllerName,
  140. and EFI_SUCCESS is returned. If the driver specified by This is not currently
  141. managing the controller specified by ControllerHandle and ChildHandle,
  142. then EFI_UNSUPPORTED is returned. If the driver specified by This does not
  143. support the language specified by Language, then EFI_UNSUPPORTED is returned.
  144. @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
  145. EFI_COMPONENT_NAME_PROTOCOL instance.
  146. @param ControllerHandle[in] The handle of a controller that the driver
  147. specified by This is managing. This handle
  148. specifies the controller whose name is to be
  149. returned.
  150. @param ChildHandle[in] The handle of the child controller to retrieve
  151. the name of. This is an optional parameter that
  152. may be NULL. It will be NULL for device
  153. drivers. It will also be NULL for a bus drivers
  154. that wish to retrieve the name of the bus
  155. controller. It will not be NULL for a bus
  156. driver that wishes to retrieve the name of a
  157. child controller.
  158. @param Language[in] A pointer to a Null-terminated ASCII string
  159. array indicating the language. This is the
  160. language of the driver name that the caller is
  161. requesting, and it must match one of the
  162. languages specified in SupportedLanguages. The
  163. number of languages supported by a driver is up
  164. to the driver writer. Language is specified in
  165. RFC 4646 or ISO 639-2 language code format.
  166. @param ControllerName[out] A pointer to the Unicode string to return.
  167. This Unicode string is the name of the
  168. controller specified by ControllerHandle and
  169. ChildHandle in the language specified by
  170. Language from the point of view of the driver
  171. specified by This.
  172. @retval EFI_SUCCESS The Unicode string for the user readable name in
  173. the language specified by Language for the
  174. driver specified by This was returned in
  175. DriverName.
  176. @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
  177. @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
  178. EFI_HANDLE.
  179. @retval EFI_INVALID_PARAMETER Language is NULL.
  180. @retval EFI_INVALID_PARAMETER ControllerName is NULL.
  181. @retval EFI_UNSUPPORTED The driver specified by This is not currently
  182. managing the controller specified by
  183. ControllerHandle and ChildHandle.
  184. @retval EFI_UNSUPPORTED The driver specified by This does not support
  185. the language specified by Language.
  186. **/
  187. EFI_STATUS
  188. EFIAPI
  189. I2cBusComponentNameGetControllerName (
  190. IN EFI_COMPONENT_NAME2_PROTOCOL *This,
  191. IN EFI_HANDLE ControllerHandle,
  192. IN EFI_HANDLE ChildHandle OPTIONAL,
  193. IN CHAR8 *Language,
  194. OUT CHAR16 **ControllerName
  195. )
  196. {
  197. return EFI_UNSUPPORTED;
  198. }
  199. /**
  200. Check if the child of I2C controller has been created.
  201. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  202. @param[in] Controller I2C controller handle.
  203. @param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
  204. @param[in] RemainingHasControllerNode Indicate if RemainingDevicePath contains CONTROLLER_DEVICE_PATH.
  205. @param[in] RemainingControllerNumber Controller number in CONTROLLER_DEVICE_PATH.
  206. @retval EFI_SUCCESS The child of I2C controller is not created.
  207. @retval Others The child of I2C controller has been created or other errors happen.
  208. **/
  209. EFI_STATUS
  210. CheckRemainingDevicePath (
  211. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  212. IN EFI_HANDLE Controller,
  213. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
  214. IN BOOLEAN RemainingHasControllerNode,
  215. IN UINT32 RemainingControllerNumber
  216. )
  217. {
  218. EFI_STATUS Status;
  219. EFI_DEVICE_PATH_PROTOCOL *SystemDevicePath;
  220. EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
  221. UINTN EntryCount;
  222. UINTN Index;
  223. BOOLEAN SystemHasControllerNode;
  224. UINT32 SystemControllerNumber;
  225. SystemHasControllerNode = FALSE;
  226. SystemControllerNumber = 0;
  227. Status = gBS->OpenProtocolInformation (
  228. Controller,
  229. &gEfiI2cHostProtocolGuid,
  230. &OpenInfoBuffer,
  231. &EntryCount
  232. );
  233. if (EFI_ERROR (Status)) {
  234. return Status;
  235. }
  236. for (Index = 0; Index < EntryCount; Index++) {
  237. if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
  238. Status = gBS->OpenProtocol (
  239. OpenInfoBuffer[Index].ControllerHandle,
  240. &gEfiDevicePathProtocolGuid,
  241. (VOID **) &SystemDevicePath,
  242. This->DriverBindingHandle,
  243. Controller,
  244. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  245. );
  246. if (!EFI_ERROR (Status)) {
  247. //
  248. // Find vendor device path node and compare
  249. //
  250. while (!IsDevicePathEnd (SystemDevicePath)) {
  251. if ((DevicePathType (SystemDevicePath) == HARDWARE_DEVICE_PATH) &&
  252. (DevicePathSubType (SystemDevicePath) == HW_VENDOR_DP)) {
  253. //
  254. // Check if vendor device path is same between system device path and remaining device path
  255. //
  256. if (CompareMem (SystemDevicePath, RemainingDevicePath, sizeof (VENDOR_DEVICE_PATH)) == 0) {
  257. //
  258. // Get controller node appended after vendor node
  259. //
  260. SystemDevicePath = NextDevicePathNode (SystemDevicePath);
  261. if ((DevicePathType (SystemDevicePath) == HARDWARE_DEVICE_PATH) &&
  262. (DevicePathSubType (SystemDevicePath) == HW_CONTROLLER_DP)) {
  263. SystemHasControllerNode = TRUE;
  264. SystemControllerNumber = ((CONTROLLER_DEVICE_PATH *) SystemDevicePath)->ControllerNumber;
  265. } else {
  266. SystemHasControllerNode = FALSE;
  267. SystemControllerNumber = 0;
  268. }
  269. if (((SystemHasControllerNode) && (!RemainingHasControllerNode) && (SystemControllerNumber == 0)) ||
  270. ((!SystemHasControllerNode) && (RemainingHasControllerNode) && (RemainingControllerNumber == 0)) ||
  271. ((SystemHasControllerNode) && (RemainingHasControllerNode) && (SystemControllerNumber == RemainingControllerNumber)) ||
  272. ((!SystemHasControllerNode) && (!RemainingHasControllerNode))) {
  273. DEBUG ((EFI_D_ERROR, "This I2C device has been already started.\n"));
  274. Status = EFI_UNSUPPORTED;
  275. break;
  276. }
  277. }
  278. }
  279. SystemDevicePath = NextDevicePathNode (SystemDevicePath);
  280. }
  281. if (EFI_ERROR (Status)) {
  282. break;
  283. }
  284. }
  285. }
  286. }
  287. FreePool (OpenInfoBuffer);
  288. return Status;
  289. }
  290. /**
  291. Tests to see if this driver supports a given controller. If a child device is provided,
  292. it further tests to see if this driver supports creating a handle for the specified child device.
  293. This function checks to see if the driver specified by This supports the device specified by
  294. ControllerHandle. Drivers will typically use the device path attached to
  295. ControllerHandle and/or the services from the bus I/O abstraction attached to
  296. ControllerHandle to determine if the driver supports ControllerHandle. This function
  297. may be called many times during platform initialization. In order to reduce boot times, the tests
  298. performed by this function must be very small, and take as little time as possible to execute. This
  299. function must not change the state of any hardware devices, and this function must be aware that the
  300. device specified by ControllerHandle may already be managed by the same driver or a
  301. different driver. This function must match its calls to AllocatePages() with FreePages(),
  302. AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
  303. Since ControllerHandle may have been previously started by the same driver, if a protocol is
  304. already in the opened state, then it must not be closed with CloseProtocol(). This is required
  305. to guarantee the state of ControllerHandle is not modified by this function.
  306. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  307. @param[in] ControllerHandle The handle of the controller to test. This handle
  308. must support a protocol interface that supplies
  309. an I/O abstraction to the driver.
  310. @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
  311. parameter is ignored by device drivers, and is optional for bus
  312. drivers. For bus drivers, if this parameter is not NULL, then
  313. the bus driver must determine if the bus controller specified
  314. by ControllerHandle and the child controller specified
  315. by RemainingDevicePath are both supported by this
  316. bus driver.
  317. @retval EFI_SUCCESS The device specified by ControllerHandle and
  318. RemainingDevicePath is supported by the driver specified by This.
  319. @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
  320. RemainingDevicePath is already being managed by the driver
  321. specified by This.
  322. @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
  323. RemainingDevicePath is already being managed by a different
  324. driver or an application that requires exclusive access.
  325. Currently not implemented.
  326. @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
  327. RemainingDevicePath is not supported by the driver specified by This.
  328. **/
  329. EFI_STATUS
  330. EFIAPI
  331. I2cBusDriverSupported (
  332. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  333. IN EFI_HANDLE Controller,
  334. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  335. )
  336. {
  337. EFI_STATUS Status;
  338. EFI_I2C_ENUMERATE_PROTOCOL *I2cEnumerate;
  339. EFI_I2C_HOST_PROTOCOL *I2cHost;
  340. EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
  341. EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
  342. BOOLEAN RemainingHasControllerNode;
  343. UINT32 RemainingControllerNumber;
  344. RemainingHasControllerNode = FALSE;
  345. RemainingControllerNumber = 0;
  346. //
  347. // Determine if the I2c Enumerate Protocol is available
  348. //
  349. Status = gBS->OpenProtocol (
  350. Controller,
  351. &gEfiI2cEnumerateProtocolGuid,
  352. (VOID **) &I2cEnumerate,
  353. This->DriverBindingHandle,
  354. Controller,
  355. EFI_OPEN_PROTOCOL_BY_DRIVER
  356. );
  357. if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
  358. return Status;
  359. }
  360. if (!EFI_ERROR (Status)) {
  361. gBS->CloseProtocol (
  362. Controller,
  363. &gEfiI2cEnumerateProtocolGuid,
  364. This->DriverBindingHandle,
  365. Controller
  366. );
  367. }
  368. Status = gBS->OpenProtocol (
  369. Controller,
  370. &gEfiDevicePathProtocolGuid,
  371. (VOID **) &ParentDevicePath,
  372. This->DriverBindingHandle,
  373. Controller,
  374. EFI_OPEN_PROTOCOL_BY_DRIVER
  375. );
  376. if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
  377. return Status;
  378. }
  379. if (!EFI_ERROR (Status)) {
  380. gBS->CloseProtocol (
  381. Controller,
  382. &gEfiDevicePathProtocolGuid,
  383. This->DriverBindingHandle,
  384. Controller
  385. );
  386. }
  387. if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {
  388. //
  389. // Check if the first node of RemainingDevicePath is a hardware vendor device path
  390. //
  391. if ((DevicePathType (RemainingDevicePath) != HARDWARE_DEVICE_PATH) ||
  392. (DevicePathSubType (RemainingDevicePath) != HW_VENDOR_DP)) {
  393. return EFI_UNSUPPORTED;
  394. }
  395. //
  396. // Check if the second node of RemainingDevicePath is a controller node
  397. //
  398. DevPathNode = NextDevicePathNode (RemainingDevicePath);
  399. if (!IsDevicePathEnd (DevPathNode)) {
  400. if ((DevicePathType (DevPathNode) != HARDWARE_DEVICE_PATH) ||
  401. (DevicePathSubType (DevPathNode) != HW_CONTROLLER_DP)) {
  402. return EFI_UNSUPPORTED;
  403. } else {
  404. RemainingHasControllerNode = TRUE;
  405. RemainingControllerNumber = ((CONTROLLER_DEVICE_PATH *) DevPathNode)->ControllerNumber;
  406. }
  407. }
  408. }
  409. //
  410. // Determine if the I2C Host Protocol is available
  411. //
  412. Status = gBS->OpenProtocol (
  413. Controller,
  414. &gEfiI2cHostProtocolGuid,
  415. (VOID **) &I2cHost,
  416. This->DriverBindingHandle,
  417. Controller,
  418. EFI_OPEN_PROTOCOL_BY_DRIVER
  419. );
  420. if (!EFI_ERROR (Status)) {
  421. gBS->CloseProtocol (
  422. Controller,
  423. &gEfiI2cHostProtocolGuid,
  424. This->DriverBindingHandle,
  425. Controller
  426. );
  427. }
  428. if (Status == EFI_ALREADY_STARTED) {
  429. if ((RemainingDevicePath == NULL) ||
  430. ((RemainingDevicePath != NULL) && IsDevicePathEnd (RemainingDevicePath))) {
  431. //
  432. // If RemainingDevicePath is NULL or is the End of Device Path Node, return EFI_SUCCESS.
  433. //
  434. Status = EFI_SUCCESS;
  435. } else {
  436. //
  437. // Test if the child with the RemainingDevicePath has already been created.
  438. //
  439. Status = CheckRemainingDevicePath (
  440. This,
  441. Controller,
  442. RemainingDevicePath,
  443. RemainingHasControllerNode,
  444. RemainingControllerNumber
  445. );
  446. }
  447. }
  448. return Status;
  449. }
  450. /**
  451. Starts a device controller or a bus controller.
  452. The Start() function is designed to be invoked from the EFI boot service ConnectController().
  453. As a result, much of the error checking on the parameters to Start() has been moved into this
  454. common boot service. It is legal to call Start() from other locations,
  455. but the following calling restrictions must be followed or the system behavior will not be deterministic.
  456. 1. ControllerHandle must be a valid EFI_HANDLE.
  457. 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
  458. EFI_DEVICE_PATH_PROTOCOL.
  459. 3. Prior to calling Start(), the Supported() function for the driver specified by This must
  460. have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
  461. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  462. @param[in] ControllerHandle The handle of the controller to start. This handle
  463. must support a protocol interface that supplies
  464. an I/O abstraction to the driver.
  465. @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
  466. parameter is ignored by device drivers, and is optional for bus
  467. drivers. For a bus driver, if this parameter is NULL, then handles
  468. for all the children of Controller are created by this driver.
  469. If this parameter is not NULL and the first Device Path Node is
  470. not the End of Device Path Node, then only the handle for the
  471. child device specified by the first Device Path Node of
  472. RemainingDevicePath is created by this driver.
  473. If the first Device Path Node of RemainingDevicePath is
  474. the End of Device Path Node, no child handle is created by this
  475. driver.
  476. @retval EFI_SUCCESS The device was started.
  477. @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
  478. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
  479. @retval Others The driver failded to start the device.
  480. **/
  481. EFI_STATUS
  482. EFIAPI
  483. I2cBusDriverStart (
  484. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  485. IN EFI_HANDLE Controller,
  486. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  487. )
  488. {
  489. EFI_I2C_ENUMERATE_PROTOCOL *I2cEnumerate;
  490. EFI_I2C_HOST_PROTOCOL *I2cHost;
  491. I2C_BUS_CONTEXT *I2cBusContext;
  492. EFI_STATUS Status;
  493. EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
  494. I2cBusContext = NULL;
  495. ParentDevicePath = NULL;
  496. I2cEnumerate = NULL;
  497. I2cHost = NULL;
  498. //
  499. // Determine if the I2C controller is available
  500. //
  501. Status = gBS->OpenProtocol (
  502. Controller,
  503. &gEfiI2cHostProtocolGuid,
  504. (VOID**)&I2cHost,
  505. This->DriverBindingHandle,
  506. Controller,
  507. EFI_OPEN_PROTOCOL_BY_DRIVER
  508. );
  509. if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
  510. DEBUG ((EFI_D_ERROR, "I2cBus: open I2C host error, Status = %r\n", Status));
  511. return Status;
  512. }
  513. if (Status == EFI_ALREADY_STARTED) {
  514. Status = gBS->OpenProtocol (
  515. Controller,
  516. &gEfiCallerIdGuid,
  517. (VOID **) &I2cBusContext,
  518. This->DriverBindingHandle,
  519. Controller,
  520. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  521. );
  522. if (EFI_ERROR (Status)) {
  523. DEBUG ((EFI_D_ERROR, "I2cBus: open private protocol error, Status = %r.\n", Status));
  524. return Status;
  525. }
  526. }
  527. //
  528. // Get the I2C bus enumeration API
  529. //
  530. Status = gBS->OpenProtocol (
  531. Controller,
  532. &gEfiI2cEnumerateProtocolGuid,
  533. (VOID**)&I2cEnumerate,
  534. This->DriverBindingHandle,
  535. Controller,
  536. EFI_OPEN_PROTOCOL_BY_DRIVER
  537. );
  538. if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
  539. DEBUG ((EFI_D_ERROR, "I2cBus: open I2C enumerate error, Status = %r\n", Status));
  540. goto Error;
  541. }
  542. Status = gBS->OpenProtocol (
  543. Controller,
  544. &gEfiDevicePathProtocolGuid,
  545. (VOID **) &ParentDevicePath,
  546. This->DriverBindingHandle,
  547. Controller,
  548. EFI_OPEN_PROTOCOL_BY_DRIVER
  549. );
  550. if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
  551. DEBUG ((EFI_D_ERROR, "I2cBus: open device path error, Status = %r\n", Status));
  552. goto Error;
  553. }
  554. if ((RemainingDevicePath != NULL) && IsDevicePathEnd (RemainingDevicePath)) {
  555. //
  556. // If RemainingDevicePath is the End of Device Path Node,
  557. // don't create any child device and return EFI_SUCESS
  558. //
  559. return EFI_SUCCESS;
  560. }
  561. //
  562. // Allocate the buffer for I2C_BUS_CONTEXT if it is not allocated before.
  563. //
  564. if (I2cBusContext == NULL) {
  565. //
  566. // Allocate the I2C context structure for the current I2C controller
  567. //
  568. I2cBusContext = AllocateZeroPool (sizeof (I2C_BUS_CONTEXT));
  569. if (I2cBusContext == NULL) {
  570. DEBUG ((EFI_D_ERROR, "I2cBus: there is no enough memory to allocate.\n"));
  571. Status = EFI_OUT_OF_RESOURCES;
  572. goto Error;
  573. }
  574. /*
  575. +----------------+
  576. .->| I2C_BUS_CONTEXT|<----- This file Protocol (gEfiCallerIdGuid) installed on I2C Controller handle
  577. | +----------------+
  578. |
  579. | +----------------------------+
  580. | | I2C_DEVICE_CONTEXT |
  581. `--| |
  582. | |
  583. | I2C IO Protocol Structure | <----- I2C IO Protocol
  584. | |
  585. +----------------------------+
  586. */
  587. I2cBusContext->I2cHost = I2cHost;
  588. I2cBusContext->I2cEnumerate = I2cEnumerate;
  589. //
  590. // Parent controller used to create children
  591. //
  592. I2cBusContext->Controller = Controller;
  593. //
  594. // Parent controller device path used to create children device path
  595. //
  596. I2cBusContext->ParentDevicePath = ParentDevicePath;
  597. I2cBusContext->DriverBindingHandle = This->DriverBindingHandle;
  598. Status = gBS->InstallMultipleProtocolInterfaces (
  599. &Controller,
  600. &gEfiCallerIdGuid,
  601. I2cBusContext,
  602. NULL
  603. );
  604. if (EFI_ERROR (Status)) {
  605. DEBUG ((EFI_D_ERROR, "I2cBus: install private protocol error, Status = %r.\n", Status));
  606. goto Error;
  607. }
  608. }
  609. //
  610. // Start the driver
  611. //
  612. Status = RegisterI2cDevice (I2cBusContext, Controller, RemainingDevicePath);
  613. return Status;
  614. Error:
  615. if (EFI_ERROR (Status)) {
  616. DEBUG ((EFI_D_ERROR, "I2cBus: Start() function failed, Status = %r\n", Status));
  617. if (ParentDevicePath != NULL) {
  618. gBS->CloseProtocol (
  619. Controller,
  620. &gEfiDevicePathProtocolGuid,
  621. This->DriverBindingHandle,
  622. Controller
  623. );
  624. }
  625. if (I2cHost != NULL) {
  626. gBS->CloseProtocol (
  627. Controller,
  628. &gEfiI2cHostProtocolGuid,
  629. This->DriverBindingHandle,
  630. Controller
  631. );
  632. }
  633. if (I2cEnumerate != NULL) {
  634. gBS->CloseProtocol (
  635. Controller,
  636. &gEfiI2cEnumerateProtocolGuid,
  637. This->DriverBindingHandle,
  638. Controller
  639. );
  640. }
  641. if (I2cBusContext != NULL) {
  642. Status = gBS->UninstallMultipleProtocolInterfaces (
  643. &Controller,
  644. gEfiCallerIdGuid,
  645. I2cBusContext,
  646. NULL
  647. );
  648. FreePool (I2cBusContext);
  649. }
  650. }
  651. //
  652. // Return the operation status.
  653. //
  654. return Status;
  655. }
  656. /**
  657. Stops a device controller or a bus controller.
  658. The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
  659. As a result, much of the error checking on the parameters to Stop() has been moved
  660. into this common boot service. It is legal to call Stop() from other locations,
  661. but the following calling restrictions must be followed or the system behavior will not be deterministic.
  662. 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
  663. same driver's Start() function.
  664. 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
  665. EFI_HANDLE. In addition, all of these handles must have been created in this driver's
  666. Start() function, and the Start() function must have called OpenProtocol() on
  667. ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
  668. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  669. @param[in] ControllerHandle A handle to the device being stopped. The handle must
  670. support a bus specific I/O protocol for the driver
  671. to use to stop the device.
  672. @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
  673. @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
  674. if NumberOfChildren is 0.
  675. @retval EFI_SUCCESS The device was stopped.
  676. @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
  677. **/
  678. EFI_STATUS
  679. EFIAPI
  680. I2cBusDriverStop (
  681. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  682. IN EFI_HANDLE Controller,
  683. IN UINTN NumberOfChildren,
  684. IN EFI_HANDLE *ChildHandleBuffer
  685. )
  686. {
  687. I2C_BUS_CONTEXT *I2cBusContext;
  688. EFI_STATUS Status;
  689. BOOLEAN AllChildrenStopped;
  690. UINTN Index;
  691. if (NumberOfChildren == 0) {
  692. gBS->CloseProtocol (
  693. Controller,
  694. &gEfiDevicePathProtocolGuid,
  695. This->DriverBindingHandle,
  696. Controller
  697. );
  698. gBS->CloseProtocol (
  699. Controller,
  700. &gEfiI2cHostProtocolGuid,
  701. This->DriverBindingHandle,
  702. Controller
  703. );
  704. gBS->CloseProtocol (
  705. Controller,
  706. &gEfiI2cEnumerateProtocolGuid,
  707. This->DriverBindingHandle,
  708. Controller
  709. );
  710. Status = gBS->OpenProtocol (
  711. Controller,
  712. &gEfiCallerIdGuid,
  713. (VOID **) &I2cBusContext,
  714. This->DriverBindingHandle,
  715. Controller,
  716. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  717. );
  718. if (!EFI_ERROR (Status)) {
  719. gBS->UninstallMultipleProtocolInterfaces (
  720. Controller,
  721. &gEfiCallerIdGuid,
  722. I2cBusContext,
  723. NULL
  724. );
  725. //
  726. // No more child now, free bus context data.
  727. //
  728. FreePool (I2cBusContext);
  729. }
  730. return Status;
  731. }
  732. AllChildrenStopped = TRUE;
  733. for (Index = 0; Index < NumberOfChildren; Index++) {
  734. Status = UnRegisterI2cDevice (This, Controller, ChildHandleBuffer[Index]);
  735. if (EFI_ERROR (Status)) {
  736. AllChildrenStopped = FALSE;
  737. }
  738. }
  739. if (!AllChildrenStopped) {
  740. return EFI_DEVICE_ERROR;
  741. }
  742. return EFI_SUCCESS;
  743. }
  744. /**
  745. Enumerate the I2C bus
  746. This routine walks the platform specific data describing the
  747. I2C bus to create the I2C devices where driver GUIDs were
  748. specified.
  749. @param[in] I2cBusContext Address of an I2C_BUS_CONTEXT structure
  750. @param[in] Controller Handle to the controller
  751. @param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
  752. @retval EFI_SUCCESS The bus is successfully configured
  753. **/
  754. EFI_STATUS
  755. RegisterI2cDevice (
  756. IN I2C_BUS_CONTEXT *I2cBusContext,
  757. IN EFI_HANDLE Controller,
  758. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  759. )
  760. {
  761. I2C_DEVICE_CONTEXT *I2cDeviceContext;
  762. EFI_STATUS Status;
  763. CONST EFI_I2C_DEVICE *Device;
  764. CONST EFI_I2C_DEVICE *TempDevice;
  765. UINT32 RemainingPathDeviceIndex;
  766. EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
  767. BOOLEAN BuildControllerNode;
  768. UINTN Count;
  769. Status = EFI_SUCCESS;
  770. BuildControllerNode = TRUE;
  771. //
  772. // Default DeviceIndex
  773. //
  774. RemainingPathDeviceIndex = 0;
  775. //
  776. // Determine the controller number in Controller Node Device Path when RemainingDevicePath is not NULL.
  777. //
  778. if (RemainingDevicePath != NULL) {
  779. //
  780. // Check if there is a controller node appended after vendor node
  781. //
  782. DevPathNode = NextDevicePathNode (RemainingDevicePath);
  783. if ((DevicePathType (DevPathNode) == HARDWARE_DEVICE_PATH) &&
  784. (DevicePathSubType(DevPathNode) == HW_CONTROLLER_DP)) {
  785. //
  786. // RemainingDevicePath != NULL and RemainingDevicePath contains Controller Node,
  787. // add Controller Node to Device Path on child handle.
  788. //
  789. RemainingPathDeviceIndex = ((CONTROLLER_DEVICE_PATH *) DevPathNode)->ControllerNumber;
  790. } else {
  791. //
  792. // RemainingDevicePath != NULL and RemainingDevicePath does not contain Controller Node,
  793. // do not add controller node to Device Path on child handle.
  794. //
  795. BuildControllerNode = FALSE;
  796. }
  797. }
  798. //
  799. // Walk the list of I2C devices on this bus
  800. //
  801. Device = NULL;
  802. while (TRUE) {
  803. //
  804. // Get the next I2C device
  805. //
  806. Status = I2cBusContext->I2cEnumerate->Enumerate (I2cBusContext->I2cEnumerate, &Device);
  807. if (EFI_ERROR (Status) || Device == NULL) {
  808. if (RemainingDevicePath != NULL) {
  809. Status = EFI_NOT_FOUND;
  810. } else {
  811. Status = EFI_SUCCESS;
  812. }
  813. break;
  814. }
  815. //
  816. // Determine if the device info is valid
  817. //
  818. if ((Device->DeviceGuid == NULL) || (Device->SlaveAddressCount == 0) || (Device->SlaveAddressArray == NULL)) {
  819. DEBUG ((EFI_D_ERROR, "Invalid EFI_I2C_DEVICE reported by I2c Enumerate protocol.\n"));
  820. continue;
  821. }
  822. if (RemainingDevicePath == NULL) {
  823. if (Device->DeviceIndex == 0) {
  824. //
  825. // Determine if the controller node is necessary when controller number is zero in I2C device
  826. //
  827. TempDevice = NULL;
  828. Count = 0;
  829. while (TRUE) {
  830. //
  831. // Get the next I2C device
  832. //
  833. Status = I2cBusContext->I2cEnumerate->Enumerate (I2cBusContext->I2cEnumerate, &TempDevice);
  834. if (EFI_ERROR (Status) || TempDevice == NULL) {
  835. Status = EFI_SUCCESS;
  836. break;
  837. }
  838. if (CompareGuid (Device->DeviceGuid, TempDevice->DeviceGuid)) {
  839. Count++;
  840. }
  841. }
  842. if (Count == 1) {
  843. //
  844. // RemainingDevicePath == NULL and only DeviceIndex 0 is present on the I2C bus,
  845. // do not add Controller Node to Device Path on child handle.
  846. //
  847. BuildControllerNode = FALSE;
  848. }
  849. }
  850. } else {
  851. //
  852. // Find I2C device reported in Remaining Device Path
  853. //
  854. if ((!CompareGuid (&((VENDOR_DEVICE_PATH *)RemainingDevicePath)->Guid, Device->DeviceGuid)) ||
  855. (RemainingPathDeviceIndex != Device->DeviceIndex)) {
  856. continue;
  857. }
  858. }
  859. //
  860. // Build the device context for current I2C device.
  861. //
  862. I2cDeviceContext = NULL;
  863. I2cDeviceContext = AllocateCopyPool (sizeof (I2C_DEVICE_CONTEXT), &gI2cDeviceContextTemplate);
  864. ASSERT (I2cDeviceContext != NULL);
  865. if (I2cDeviceContext == NULL) {
  866. continue;
  867. }
  868. //
  869. // Initialize the specific device context
  870. //
  871. I2cDeviceContext->I2cBusContext = I2cBusContext;
  872. I2cDeviceContext->I2cDevice = Device;
  873. I2cDeviceContext->I2cIo.DeviceGuid = Device->DeviceGuid;
  874. I2cDeviceContext->I2cIo.DeviceIndex = Device->DeviceIndex;
  875. I2cDeviceContext->I2cIo.HardwareRevision = Device->HardwareRevision;
  876. I2cDeviceContext->I2cIo.I2cControllerCapabilities = I2cBusContext->I2cHost->I2cControllerCapabilities;
  877. //
  878. // Build the device path
  879. //
  880. Status = I2cBusDevicePathAppend (I2cDeviceContext, BuildControllerNode);
  881. ASSERT_EFI_ERROR (Status);
  882. if (EFI_ERROR (Status)) {
  883. continue;
  884. }
  885. //
  886. // Install the protocol
  887. //
  888. Status = gBS->InstallMultipleProtocolInterfaces (
  889. &I2cDeviceContext->Handle,
  890. &gEfiI2cIoProtocolGuid,
  891. &I2cDeviceContext->I2cIo,
  892. &gEfiDevicePathProtocolGuid,
  893. I2cDeviceContext->DevicePath,
  894. NULL );
  895. if (EFI_ERROR (Status)) {
  896. //
  897. // Free resources for this I2C device
  898. //
  899. ReleaseI2cDeviceContext (I2cDeviceContext);
  900. continue;
  901. }
  902. //
  903. // Create the child handle
  904. //
  905. Status = gBS->OpenProtocol (
  906. Controller,
  907. &gEfiI2cHostProtocolGuid,
  908. (VOID **) &I2cBusContext->I2cHost,
  909. I2cBusContext->DriverBindingHandle,
  910. I2cDeviceContext->Handle,
  911. EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
  912. );
  913. if (EFI_ERROR (Status)) {
  914. Status = gBS->UninstallMultipleProtocolInterfaces (
  915. I2cDeviceContext->Handle,
  916. &gEfiDevicePathProtocolGuid,
  917. I2cDeviceContext->DevicePath,
  918. &gEfiI2cIoProtocolGuid,
  919. &I2cDeviceContext->I2cIo,
  920. NULL
  921. );
  922. //
  923. // Free resources for this I2C device
  924. //
  925. ReleaseI2cDeviceContext (I2cDeviceContext);
  926. continue;
  927. }
  928. if (RemainingDevicePath != NULL) {
  929. //
  930. // Child has been created successfully
  931. //
  932. break;
  933. }
  934. }
  935. return Status;
  936. }
  937. /**
  938. Queue an I2C transaction for execution on the I2C device.
  939. This routine must be called at or below TPL_NOTIFY. For synchronous
  940. requests this routine must be called at or below TPL_CALLBACK.
  941. This routine queues an I2C transaction to the I2C controller for
  942. execution on the I2C bus.
  943. When Event is NULL, QueueRequest() operates synchronously and returns
  944. the I2C completion status as its return value.
  945. When Event is not NULL, QueueRequest() synchronously returns EFI_SUCCESS
  946. indicating that the asynchronous I2C transaction was queued. The values
  947. above are returned in the buffer pointed to by I2cStatus upon the
  948. completion of the I2C transaction when I2cStatus is not NULL.
  949. The upper layer driver writer provides the following to the platform
  950. vendor:
  951. 1. Vendor specific GUID for the I2C part
  952. 2. Guidance on proper construction of the slave address array when the
  953. I2C device uses more than one slave address. The I2C bus protocol
  954. uses the SlaveAddressIndex to perform relative to physical address
  955. translation to access the blocks of hardware within the I2C device.
  956. @param[in] This Pointer to an EFI_I2C_IO_PROTOCOL structure.
  957. @param[in] SlaveAddressIndex Index value into an array of slave addresses
  958. for the I2C device. The values in the array
  959. are specified by the board designer, with the
  960. third party I2C device driver writer providing
  961. the slave address order.
  962. For devices that have a single slave address,
  963. this value must be zero. If the I2C device
  964. uses more than one slave address then the
  965. third party (upper level) I2C driver writer
  966. needs to specify the order of entries in the
  967. slave address array.
  968. \ref ThirdPartyI2cDrivers "Third Party I2C
  969. Drivers" section in I2cMaster.h.
  970. @param[in] Event Event to signal for asynchronous transactions,
  971. NULL for synchronous transactions
  972. @param[in] RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET structure
  973. describing the I2C transaction
  974. @param[out] I2cStatus Optional buffer to receive the I2C transaction
  975. completion status
  976. @retval EFI_SUCCESS The asynchronous transaction was successfully
  977. queued when Event is not NULL.
  978. @retval EFI_SUCCESS The transaction completed successfully when
  979. Event is NULL.
  980. @retval EFI_BAD_BUFFER_SIZE The RequestPacket->LengthInBytes value is too
  981. large.
  982. @retval EFI_DEVICE_ERROR There was an I2C error (NACK) during the
  983. transaction.
  984. @retval EFI_INVALID_PARAMETER RequestPacket is NULL
  985. @retval EFI_NO_MAPPING The EFI_I2C_HOST_PROTOCOL could not set the
  986. bus configuration required to access this I2C
  987. device.
  988. @retval EFI_NO_RESPONSE The I2C device is not responding to the slave
  989. address selected by SlaveAddressIndex.
  990. EFI_DEVICE_ERROR will be returned if the
  991. controller cannot distinguish when the NACK
  992. occurred.
  993. @retval EFI_OUT_OF_RESOURCES Insufficient memory for I2C transaction
  994. @retval EFI_UNSUPPORTED The controller does not support the requested
  995. transaction.
  996. **/
  997. EFI_STATUS
  998. EFIAPI
  999. I2cBusQueueRequest (
  1000. IN CONST EFI_I2C_IO_PROTOCOL *This,
  1001. IN UINTN SlaveAddressIndex,
  1002. IN EFI_EVENT Event OPTIONAL,
  1003. IN EFI_I2C_REQUEST_PACKET *RequestPacket,
  1004. OUT EFI_STATUS *I2cStatus OPTIONAL
  1005. )
  1006. {
  1007. CONST EFI_I2C_DEVICE *I2cDevice;
  1008. I2C_BUS_CONTEXT *I2cBusContext;
  1009. CONST EFI_I2C_HOST_PROTOCOL *I2cHost;
  1010. I2C_DEVICE_CONTEXT *I2cDeviceContext;
  1011. EFI_STATUS Status;
  1012. if (RequestPacket == NULL) {
  1013. return EFI_INVALID_PARAMETER;
  1014. }
  1015. //
  1016. // Validate the I2C slave index
  1017. //
  1018. I2cDeviceContext = I2C_DEVICE_CONTEXT_FROM_PROTOCOL (This);
  1019. I2cDevice = I2cDeviceContext->I2cDevice;
  1020. if ( SlaveAddressIndex >= I2cDevice->SlaveAddressCount ) {
  1021. return EFI_INVALID_PARAMETER;
  1022. }
  1023. //
  1024. // Locate the I2c Host Protocol to queue request
  1025. //
  1026. I2cBusContext = I2cDeviceContext->I2cBusContext;
  1027. I2cHost = I2cBusContext->I2cHost;
  1028. //
  1029. // Start the I2C operation
  1030. //
  1031. Status = I2cHost->QueueRequest (
  1032. I2cHost,
  1033. I2cDevice->I2cBusConfiguration,
  1034. I2cDevice->SlaveAddressArray [SlaveAddressIndex],
  1035. Event,
  1036. RequestPacket,
  1037. I2cStatus
  1038. );
  1039. return Status;
  1040. }
  1041. /**
  1042. Release all the resources allocated for the I2C device.
  1043. This function releases all the resources allocated for the I2C device.
  1044. @param I2cDeviceContext The I2C child device involved for the operation.
  1045. **/
  1046. VOID
  1047. ReleaseI2cDeviceContext (
  1048. IN I2C_DEVICE_CONTEXT *I2cDeviceContext
  1049. )
  1050. {
  1051. if (I2cDeviceContext == NULL) {
  1052. return;
  1053. }
  1054. if (I2cDeviceContext->DevicePath != NULL) {
  1055. FreePool (I2cDeviceContext->DevicePath);
  1056. }
  1057. FreePool (I2cDeviceContext);
  1058. }
  1059. /**
  1060. Unregister an I2C device.
  1061. This function removes the protocols installed on the controller handle and
  1062. frees the resources allocated for the I2C device.
  1063. @param This The pointer to EFI_DRIVER_BINDING_PROTOCOL instance.
  1064. @param Controller The controller handle of the I2C device.
  1065. @param Handle The child handle.
  1066. @retval EFI_SUCCESS The I2C device is successfully unregistered.
  1067. @return Others Some error occurs when unregistering the I2C device.
  1068. **/
  1069. EFI_STATUS
  1070. UnRegisterI2cDevice (
  1071. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  1072. IN EFI_HANDLE Controller,
  1073. IN EFI_HANDLE Handle
  1074. )
  1075. {
  1076. EFI_STATUS Status;
  1077. I2C_DEVICE_CONTEXT *I2cDeviceContext;
  1078. EFI_I2C_IO_PROTOCOL *I2cIo;
  1079. EFI_I2C_HOST_PROTOCOL *I2cHost;
  1080. I2cIo = NULL;
  1081. Status = gBS->OpenProtocol (
  1082. Handle,
  1083. &gEfiI2cIoProtocolGuid,
  1084. (VOID **) &I2cIo,
  1085. This->DriverBindingHandle,
  1086. Controller,
  1087. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  1088. );
  1089. if (EFI_ERROR (Status)) {
  1090. return Status;
  1091. }
  1092. //
  1093. // Get I2c device context data.
  1094. //
  1095. I2cDeviceContext = I2C_DEVICE_CONTEXT_FROM_PROTOCOL (I2cIo);
  1096. //
  1097. // Close the child handle
  1098. //
  1099. gBS->CloseProtocol (
  1100. Controller,
  1101. &gEfiI2cHostProtocolGuid,
  1102. This->DriverBindingHandle,
  1103. Handle
  1104. );
  1105. //
  1106. // The I2C Bus driver installs the I2C Io and Device Path Protocol in the DriverBindingStart().
  1107. // Here should uninstall them.
  1108. //
  1109. Status = gBS->UninstallMultipleProtocolInterfaces (
  1110. Handle,
  1111. &gEfiDevicePathProtocolGuid,
  1112. I2cDeviceContext->DevicePath,
  1113. &gEfiI2cIoProtocolGuid,
  1114. &I2cDeviceContext->I2cIo,
  1115. NULL
  1116. );
  1117. if (EFI_ERROR (Status)) {
  1118. //
  1119. // Keep parent and child relationship
  1120. //
  1121. gBS->OpenProtocol (
  1122. Controller,
  1123. &gEfiI2cHostProtocolGuid,
  1124. (VOID **) &I2cHost,
  1125. This->DriverBindingHandle,
  1126. Handle,
  1127. EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
  1128. );
  1129. return Status;
  1130. }
  1131. //
  1132. // Free resources for this I2C device
  1133. //
  1134. ReleaseI2cDeviceContext (I2cDeviceContext);
  1135. return EFI_SUCCESS;
  1136. }
  1137. /**
  1138. Create a path for the I2C device
  1139. Append the I2C slave path to the I2C master controller path.
  1140. @param[in] I2cDeviceContext Address of an I2C_DEVICE_CONTEXT structure.
  1141. @param[in] BuildControllerNode Flag to build controller node in device path.
  1142. @retval EFI_SUCCESS The I2C device path is built successfully.
  1143. @return Others It is failed to built device path.
  1144. **/
  1145. EFI_STATUS
  1146. I2cBusDevicePathAppend (
  1147. IN I2C_DEVICE_CONTEXT *I2cDeviceContext,
  1148. IN BOOLEAN BuildControllerNode
  1149. )
  1150. {
  1151. EFI_DEVICE_PATH_PROTOCOL *PreviousDevicePath;
  1152. PreviousDevicePath = NULL;
  1153. //
  1154. // Build vendor device path
  1155. //
  1156. CopyMem (&gVendorDevicePathTemplate.Guid, I2cDeviceContext->I2cDevice->DeviceGuid, sizeof (EFI_GUID));
  1157. I2cDeviceContext->DevicePath = AppendDevicePathNode (
  1158. I2cDeviceContext->I2cBusContext->ParentDevicePath,
  1159. (EFI_DEVICE_PATH_PROTOCOL *) &gVendorDevicePathTemplate
  1160. );
  1161. ASSERT (I2cDeviceContext->DevicePath != NULL);
  1162. if (I2cDeviceContext->DevicePath == NULL) {
  1163. return EFI_OUT_OF_RESOURCES;
  1164. }
  1165. if ((BuildControllerNode) && (I2cDeviceContext->DevicePath != NULL)) {
  1166. //
  1167. // Build the final I2C device path with controller node
  1168. //
  1169. PreviousDevicePath = I2cDeviceContext->DevicePath;
  1170. gControllerDevicePathTemplate.ControllerNumber = I2cDeviceContext->I2cDevice->DeviceIndex;
  1171. I2cDeviceContext->DevicePath = AppendDevicePathNode (
  1172. I2cDeviceContext->DevicePath,
  1173. (EFI_DEVICE_PATH_PROTOCOL *) &gControllerDevicePathTemplate
  1174. );
  1175. gBS->FreePool (PreviousDevicePath);
  1176. ASSERT (I2cDeviceContext->DevicePath != NULL);
  1177. if (I2cDeviceContext->DevicePath == NULL) {
  1178. return EFI_OUT_OF_RESOURCES;
  1179. }
  1180. }
  1181. return EFI_SUCCESS;
  1182. }
  1183. /**
  1184. The user entry point for the I2C bus module. The user code starts with
  1185. this function.
  1186. @param[in] ImageHandle The firmware allocated handle for the EFI image.
  1187. @param[in] SystemTable A pointer to the EFI System Table.
  1188. @retval EFI_SUCCESS The entry point is executed successfully.
  1189. @retval other Some error occurs when executing this entry point.
  1190. **/
  1191. EFI_STATUS
  1192. EFIAPI
  1193. InitializeI2cBus(
  1194. IN EFI_HANDLE ImageHandle,
  1195. IN EFI_SYSTEM_TABLE *SystemTable
  1196. )
  1197. {
  1198. EFI_STATUS Status;
  1199. //
  1200. // Install driver model protocol(s).
  1201. //
  1202. Status = EfiLibInstallDriverBindingComponentName2 (
  1203. ImageHandle,
  1204. SystemTable,
  1205. &gI2cBusDriverBinding,
  1206. NULL,
  1207. &gI2cBusComponentName,
  1208. &gI2cBusComponentName2
  1209. );
  1210. ASSERT_EFI_ERROR (Status);
  1211. return Status;
  1212. }
  1213. /**
  1214. This is the unload handle for I2C bus module.
  1215. Disconnect the driver specified by ImageHandle from all the devices in the handle database.
  1216. Uninstall all the protocols installed in the driver entry point.
  1217. @param[in] ImageHandle The drivers' driver image.
  1218. @retval EFI_SUCCESS The image is unloaded.
  1219. @retval Others Failed to unload the image.
  1220. **/
  1221. EFI_STATUS
  1222. EFIAPI
  1223. I2cBusUnload (
  1224. IN EFI_HANDLE ImageHandle
  1225. )
  1226. {
  1227. EFI_STATUS Status;
  1228. EFI_HANDLE *DeviceHandleBuffer;
  1229. UINTN DeviceHandleCount;
  1230. UINTN Index;
  1231. EFI_COMPONENT_NAME_PROTOCOL *ComponentName;
  1232. EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2;
  1233. //
  1234. // Get the list of all I2C Controller handles in the handle database.
  1235. // If there is an error getting the list, then the unload
  1236. // operation fails.
  1237. //
  1238. Status = gBS->LocateHandleBuffer (
  1239. ByProtocol,
  1240. &gEfiI2cHostProtocolGuid,
  1241. NULL,
  1242. &DeviceHandleCount,
  1243. &DeviceHandleBuffer
  1244. );
  1245. if (!EFI_ERROR (Status)) {
  1246. //
  1247. // Disconnect the driver specified by Driver BindingHandle from all
  1248. // the devices in the handle database.
  1249. //
  1250. for (Index = 0; Index < DeviceHandleCount; Index++) {
  1251. Status = gBS->DisconnectController (
  1252. DeviceHandleBuffer[Index],
  1253. gI2cBusDriverBinding.DriverBindingHandle,
  1254. NULL
  1255. );
  1256. if (EFI_ERROR (Status)) {
  1257. goto Done;
  1258. }
  1259. }
  1260. }
  1261. //
  1262. // Uninstall all the protocols installed in the driver entry point
  1263. //
  1264. Status = gBS->UninstallMultipleProtocolInterfaces (
  1265. gI2cBusDriverBinding.DriverBindingHandle,
  1266. &gEfiDriverBindingProtocolGuid,
  1267. &gI2cBusDriverBinding,
  1268. NULL
  1269. );
  1270. ASSERT_EFI_ERROR (Status);
  1271. //
  1272. // Note we have to one by one uninstall the following protocols.
  1273. // It's because some of them are optionally installed based on
  1274. // the following PCD settings.
  1275. // gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable
  1276. // gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable
  1277. // gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable
  1278. // gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable
  1279. //
  1280. Status = gBS->HandleProtocol (
  1281. gI2cBusDriverBinding.DriverBindingHandle,
  1282. &gEfiComponentNameProtocolGuid,
  1283. (VOID **) &ComponentName
  1284. );
  1285. if (!EFI_ERROR (Status)) {
  1286. gBS->UninstallProtocolInterface (
  1287. gI2cBusDriverBinding.DriverBindingHandle,
  1288. &gEfiComponentNameProtocolGuid,
  1289. ComponentName
  1290. );
  1291. }
  1292. Status = gBS->HandleProtocol (
  1293. gI2cBusDriverBinding.DriverBindingHandle,
  1294. &gEfiComponentName2ProtocolGuid,
  1295. (VOID **) &ComponentName2
  1296. );
  1297. if (!EFI_ERROR (Status)) {
  1298. gBS->UninstallProtocolInterface (
  1299. gI2cBusDriverBinding.DriverBindingHandle,
  1300. &gEfiComponentName2ProtocolGuid,
  1301. ComponentName2
  1302. );
  1303. }
  1304. Status = EFI_SUCCESS;
  1305. Done:
  1306. //
  1307. // Free the buffer containing the list of handles from the handle database
  1308. //
  1309. if (DeviceHandleBuffer != NULL) {
  1310. gBS->FreePool (DeviceHandleBuffer);
  1311. }
  1312. return Status;
  1313. }