boot.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
  4. *
  5. */
  6. #include <linux/delay.h>
  7. #include <linux/device.h>
  8. #include <linux/dma-direction.h>
  9. #include <linux/dma-mapping.h>
  10. #include <linux/firmware.h>
  11. #include <linux/interrupt.h>
  12. #include <linux/list.h>
  13. #include <linux/mhi.h>
  14. #include <linux/module.h>
  15. #include <linux/random.h>
  16. #include <linux/slab.h>
  17. #include <linux/wait.h>
  18. #include "internal.h"
  19. /* Setup RDDM vector table for RDDM transfer and program RXVEC */
  20. int mhi_rddm_prepare(struct mhi_controller *mhi_cntrl,
  21. struct image_info *img_info)
  22. {
  23. struct mhi_buf *mhi_buf = img_info->mhi_buf;
  24. struct bhi_vec_entry *bhi_vec = img_info->bhi_vec;
  25. void __iomem *base = mhi_cntrl->bhie;
  26. struct device *dev = &mhi_cntrl->mhi_dev->dev;
  27. u32 sequence_id;
  28. unsigned int i;
  29. int ret;
  30. for (i = 0; i < img_info->entries - 1; i++, mhi_buf++, bhi_vec++) {
  31. bhi_vec->dma_addr = cpu_to_le64(mhi_buf->dma_addr);
  32. bhi_vec->size = cpu_to_le64(mhi_buf->len);
  33. }
  34. dev_dbg(dev, "BHIe programming for RDDM\n");
  35. mhi_write_reg(mhi_cntrl, base, BHIE_RXVECADDR_HIGH_OFFS,
  36. upper_32_bits(mhi_buf->dma_addr));
  37. mhi_write_reg(mhi_cntrl, base, BHIE_RXVECADDR_LOW_OFFS,
  38. lower_32_bits(mhi_buf->dma_addr));
  39. mhi_write_reg(mhi_cntrl, base, BHIE_RXVECSIZE_OFFS, mhi_buf->len);
  40. sequence_id = MHI_RANDOM_U32_NONZERO(BHIE_RXVECSTATUS_SEQNUM_BMSK);
  41. ret = mhi_write_reg_field(mhi_cntrl, base, BHIE_RXVECDB_OFFS,
  42. BHIE_RXVECDB_SEQNUM_BMSK, sequence_id);
  43. if (ret) {
  44. dev_err(dev, "Failed to write sequence ID for BHIE_RXVECDB\n");
  45. return ret;
  46. }
  47. dev_dbg(dev, "Address: %p and len: 0x%zx sequence: %u\n",
  48. &mhi_buf->dma_addr, mhi_buf->len, sequence_id);
  49. return 0;
  50. }
  51. /* Collect RDDM buffer during kernel panic */
  52. static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl)
  53. {
  54. int ret;
  55. u32 rx_status;
  56. enum mhi_ee_type ee;
  57. const u32 delayus = 2000;
  58. u32 retry = (mhi_cntrl->timeout_ms * 1000) / delayus;
  59. const u32 rddm_timeout_us = 200000;
  60. int rddm_retry = rddm_timeout_us / delayus;
  61. void __iomem *base = mhi_cntrl->bhie;
  62. struct device *dev = &mhi_cntrl->mhi_dev->dev;
  63. dev_dbg(dev, "Entered with pm_state:%s dev_state:%s ee:%s\n",
  64. to_mhi_pm_state_str(mhi_cntrl->pm_state),
  65. mhi_state_str(mhi_cntrl->dev_state),
  66. TO_MHI_EXEC_STR(mhi_cntrl->ee));
  67. /*
  68. * This should only be executing during a kernel panic, we expect all
  69. * other cores to shutdown while we're collecting RDDM buffer. After
  70. * returning from this function, we expect the device to reset.
  71. *
  72. * Normaly, we read/write pm_state only after grabbing the
  73. * pm_lock, since we're in a panic, skipping it. Also there is no
  74. * gurantee that this state change would take effect since
  75. * we're setting it w/o grabbing pm_lock
  76. */
  77. mhi_cntrl->pm_state = MHI_PM_LD_ERR_FATAL_DETECT;
  78. /* update should take the effect immediately */
  79. smp_wmb();
  80. /*
  81. * Make sure device is not already in RDDM. In case the device asserts
  82. * and a kernel panic follows, device will already be in RDDM.
  83. * Do not trigger SYS ERR again and proceed with waiting for
  84. * image download completion.
  85. */
  86. ee = mhi_get_exec_env(mhi_cntrl);
  87. if (ee == MHI_EE_MAX)
  88. goto error_exit_rddm;
  89. if (ee != MHI_EE_RDDM) {
  90. dev_dbg(dev, "Trigger device into RDDM mode using SYS ERR\n");
  91. mhi_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR);
  92. dev_dbg(dev, "Waiting for device to enter RDDM\n");
  93. while (rddm_retry--) {
  94. ee = mhi_get_exec_env(mhi_cntrl);
  95. if (ee == MHI_EE_RDDM)
  96. break;
  97. udelay(delayus);
  98. }
  99. if (rddm_retry <= 0) {
  100. /* Hardware reset so force device to enter RDDM */
  101. dev_dbg(dev,
  102. "Did not enter RDDM, do a host req reset\n");
  103. mhi_soc_reset(mhi_cntrl);
  104. udelay(delayus);
  105. }
  106. ee = mhi_get_exec_env(mhi_cntrl);
  107. }
  108. dev_dbg(dev,
  109. "Waiting for RDDM image download via BHIe, current EE:%s\n",
  110. TO_MHI_EXEC_STR(ee));
  111. while (retry--) {
  112. ret = mhi_read_reg_field(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS,
  113. BHIE_RXVECSTATUS_STATUS_BMSK, &rx_status);
  114. if (ret)
  115. return -EIO;
  116. if (rx_status == BHIE_RXVECSTATUS_STATUS_XFER_COMPL)
  117. return 0;
  118. udelay(delayus);
  119. }
  120. ee = mhi_get_exec_env(mhi_cntrl);
  121. ret = mhi_read_reg(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, &rx_status);
  122. dev_err(dev, "RXVEC_STATUS: 0x%x\n", rx_status);
  123. error_exit_rddm:
  124. dev_err(dev, "RDDM transfer failed. Current EE: %s\n",
  125. TO_MHI_EXEC_STR(ee));
  126. return -EIO;
  127. }
  128. /* Download RDDM image from device */
  129. int mhi_download_rddm_image(struct mhi_controller *mhi_cntrl, bool in_panic)
  130. {
  131. void __iomem *base = mhi_cntrl->bhie;
  132. struct device *dev = &mhi_cntrl->mhi_dev->dev;
  133. u32 rx_status;
  134. if (in_panic)
  135. return __mhi_download_rddm_in_panic(mhi_cntrl);
  136. dev_dbg(dev, "Waiting for RDDM image download via BHIe\n");
  137. /* Wait for the image download to complete */
  138. wait_event_timeout(mhi_cntrl->state_event,
  139. mhi_read_reg_field(mhi_cntrl, base,
  140. BHIE_RXVECSTATUS_OFFS,
  141. BHIE_RXVECSTATUS_STATUS_BMSK,
  142. &rx_status) || rx_status,
  143. msecs_to_jiffies(mhi_cntrl->timeout_ms));
  144. return (rx_status == BHIE_RXVECSTATUS_STATUS_XFER_COMPL) ? 0 : -EIO;
  145. }
  146. EXPORT_SYMBOL_GPL(mhi_download_rddm_image);
  147. static int mhi_fw_load_bhie(struct mhi_controller *mhi_cntrl,
  148. const struct mhi_buf *mhi_buf)
  149. {
  150. void __iomem *base = mhi_cntrl->bhie;
  151. struct device *dev = &mhi_cntrl->mhi_dev->dev;
  152. rwlock_t *pm_lock = &mhi_cntrl->pm_lock;
  153. u32 tx_status, sequence_id;
  154. int ret;
  155. read_lock_bh(pm_lock);
  156. if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) {
  157. read_unlock_bh(pm_lock);
  158. return -EIO;
  159. }
  160. sequence_id = MHI_RANDOM_U32_NONZERO(BHIE_TXVECSTATUS_SEQNUM_BMSK);
  161. dev_dbg(dev, "Starting image download via BHIe. Sequence ID: %u\n",
  162. sequence_id);
  163. mhi_write_reg(mhi_cntrl, base, BHIE_TXVECADDR_HIGH_OFFS,
  164. upper_32_bits(mhi_buf->dma_addr));
  165. mhi_write_reg(mhi_cntrl, base, BHIE_TXVECADDR_LOW_OFFS,
  166. lower_32_bits(mhi_buf->dma_addr));
  167. mhi_write_reg(mhi_cntrl, base, BHIE_TXVECSIZE_OFFS, mhi_buf->len);
  168. ret = mhi_write_reg_field(mhi_cntrl, base, BHIE_TXVECDB_OFFS,
  169. BHIE_TXVECDB_SEQNUM_BMSK, sequence_id);
  170. read_unlock_bh(pm_lock);
  171. if (ret)
  172. return ret;
  173. /* Wait for the image download to complete */
  174. ret = wait_event_timeout(mhi_cntrl->state_event,
  175. MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state) ||
  176. mhi_read_reg_field(mhi_cntrl, base,
  177. BHIE_TXVECSTATUS_OFFS,
  178. BHIE_TXVECSTATUS_STATUS_BMSK,
  179. &tx_status) || tx_status,
  180. msecs_to_jiffies(mhi_cntrl->timeout_ms));
  181. if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state) ||
  182. tx_status != BHIE_TXVECSTATUS_STATUS_XFER_COMPL)
  183. return -EIO;
  184. return (!ret) ? -ETIMEDOUT : 0;
  185. }
  186. static int mhi_fw_load_bhi(struct mhi_controller *mhi_cntrl,
  187. dma_addr_t dma_addr,
  188. size_t size)
  189. {
  190. u32 tx_status, val, session_id;
  191. int i, ret;
  192. void __iomem *base = mhi_cntrl->bhi;
  193. rwlock_t *pm_lock = &mhi_cntrl->pm_lock;
  194. struct device *dev = &mhi_cntrl->mhi_dev->dev;
  195. struct {
  196. char *name;
  197. u32 offset;
  198. } error_reg[] = {
  199. { "ERROR_CODE", BHI_ERRCODE },
  200. { "ERROR_DBG1", BHI_ERRDBG1 },
  201. { "ERROR_DBG2", BHI_ERRDBG2 },
  202. { "ERROR_DBG3", BHI_ERRDBG3 },
  203. { NULL },
  204. };
  205. read_lock_bh(pm_lock);
  206. if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) {
  207. read_unlock_bh(pm_lock);
  208. goto invalid_pm_state;
  209. }
  210. session_id = MHI_RANDOM_U32_NONZERO(BHI_TXDB_SEQNUM_BMSK);
  211. dev_dbg(dev, "Starting image download via BHI. Session ID: %u\n",
  212. session_id);
  213. mhi_write_reg(mhi_cntrl, base, BHI_STATUS, 0);
  214. mhi_write_reg(mhi_cntrl, base, BHI_IMGADDR_HIGH,
  215. upper_32_bits(dma_addr));
  216. mhi_write_reg(mhi_cntrl, base, BHI_IMGADDR_LOW,
  217. lower_32_bits(dma_addr));
  218. mhi_write_reg(mhi_cntrl, base, BHI_IMGSIZE, size);
  219. mhi_write_reg(mhi_cntrl, base, BHI_IMGTXDB, session_id);
  220. read_unlock_bh(pm_lock);
  221. /* Wait for the image download to complete */
  222. ret = wait_event_timeout(mhi_cntrl->state_event,
  223. MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state) ||
  224. mhi_read_reg_field(mhi_cntrl, base, BHI_STATUS,
  225. BHI_STATUS_MASK, &tx_status) || tx_status,
  226. msecs_to_jiffies(mhi_cntrl->timeout_ms));
  227. if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state))
  228. goto invalid_pm_state;
  229. if (tx_status == BHI_STATUS_ERROR) {
  230. dev_err(dev, "Image transfer failed\n");
  231. read_lock_bh(pm_lock);
  232. if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) {
  233. for (i = 0; error_reg[i].name; i++) {
  234. ret = mhi_read_reg(mhi_cntrl, base,
  235. error_reg[i].offset, &val);
  236. if (ret)
  237. break;
  238. dev_err(dev, "Reg: %s value: 0x%x\n",
  239. error_reg[i].name, val);
  240. }
  241. }
  242. read_unlock_bh(pm_lock);
  243. goto invalid_pm_state;
  244. }
  245. return (!ret) ? -ETIMEDOUT : 0;
  246. invalid_pm_state:
  247. return -EIO;
  248. }
  249. void mhi_free_bhie_table(struct mhi_controller *mhi_cntrl,
  250. struct image_info *image_info)
  251. {
  252. int i;
  253. struct mhi_buf *mhi_buf = image_info->mhi_buf;
  254. for (i = 0; i < image_info->entries; i++, mhi_buf++)
  255. dma_free_coherent(mhi_cntrl->cntrl_dev, mhi_buf->len,
  256. mhi_buf->buf, mhi_buf->dma_addr);
  257. kfree(image_info->mhi_buf);
  258. kfree(image_info);
  259. }
  260. int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl,
  261. struct image_info **image_info,
  262. size_t alloc_size)
  263. {
  264. size_t seg_size = mhi_cntrl->seg_len;
  265. int segments = DIV_ROUND_UP(alloc_size, seg_size) + 1;
  266. int i;
  267. struct image_info *img_info;
  268. struct mhi_buf *mhi_buf;
  269. img_info = kzalloc(sizeof(*img_info), GFP_KERNEL);
  270. if (!img_info)
  271. return -ENOMEM;
  272. /* Allocate memory for entries */
  273. img_info->mhi_buf = kcalloc(segments, sizeof(*img_info->mhi_buf),
  274. GFP_KERNEL);
  275. if (!img_info->mhi_buf)
  276. goto error_alloc_mhi_buf;
  277. /* Allocate and populate vector table */
  278. mhi_buf = img_info->mhi_buf;
  279. for (i = 0; i < segments; i++, mhi_buf++) {
  280. size_t vec_size = seg_size;
  281. /* Vector table is the last entry */
  282. if (i == segments - 1)
  283. vec_size = sizeof(struct bhi_vec_entry) * i;
  284. mhi_buf->len = vec_size;
  285. mhi_buf->buf = dma_alloc_coherent(mhi_cntrl->cntrl_dev,
  286. vec_size, &mhi_buf->dma_addr,
  287. GFP_KERNEL);
  288. if (!mhi_buf->buf)
  289. goto error_alloc_segment;
  290. }
  291. img_info->bhi_vec = img_info->mhi_buf[segments - 1].buf;
  292. img_info->entries = segments;
  293. *image_info = img_info;
  294. return 0;
  295. error_alloc_segment:
  296. for (--i, --mhi_buf; i >= 0; i--, mhi_buf--)
  297. dma_free_coherent(mhi_cntrl->cntrl_dev, mhi_buf->len,
  298. mhi_buf->buf, mhi_buf->dma_addr);
  299. error_alloc_mhi_buf:
  300. kfree(img_info);
  301. return -ENOMEM;
  302. }
  303. static void mhi_firmware_copy(struct mhi_controller *mhi_cntrl,
  304. const u8 *buf, size_t remainder,
  305. struct image_info *img_info)
  306. {
  307. size_t to_cpy;
  308. struct mhi_buf *mhi_buf = img_info->mhi_buf;
  309. struct bhi_vec_entry *bhi_vec = img_info->bhi_vec;
  310. while (remainder) {
  311. to_cpy = min(remainder, mhi_buf->len);
  312. memcpy(mhi_buf->buf, buf, to_cpy);
  313. bhi_vec->dma_addr = cpu_to_le64(mhi_buf->dma_addr);
  314. bhi_vec->size = cpu_to_le64(to_cpy);
  315. buf += to_cpy;
  316. remainder -= to_cpy;
  317. bhi_vec++;
  318. mhi_buf++;
  319. }
  320. }
  321. void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
  322. {
  323. const struct firmware *firmware = NULL;
  324. struct device *dev = &mhi_cntrl->mhi_dev->dev;
  325. enum mhi_pm_state new_state;
  326. const char *fw_name;
  327. const u8 *fw_data;
  328. void *buf;
  329. dma_addr_t dma_addr;
  330. size_t size, fw_sz;
  331. int ret;
  332. if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) {
  333. dev_err(dev, "Device MHI is not in valid state\n");
  334. return;
  335. }
  336. /* save hardware info from BHI */
  337. ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_SERIALNU,
  338. &mhi_cntrl->serial_number);
  339. if (ret)
  340. dev_err(dev, "Could not capture serial number via BHI\n");
  341. /* wait for ready on pass through or any other execution environment */
  342. if (!MHI_FW_LOAD_CAPABLE(mhi_cntrl->ee))
  343. goto fw_load_ready_state;
  344. fw_name = (mhi_cntrl->ee == MHI_EE_EDL) ?
  345. mhi_cntrl->edl_image : mhi_cntrl->fw_image;
  346. /* check if the driver has already provided the firmware data */
  347. if (!fw_name && mhi_cntrl->fbc_download &&
  348. mhi_cntrl->fw_data && mhi_cntrl->fw_sz) {
  349. if (!mhi_cntrl->sbl_size) {
  350. dev_err(dev, "fw_data provided but no sbl_size\n");
  351. goto error_fw_load;
  352. }
  353. size = mhi_cntrl->sbl_size;
  354. fw_data = mhi_cntrl->fw_data;
  355. fw_sz = mhi_cntrl->fw_sz;
  356. goto skip_req_fw;
  357. }
  358. if (!fw_name || (mhi_cntrl->fbc_download && (!mhi_cntrl->sbl_size ||
  359. !mhi_cntrl->seg_len))) {
  360. dev_err(dev,
  361. "No firmware image defined or !sbl_size || !seg_len\n");
  362. goto error_fw_load;
  363. }
  364. ret = request_firmware(&firmware, fw_name, dev);
  365. if (ret) {
  366. dev_err(dev, "Error loading firmware: %d\n", ret);
  367. goto error_fw_load;
  368. }
  369. size = (mhi_cntrl->fbc_download) ? mhi_cntrl->sbl_size : firmware->size;
  370. /* SBL size provided is maximum size, not necessarily the image size */
  371. if (size > firmware->size)
  372. size = firmware->size;
  373. fw_data = firmware->data;
  374. fw_sz = firmware->size;
  375. skip_req_fw:
  376. buf = dma_alloc_coherent(mhi_cntrl->cntrl_dev, size, &dma_addr,
  377. GFP_KERNEL);
  378. if (!buf) {
  379. release_firmware(firmware);
  380. goto error_fw_load;
  381. }
  382. /* Download image using BHI */
  383. memcpy(buf, fw_data, size);
  384. ret = mhi_fw_load_bhi(mhi_cntrl, dma_addr, size);
  385. dma_free_coherent(mhi_cntrl->cntrl_dev, size, buf, dma_addr);
  386. /* Error or in EDL mode, we're done */
  387. if (ret) {
  388. dev_err(dev, "MHI did not load image over BHI, ret: %d\n", ret);
  389. release_firmware(firmware);
  390. goto error_fw_load;
  391. }
  392. /* Wait for ready since EDL image was loaded */
  393. if (fw_name && fw_name == mhi_cntrl->edl_image) {
  394. release_firmware(firmware);
  395. goto fw_load_ready_state;
  396. }
  397. write_lock_irq(&mhi_cntrl->pm_lock);
  398. mhi_cntrl->dev_state = MHI_STATE_RESET;
  399. write_unlock_irq(&mhi_cntrl->pm_lock);
  400. /*
  401. * If we're doing fbc, populate vector tables while
  402. * device transitioning into MHI READY state
  403. */
  404. if (mhi_cntrl->fbc_download) {
  405. ret = mhi_alloc_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image, fw_sz);
  406. if (ret) {
  407. release_firmware(firmware);
  408. goto error_fw_load;
  409. }
  410. /* Load the firmware into BHIE vec table */
  411. mhi_firmware_copy(mhi_cntrl, fw_data, fw_sz, mhi_cntrl->fbc_image);
  412. }
  413. release_firmware(firmware);
  414. fw_load_ready_state:
  415. /* Transitioning into MHI RESET->READY state */
  416. ret = mhi_ready_state_transition(mhi_cntrl);
  417. if (ret) {
  418. dev_err(dev, "MHI did not enter READY state\n");
  419. goto error_ready_state;
  420. }
  421. dev_info(dev, "Wait for device to enter SBL or Mission mode\n");
  422. return;
  423. error_ready_state:
  424. if (mhi_cntrl->fbc_download) {
  425. mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image);
  426. mhi_cntrl->fbc_image = NULL;
  427. }
  428. error_fw_load:
  429. write_lock_irq(&mhi_cntrl->pm_lock);
  430. new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_FW_DL_ERR);
  431. write_unlock_irq(&mhi_cntrl->pm_lock);
  432. if (new_state == MHI_PM_FW_DL_ERR)
  433. wake_up_all(&mhi_cntrl->state_event);
  434. }
  435. int mhi_download_amss_image(struct mhi_controller *mhi_cntrl)
  436. {
  437. struct image_info *image_info = mhi_cntrl->fbc_image;
  438. struct device *dev = &mhi_cntrl->mhi_dev->dev;
  439. enum mhi_pm_state new_state;
  440. int ret;
  441. if (!image_info)
  442. return -EIO;
  443. ret = mhi_fw_load_bhie(mhi_cntrl,
  444. /* Vector table is the last entry */
  445. &image_info->mhi_buf[image_info->entries - 1]);
  446. if (ret) {
  447. dev_err(dev, "MHI did not load AMSS, ret:%d\n", ret);
  448. write_lock_irq(&mhi_cntrl->pm_lock);
  449. new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_FW_DL_ERR);
  450. write_unlock_irq(&mhi_cntrl->pm_lock);
  451. if (new_state == MHI_PM_FW_DL_ERR)
  452. wake_up_all(&mhi_cntrl->state_event);
  453. }
  454. return ret;
  455. }