ieee1275.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. /* of.c - Access the Open Firmware client interface. */
  2. /*
  3. * GRUB -- GRand Unified Bootloader
  4. * Copyright (C) 2003,2004,2005,2007,2008,2009 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/ieee1275/ieee1275.h>
  20. #include <grub/types.h>
  21. #include <grub/misc.h>
  22. #define IEEE1275_PHANDLE_INVALID ((grub_ieee1275_cell_t) -1)
  23. #define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_cell_t) 0)
  24. #define IEEE1275_CELL_INVALID ((grub_ieee1275_cell_t) -1)
  25. int
  26. grub_ieee1275_finddevice (const char *name, grub_ieee1275_phandle_t *phandlep)
  27. {
  28. struct find_device_args
  29. {
  30. struct grub_ieee1275_common_hdr common;
  31. grub_ieee1275_cell_t device;
  32. grub_ieee1275_cell_t phandle;
  33. }
  34. args;
  35. INIT_IEEE1275_COMMON (&args.common, "finddevice", 1, 1);
  36. args.device = (grub_ieee1275_cell_t) name;
  37. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  38. return -1;
  39. *phandlep = args.phandle;
  40. if (args.phandle == IEEE1275_PHANDLE_INVALID)
  41. return -1;
  42. return 0;
  43. }
  44. int
  45. grub_ieee1275_get_property (grub_ieee1275_phandle_t phandle,
  46. const char *property, void *buf,
  47. grub_size_t size, grub_ssize_t *actual)
  48. {
  49. struct get_property_args
  50. {
  51. struct grub_ieee1275_common_hdr common;
  52. grub_ieee1275_cell_t phandle;
  53. grub_ieee1275_cell_t prop;
  54. grub_ieee1275_cell_t buf;
  55. grub_ieee1275_cell_t buflen;
  56. grub_ieee1275_cell_t size;
  57. }
  58. args;
  59. INIT_IEEE1275_COMMON (&args.common, "getprop", 4, 1);
  60. args.phandle = phandle;
  61. args.prop = (grub_ieee1275_cell_t) property;
  62. args.buf = (grub_ieee1275_cell_t) buf;
  63. args.buflen = (grub_ieee1275_cell_t) size;
  64. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  65. return -1;
  66. if (actual)
  67. *actual = (grub_ssize_t) args.size;
  68. if (args.size == IEEE1275_CELL_INVALID)
  69. return -1;
  70. return 0;
  71. }
  72. int
  73. grub_ieee1275_get_integer_property (grub_ieee1275_phandle_t phandle,
  74. const char *property, grub_uint32_t *buf,
  75. grub_size_t size, grub_ssize_t *actual)
  76. {
  77. int ret;
  78. ret = grub_ieee1275_get_property (phandle, property, (void *) buf, size, actual);
  79. #ifndef GRUB_CPU_WORDS_BIGENDIAN
  80. /* Integer properties are always in big endian. */
  81. if (ret == 0)
  82. {
  83. unsigned int i;
  84. size /= sizeof (grub_uint32_t);
  85. for (i = 0; i < size; i++)
  86. buf[i] = grub_be_to_cpu32 (buf[i]);
  87. }
  88. #endif
  89. return ret;
  90. }
  91. int
  92. grub_ieee1275_next_property (grub_ieee1275_phandle_t phandle, char *prev_prop,
  93. char *prop)
  94. {
  95. struct get_property_args
  96. {
  97. struct grub_ieee1275_common_hdr common;
  98. grub_ieee1275_cell_t phandle;
  99. grub_ieee1275_cell_t prev_prop;
  100. grub_ieee1275_cell_t next_prop;
  101. grub_ieee1275_cell_t flags;
  102. }
  103. args;
  104. INIT_IEEE1275_COMMON (&args.common, "nextprop", 3, 1);
  105. args.phandle = phandle;
  106. args.prev_prop = (grub_ieee1275_cell_t) prev_prop;
  107. args.next_prop = (grub_ieee1275_cell_t) prop;
  108. args.flags = (grub_ieee1275_cell_t) -1;
  109. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  110. return -1;
  111. return (int) args.flags;
  112. }
  113. int
  114. grub_ieee1275_get_property_length (grub_ieee1275_phandle_t phandle,
  115. const char *prop, grub_ssize_t *length)
  116. {
  117. struct get_property_args
  118. {
  119. struct grub_ieee1275_common_hdr common;
  120. grub_ieee1275_cell_t phandle;
  121. grub_ieee1275_cell_t prop;
  122. grub_ieee1275_cell_t length;
  123. }
  124. args;
  125. INIT_IEEE1275_COMMON (&args.common, "getproplen", 2, 1);
  126. args.phandle = phandle;
  127. args.prop = (grub_ieee1275_cell_t) prop;
  128. args.length = (grub_ieee1275_cell_t) -1;
  129. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  130. return -1;
  131. *length = args.length;
  132. if (args.length == IEEE1275_CELL_INVALID)
  133. return -1;
  134. return 0;
  135. }
  136. int
  137. grub_ieee1275_instance_to_package (grub_ieee1275_ihandle_t ihandle,
  138. grub_ieee1275_phandle_t *phandlep)
  139. {
  140. struct instance_to_package_args
  141. {
  142. struct grub_ieee1275_common_hdr common;
  143. grub_ieee1275_cell_t ihandle;
  144. grub_ieee1275_cell_t phandle;
  145. }
  146. args;
  147. INIT_IEEE1275_COMMON (&args.common, "instance-to-package", 1, 1);
  148. args.ihandle = ihandle;
  149. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  150. return -1;
  151. *phandlep = args.phandle;
  152. if (args.phandle == IEEE1275_PHANDLE_INVALID)
  153. return -1;
  154. return 0;
  155. }
  156. int
  157. grub_ieee1275_package_to_path (grub_ieee1275_phandle_t phandle,
  158. char *path, grub_size_t len,
  159. grub_ssize_t *actual)
  160. {
  161. struct instance_to_package_args
  162. {
  163. struct grub_ieee1275_common_hdr common;
  164. grub_ieee1275_cell_t phandle;
  165. grub_ieee1275_cell_t buf;
  166. grub_ieee1275_cell_t buflen;
  167. grub_ieee1275_cell_t actual;
  168. }
  169. args;
  170. INIT_IEEE1275_COMMON (&args.common, "package-to-path", 3, 1);
  171. args.phandle = phandle;
  172. args.buf = (grub_ieee1275_cell_t) path;
  173. args.buflen = (grub_ieee1275_cell_t) len;
  174. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  175. return -1;
  176. if (actual)
  177. *actual = args.actual;
  178. if (args.actual == IEEE1275_CELL_INVALID)
  179. return -1;
  180. return 0;
  181. }
  182. int
  183. grub_ieee1275_instance_to_path (grub_ieee1275_ihandle_t ihandle,
  184. char *path, grub_size_t len,
  185. grub_ssize_t *actual)
  186. {
  187. struct instance_to_path_args
  188. {
  189. struct grub_ieee1275_common_hdr common;
  190. grub_ieee1275_cell_t ihandle;
  191. grub_ieee1275_cell_t buf;
  192. grub_ieee1275_cell_t buflen;
  193. grub_ieee1275_cell_t actual;
  194. }
  195. args;
  196. INIT_IEEE1275_COMMON (&args.common, "instance-to-path", 3, 1);
  197. args.ihandle = ihandle;
  198. args.buf = (grub_ieee1275_cell_t) path;
  199. args.buflen = (grub_ieee1275_cell_t) len;
  200. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  201. return -1;
  202. if (actual)
  203. *actual = args.actual;
  204. if (args.actual == IEEE1275_CELL_INVALID)
  205. return -1;
  206. return 0;
  207. }
  208. int
  209. grub_ieee1275_write (grub_ieee1275_ihandle_t ihandle, const void *buffer,
  210. grub_size_t len, grub_ssize_t *actualp)
  211. {
  212. struct write_args
  213. {
  214. struct grub_ieee1275_common_hdr common;
  215. grub_ieee1275_cell_t ihandle;
  216. grub_ieee1275_cell_t buf;
  217. grub_ieee1275_cell_t len;
  218. grub_ieee1275_cell_t actual;
  219. }
  220. args;
  221. INIT_IEEE1275_COMMON (&args.common, "write", 3, 1);
  222. args.ihandle = ihandle;
  223. args.buf = (grub_ieee1275_cell_t) buffer;
  224. args.len = (grub_ieee1275_cell_t) len;
  225. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  226. return -1;
  227. if (actualp)
  228. *actualp = args.actual;
  229. return 0;
  230. }
  231. int
  232. grub_ieee1275_read (grub_ieee1275_ihandle_t ihandle, void *buffer,
  233. grub_size_t len, grub_ssize_t *actualp)
  234. {
  235. struct write_args
  236. {
  237. struct grub_ieee1275_common_hdr common;
  238. grub_ieee1275_cell_t ihandle;
  239. grub_ieee1275_cell_t buf;
  240. grub_ieee1275_cell_t len;
  241. grub_ieee1275_cell_t actual;
  242. }
  243. args;
  244. INIT_IEEE1275_COMMON (&args.common, "read", 3, 1);
  245. args.ihandle = ihandle;
  246. args.buf = (grub_ieee1275_cell_t) buffer;
  247. args.len = (grub_ieee1275_cell_t) len;
  248. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  249. return -1;
  250. if (actualp)
  251. *actualp = args.actual;
  252. return 0;
  253. }
  254. int
  255. grub_ieee1275_seek (grub_ieee1275_ihandle_t ihandle, grub_disk_addr_t pos,
  256. grub_ssize_t *result)
  257. {
  258. struct write_args
  259. {
  260. struct grub_ieee1275_common_hdr common;
  261. grub_ieee1275_cell_t ihandle;
  262. grub_ieee1275_cell_t pos_hi;
  263. grub_ieee1275_cell_t pos_lo;
  264. grub_ieee1275_cell_t result;
  265. }
  266. args;
  267. INIT_IEEE1275_COMMON (&args.common, "seek", 3, 1);
  268. args.ihandle = ihandle;
  269. /* To prevent stupid gcc warning. */
  270. #if GRUB_IEEE1275_CELL_SIZEOF >= 8
  271. args.pos_hi = 0;
  272. args.pos_lo = pos;
  273. #else
  274. args.pos_hi = (grub_ieee1275_cell_t) (pos >> (8 * GRUB_IEEE1275_CELL_SIZEOF));
  275. args.pos_lo = (grub_ieee1275_cell_t)
  276. (pos & ((1ULL << (8 * GRUB_IEEE1275_CELL_SIZEOF)) - 1));
  277. #endif
  278. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  279. return -1;
  280. if (result)
  281. *result = args.result;
  282. return 0;
  283. }
  284. int
  285. grub_ieee1275_peer (grub_ieee1275_phandle_t node,
  286. grub_ieee1275_phandle_t *result)
  287. {
  288. struct peer_args
  289. {
  290. struct grub_ieee1275_common_hdr common;
  291. grub_ieee1275_cell_t node;
  292. grub_ieee1275_cell_t result;
  293. }
  294. args;
  295. INIT_IEEE1275_COMMON (&args.common, "peer", 1, 1);
  296. args.node = node;
  297. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  298. return -1;
  299. *result = args.result;
  300. if (args.result == 0)
  301. return -1;
  302. return 0;
  303. }
  304. int
  305. grub_ieee1275_child (grub_ieee1275_phandle_t node,
  306. grub_ieee1275_phandle_t *result)
  307. {
  308. struct child_args
  309. {
  310. struct grub_ieee1275_common_hdr common;
  311. grub_ieee1275_cell_t node;
  312. grub_ieee1275_cell_t result;
  313. }
  314. args;
  315. INIT_IEEE1275_COMMON (&args.common, "child", 1, 1);
  316. args.node = node;
  317. args.result = IEEE1275_PHANDLE_INVALID;
  318. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  319. return -1;
  320. *result = args.result;
  321. if (args.result == 0)
  322. return -1;
  323. return 0;
  324. }
  325. int
  326. grub_ieee1275_parent (grub_ieee1275_phandle_t node,
  327. grub_ieee1275_phandle_t *result)
  328. {
  329. struct parent_args
  330. {
  331. struct grub_ieee1275_common_hdr common;
  332. grub_ieee1275_cell_t node;
  333. grub_ieee1275_cell_t result;
  334. }
  335. args;
  336. INIT_IEEE1275_COMMON (&args.common, "parent", 1, 1);
  337. args.node = node;
  338. args.result = IEEE1275_PHANDLE_INVALID;
  339. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  340. return -1;
  341. *result = args.result;
  342. return 0;
  343. }
  344. int
  345. grub_ieee1275_interpret (const char *command, grub_ieee1275_cell_t *catch)
  346. {
  347. struct enter_args
  348. {
  349. struct grub_ieee1275_common_hdr common;
  350. grub_ieee1275_cell_t command;
  351. grub_ieee1275_cell_t catch;
  352. }
  353. args;
  354. if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
  355. return -1;
  356. INIT_IEEE1275_COMMON (&args.common, "interpret", 1, 1);
  357. args.command = (grub_ieee1275_cell_t) command;
  358. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  359. return -1;
  360. if (catch)
  361. *catch = args.catch;
  362. return 0;
  363. }
  364. int
  365. grub_ieee1275_enter (void)
  366. {
  367. struct enter_args
  368. {
  369. struct grub_ieee1275_common_hdr common;
  370. }
  371. args;
  372. INIT_IEEE1275_COMMON (&args.common, "enter", 0, 0);
  373. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  374. return -1;
  375. return 0;
  376. }
  377. void
  378. grub_ieee1275_exit (void)
  379. {
  380. struct exit_args
  381. {
  382. struct grub_ieee1275_common_hdr common;
  383. }
  384. args;
  385. INIT_IEEE1275_COMMON (&args.common, "exit", 0, 0);
  386. IEEE1275_CALL_ENTRY_FN (&args);
  387. for (;;) ;
  388. }
  389. int
  390. grub_ieee1275_open (const char *path, grub_ieee1275_ihandle_t *result)
  391. {
  392. struct open_args
  393. {
  394. struct grub_ieee1275_common_hdr common;
  395. grub_ieee1275_cell_t path;
  396. grub_ieee1275_cell_t result;
  397. }
  398. args;
  399. INIT_IEEE1275_COMMON (&args.common, "open", 1, 1);
  400. args.path = (grub_ieee1275_cell_t) path;
  401. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  402. return -1;
  403. *result = args.result;
  404. if (args.result == IEEE1275_IHANDLE_INVALID)
  405. return -1;
  406. return 0;
  407. }
  408. int
  409. grub_ieee1275_close (grub_ieee1275_ihandle_t ihandle)
  410. {
  411. struct close_args
  412. {
  413. struct grub_ieee1275_common_hdr common;
  414. grub_ieee1275_cell_t ihandle;
  415. }
  416. args;
  417. INIT_IEEE1275_COMMON (&args.common, "close", 1, 0);
  418. args.ihandle = ihandle;
  419. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  420. return -1;
  421. return 0;
  422. }
  423. int
  424. grub_ieee1275_decode_unit4 (grub_ieee1275_ihandle_t ihandle,
  425. void *addr, grub_size_t size,
  426. grub_uint32_t *phy_lo, grub_uint32_t *phy_hi,
  427. grub_uint32_t *lun_lo, grub_uint32_t *lun_hi)
  428. {
  429. struct decode_args
  430. {
  431. struct grub_ieee1275_common_hdr common;
  432. grub_ieee1275_cell_t method;
  433. grub_ieee1275_cell_t ihandle;
  434. grub_ieee1275_cell_t size;
  435. grub_ieee1275_cell_t addr;
  436. grub_ieee1275_cell_t catch_result;
  437. grub_ieee1275_cell_t tgt_h;
  438. grub_ieee1275_cell_t tgt_l;
  439. grub_ieee1275_cell_t lun_h;
  440. grub_ieee1275_cell_t lun_l;
  441. }
  442. args;
  443. INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 5);
  444. args.method = (grub_ieee1275_cell_t) "decode-unit";
  445. args.ihandle = ihandle;
  446. args.size = size;
  447. args.addr = (grub_ieee1275_cell_t) addr;
  448. args.catch_result = 1;
  449. if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result))
  450. {
  451. grub_error (GRUB_ERR_OUT_OF_RANGE, "decode-unit failed\n");
  452. return -1;
  453. }
  454. *phy_lo = args.tgt_l;
  455. *phy_hi = args.tgt_h;
  456. *lun_lo = args.lun_l;
  457. *lun_hi = args.lun_h;
  458. return 0;
  459. }
  460. char *
  461. grub_ieee1275_encode_uint4 (grub_ieee1275_ihandle_t ihandle,
  462. grub_uint32_t phy_lo, grub_uint32_t phy_hi,
  463. grub_uint32_t lun_lo, grub_uint32_t lun_hi,
  464. grub_size_t *size)
  465. {
  466. char *addr;
  467. struct encode_args
  468. {
  469. struct grub_ieee1275_common_hdr common;
  470. grub_ieee1275_cell_t method;
  471. grub_ieee1275_cell_t ihandle;
  472. grub_ieee1275_cell_t tgt_h;
  473. grub_ieee1275_cell_t tgt_l;
  474. grub_ieee1275_cell_t lun_h;
  475. grub_ieee1275_cell_t lun_l;
  476. grub_ieee1275_cell_t catch_result;
  477. grub_ieee1275_cell_t size;
  478. grub_ieee1275_cell_t addr;
  479. }
  480. args;
  481. INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 3);
  482. args.method = (grub_ieee1275_cell_t) "encode-unit";
  483. args.ihandle = ihandle;
  484. args.tgt_l = phy_lo;
  485. args.tgt_h = phy_hi;
  486. args.lun_l = lun_lo;
  487. args.lun_h = lun_hi;
  488. args.catch_result = 1;
  489. if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result))
  490. {
  491. grub_error (GRUB_ERR_OUT_OF_RANGE, "encode-unit failed\n");
  492. return 0;
  493. }
  494. addr = (void *)args.addr;
  495. *size = args.size;
  496. addr = grub_strdup ((char *)args.addr);
  497. return addr;
  498. }
  499. int
  500. grub_ieee1275_claim (grub_addr_t addr, grub_size_t size, unsigned int align,
  501. grub_addr_t *result)
  502. {
  503. struct claim_args
  504. {
  505. struct grub_ieee1275_common_hdr common;
  506. grub_ieee1275_cell_t addr;
  507. grub_ieee1275_cell_t size;
  508. grub_ieee1275_cell_t align;
  509. grub_ieee1275_cell_t base;
  510. }
  511. args;
  512. INIT_IEEE1275_COMMON (&args.common, "claim", 3, 1);
  513. args.addr = (grub_ieee1275_cell_t) addr;
  514. args.size = (grub_ieee1275_cell_t) size;
  515. args.align = (grub_ieee1275_cell_t) align;
  516. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  517. return -1;
  518. if (result)
  519. *result = args.base;
  520. if (args.base == IEEE1275_CELL_INVALID)
  521. return -1;
  522. return 0;
  523. }
  524. int
  525. grub_ieee1275_release (grub_addr_t addr, grub_size_t size)
  526. {
  527. struct release_args
  528. {
  529. struct grub_ieee1275_common_hdr common;
  530. grub_ieee1275_cell_t addr;
  531. grub_ieee1275_cell_t size;
  532. }
  533. args;
  534. INIT_IEEE1275_COMMON (&args.common, "release", 2, 0);
  535. args.addr = addr;
  536. args.size = size;
  537. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  538. return -1;
  539. return 0;
  540. }
  541. int
  542. grub_ieee1275_set_property (grub_ieee1275_phandle_t phandle,
  543. const char *propname, const void *buf,
  544. grub_size_t size, grub_ssize_t *actual)
  545. {
  546. struct set_property_args
  547. {
  548. struct grub_ieee1275_common_hdr common;
  549. grub_ieee1275_cell_t phandle;
  550. grub_ieee1275_cell_t propname;
  551. grub_ieee1275_cell_t buf;
  552. grub_ieee1275_cell_t size;
  553. grub_ieee1275_cell_t actual;
  554. }
  555. args;
  556. INIT_IEEE1275_COMMON (&args.common, "setprop", 4, 1);
  557. args.size = (grub_ieee1275_cell_t) size;
  558. args.buf = (grub_ieee1275_cell_t) buf;
  559. args.propname = (grub_ieee1275_cell_t) propname;
  560. args.phandle = (grub_ieee1275_cell_t) phandle;
  561. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  562. return -1;
  563. *actual = args.actual;
  564. if ((args.actual == IEEE1275_CELL_INVALID) || (args.actual != args.size))
  565. return -1;
  566. return 0;
  567. }
  568. int
  569. grub_ieee1275_set_color (grub_ieee1275_ihandle_t ihandle,
  570. int index, int r, int g, int b)
  571. {
  572. struct set_color_args
  573. {
  574. struct grub_ieee1275_common_hdr common;
  575. grub_ieee1275_cell_t method;
  576. grub_ieee1275_cell_t ihandle;
  577. grub_ieee1275_cell_t index;
  578. grub_ieee1275_cell_t b;
  579. grub_ieee1275_cell_t g;
  580. grub_ieee1275_cell_t r;
  581. grub_ieee1275_cell_t catch_result;
  582. }
  583. args;
  584. INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1);
  585. args.method = (grub_ieee1275_cell_t) "color!";
  586. args.ihandle = ihandle;
  587. args.index = index;
  588. args.r = r;
  589. args.g = g;
  590. args.b = b;
  591. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  592. return -1;
  593. return args.catch_result;
  594. }
  595. int
  596. grub_ieee1275_milliseconds (grub_uint32_t *msecs)
  597. {
  598. struct milliseconds_args
  599. {
  600. struct grub_ieee1275_common_hdr common;
  601. grub_ieee1275_cell_t msecs;
  602. }
  603. args;
  604. INIT_IEEE1275_COMMON (&args.common, "milliseconds", 0, 1);
  605. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  606. return -1;
  607. *msecs = args.msecs;
  608. return 0;
  609. }
  610. int
  611. grub_ieee1275_set_address (grub_ieee1275_ihandle_t ihandle,
  612. grub_uint32_t target, grub_uint32_t lun)
  613. {
  614. struct set_address
  615. {
  616. struct grub_ieee1275_common_hdr common;
  617. grub_ieee1275_cell_t method;
  618. grub_ieee1275_cell_t ihandle;
  619. grub_ieee1275_cell_t tgt;
  620. grub_ieee1275_cell_t lun;
  621. grub_ieee1275_cell_t catch_result;
  622. }
  623. args;
  624. INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 1);
  625. /*
  626. * IEEE 1275-1994 Standard for Boot (Initialization Configuration)
  627. * Firmware: Core Requirements and Practices
  628. * E.3.2.2 Bus-specific methods for bus nodes
  629. *
  630. * A package implementing the scsi-2 device type shall implement the
  631. * following bus-specific method:
  632. *
  633. * set-address ( unit# target# -- )
  634. * Sets the SCSI target number (0x0..0xf) and unit number (0..7) to which
  635. * subsequent commands apply.
  636. */
  637. args.method = (grub_ieee1275_cell_t) "set-address";
  638. args.ihandle = ihandle;
  639. args.tgt = target;
  640. args.lun = lun;
  641. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  642. return -1;
  643. return args.catch_result;
  644. }
  645. int
  646. grub_ieee1275_no_data_command (grub_ieee1275_ihandle_t ihandle,
  647. const void *cmd_addr, grub_ssize_t *result)
  648. {
  649. struct set_address
  650. {
  651. struct grub_ieee1275_common_hdr common;
  652. grub_ieee1275_cell_t method;
  653. grub_ieee1275_cell_t ihandle;
  654. grub_ieee1275_cell_t cmd_addr;
  655. grub_ieee1275_cell_t error;
  656. grub_ieee1275_cell_t catch_result;
  657. }
  658. args;
  659. INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2);
  660. /*
  661. * IEEE 1275-1994 Standard for Boot (Initialization Configuration)
  662. * Firmware: Core Requirements and Practices
  663. *
  664. * E.3.2.2 Bus-specific methods for bus nodes
  665. *
  666. * A package implementing the scsi-2 device type shall implement the
  667. * following bus-specific method:
  668. *
  669. * no-data-command ( cmd-addr -- error? )
  670. * Executes a simple SCSI command, automatically retrying under
  671. * certain conditions. cmd-addr is the address of a 6-byte command buffer
  672. * containing an SCSI command that does not have a data transfer phase.
  673. * Executes the command, retrying indefinitely with the same retry criteria
  674. * as retry-command.
  675. *
  676. * error? is nonzero if an error occurred, zero otherwise.
  677. * NOTE no-data-command is a convenience function. It provides
  678. * no capabilities that are not present in retry-command, but for
  679. * those commands that meet its restrictions, it is easier to use.
  680. */
  681. args.method = (grub_ieee1275_cell_t) "no-data-command";
  682. args.ihandle = ihandle;
  683. args.cmd_addr = (grub_ieee1275_cell_t) cmd_addr;
  684. if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
  685. return -1;
  686. if (result)
  687. *result = args.error;
  688. return args.catch_result;
  689. }
  690. int
  691. grub_ieee1275_get_block_size (grub_ieee1275_ihandle_t ihandle)
  692. {
  693. struct size_args_ieee1275
  694. {
  695. struct grub_ieee1275_common_hdr common;
  696. grub_ieee1275_cell_t method;
  697. grub_ieee1275_cell_t ihandle;
  698. grub_ieee1275_cell_t result;
  699. grub_ieee1275_cell_t size;
  700. } args;
  701. INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 2);
  702. args.method = (grub_ieee1275_cell_t) "block-size";
  703. args.ihandle = ihandle;
  704. args.result = 1;
  705. if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result))
  706. return 0;
  707. return args.size;
  708. }