spiflash.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. #include "compiler.h"
  2. #include "zlib.h"
  3. #include "spiflash.h"
  4. #if 1
  5. # include "console.h"
  6. # define MSG(...) con_printf(__VA_ARGS__)
  7. #else
  8. # define MSG(...) ((void)0)
  9. #endif
  10. struct spz_stream;
  11. typedef struct spz_stream spz_stream;
  12. #define NBUF 4
  13. struct spz_stream {
  14. z_stream zs;
  15. const struct spiflash *flash;
  16. uint8_t *optr; /* Output data pointer into obuf */
  17. /* Note: available output data ends at zs->next_out */
  18. union {
  19. uint8_t *bufs[NBUF];
  20. struct {
  21. uint8_t *ibuf; /* Input buffer if compressed */
  22. uint8_t *obuf; /* Output buffer */
  23. uint8_t *dbuf; /* Block data buffer */
  24. uint8_t *vbuf; /* Readback/verify buffer */
  25. };
  26. };
  27. struct spiflash_header header; /* Header of currently processed chunk */
  28. int err; /* Error code to return */
  29. bool eoi; /* Reached end of input */
  30. bool cleanup; /* Call inflateEnd() */
  31. };
  32. static void *spz_malloc(spz_stream *spz, size_t bytes)
  33. {
  34. void *p = malloc(bytes);
  35. if (!p && !spz->err) {
  36. spz->err = Z_MEM_ERROR;
  37. }
  38. return p;
  39. }
  40. static int spiflash_read_data(spz_stream *spz, void *buf, unsigned int len)
  41. {
  42. uint8_t *p = buf;
  43. while (len) {
  44. unsigned int avail = spz->zs.next_out - spz->optr;
  45. if (spz->err)
  46. break;
  47. if (avail) {
  48. if (avail > len)
  49. avail = len;
  50. memcpy(p, spz->optr, avail);
  51. p += avail;
  52. spz->optr += avail;
  53. len -= avail;
  54. } else {
  55. spz->optr = spz->zs.next_out = spz->obuf;
  56. spz->zs.avail_out = SPIFLASH_BLOCK_SIZE;
  57. while (spz->zs.avail_out) {
  58. if (!spz->zs.avail_in && !spz->eoi) {
  59. int (*read_data)(void *, void *, unsigned int);
  60. read_data = spz->flash->read_data;
  61. spz->zs.next_in = spz->ibuf;
  62. int rlen = read_data(spz->flash->cookie,
  63. spz->ibuf, SPIFLASH_BLOCK_SIZE);
  64. spz->eoi = rlen < SPIFLASH_BLOCK_SIZE;
  65. if (rlen < 0) {
  66. if (!spz->err)
  67. spz->err = rlen;
  68. rlen = 0;
  69. }
  70. spz->zs.avail_in = rlen;
  71. }
  72. int rv = inflate(&spz->zs, Z_SYNC_FLUSH);
  73. if (rv == Z_OK || (rv == Z_BUF_ERROR && !spz->eoi))
  74. continue;
  75. spz->eoi = true;
  76. if (rv != Z_STREAM_END && !spz->err)
  77. spz->err = rv;
  78. break;
  79. }
  80. }
  81. }
  82. return p - (uint8_t *)buf;
  83. }
  84. /*
  85. * spz needs to be initialized to zero except the flash, zs.next_in,
  86. * and zs.avail_in fields.
  87. */
  88. static int spiflash_data_init(spz_stream *spz)
  89. {
  90. int rv = Z_OK;
  91. uint8_t *rdbuf = NULL;
  92. int rlen;
  93. uint32_t header_crc;
  94. for (int i = 0; i < NBUF; i++) {
  95. spz->bufs[i] = spz_malloc(spz, SPIFLASH_BLOCK_SIZE);
  96. if (!spz->bufs[i])
  97. goto err;
  98. }
  99. spz->eoi = !spz->flash->read_data;
  100. /* gzip, max window size */
  101. rv = inflateInit2(&spz->zs, 16 + 15);
  102. if (rv != Z_OK && rv != Z_STREAM_END) {
  103. spz->err = rv;
  104. goto err;
  105. }
  106. spz->cleanup = true;
  107. err:
  108. return spz->err;
  109. }
  110. static int spiflash_data_cleanup(spz_stream *spz)
  111. {
  112. int err = 0;
  113. if (!spz)
  114. return 0;
  115. err = spz->err;
  116. if (spz->cleanup)
  117. inflateEnd(&spz->zs);
  118. for (int i = 0; i < NBUF; i++) {
  119. if (spz->bufs[i])
  120. free(spz->bufs[i]);
  121. }
  122. return err;
  123. }
  124. /*
  125. * Set up a command header with an address according to the SPI
  126. * addressing mode. Returns a pointer to the first byte past the
  127. * address.
  128. */
  129. static void *spiflash_setup_addrcmd(const struct spiflash *flash,
  130. uint32_t addr,
  131. uint8_t cmd24, uint8_t cmd32,
  132. void *cmdbuf)
  133. {
  134. enum spiflash_addr_mode mode = flash->param->addr;
  135. uint8_t *cmd = cmdbuf;
  136. if (!mode)
  137. mode = addr < (1 << 24) ? SPIFLASH_ADDR_24BIT : SPIFLASH_ADDR_32BIT;
  138. if (mode == SPIFLASH_ADDR_24BIT) {
  139. *cmd++ = cmd24;
  140. } else {
  141. *cmd++ = cmd32;
  142. *cmd++ = addr >> 24;
  143. }
  144. *cmd++ = addr >> 16;
  145. *cmd++ = addr >> 8;
  146. *cmd++ = addr;
  147. return cmd;
  148. }
  149. static int spiflash_get_status(const struct spiflash *flash,
  150. uint8_t cmd, uint8_t *sr)
  151. {
  152. return flash->ops->spi_read(flash->cookie, &cmd, 1, sr, 1,
  153. flash->param->tshsl);
  154. }
  155. /* This needs a timeout function */
  156. static int spiflash_wait_status(const struct spiflash *flash,
  157. int delay, uint8_t mask, uint8_t val)
  158. {
  159. uint8_t sr1;
  160. int rv;
  161. do {
  162. if (flash->ops->yield)
  163. flash->ops->yield(flash->cookie, delay);
  164. rv = spiflash_get_status(flash, ROM_READ_SR1, &sr1);
  165. if (rv)
  166. return rv;
  167. } while ((sr1 & mask) != val); /* Waiting... */
  168. return 0;
  169. }
  170. int spiflash_read(const struct spiflash *flash,
  171. uint32_t addr, void *buffer, size_t len)
  172. {
  173. uint8_t cmdbuf[6];
  174. uint8_t *cmd;
  175. cmd = spiflash_setup_addrcmd(flash, addr,
  176. ROM_FAST_READ, ROM_FAST_READ_32BIT,
  177. cmdbuf);
  178. *cmd++ = 0; /* Dummy cycles */
  179. return flash->ops->spi_read(flash->cookie, cmdbuf, cmd - cmdbuf,
  180. buffer, len, flash->param->tshsl1);
  181. }
  182. static int spiflash_simple_command(const struct spiflash *flash, uint8_t cmd)
  183. {
  184. return flash->ops->spi_write(flash->cookie, &cmd, 1, NULL, 0,
  185. flash->param->tshsl);
  186. }
  187. static int spiflash_write_enable(const struct spiflash *flash)
  188. {
  189. uint8_t sr1;
  190. int rv;
  191. rv = spiflash_wait_status(flash, 0, 1, 0);
  192. if (rv)
  193. return rv;
  194. rv = spiflash_simple_command(flash, ROM_WRITE_ENABLE);
  195. if (rv)
  196. return rv;
  197. return spiflash_wait_status(flash, 0, 3, 2);
  198. }
  199. static int spiflash_program(const struct spiflash *flash,
  200. uint32_t addr, const void *buffer, size_t len)
  201. {
  202. uint8_t cmdbuf[5];
  203. uint8_t *cmd;
  204. int rv;
  205. rv = spiflash_write_enable(flash);
  206. if (rv)
  207. return rv;
  208. cmd = spiflash_setup_addrcmd(flash, addr,
  209. ROM_PAGE_PROGRAM, ROM_PAGE_PROGRAM_32BIT,
  210. cmdbuf);
  211. rv = flash->ops->spi_write(flash->cookie, cmdbuf, cmd - cmdbuf,
  212. buffer, len, flash->param->tshsl2);
  213. if (rv)
  214. return rv;
  215. return spiflash_wait_status(flash, flash->param->tpp, 3, 0);
  216. }
  217. /*
  218. * Erase up to (long bits) sectors, using block erase if possible.
  219. */
  220. static int spiflash_erase(const struct spiflash *flash,
  221. uint32_t addr, unsigned long sector_mask)
  222. {
  223. uint8_t cmdbuf[5];
  224. uint8_t *cmd;
  225. uint8_t cmd24, cmd32;
  226. uint32_t erasesize;
  227. int rv;
  228. int delay;
  229. const uint32_t block_mask = SPIFLASH_BLOCK_SIZE - 1;
  230. const unsigned long block_sector_mask
  231. = block_mask >> SPIFLASH_SECTOR_SHIFT;
  232. if (!sector_mask) {
  233. MSG("update: nothing to erase\n");
  234. return 0;
  235. }
  236. while (sector_mask) {
  237. if (!(addr & block_mask) &&
  238. ((sector_mask & block_sector_mask) == block_sector_mask)) {
  239. cmd24 = ROM_ERASE_64K;
  240. cmd32 = ROM_ERASE_64K_32BIT;
  241. delay = flash->param->tbe2;
  242. erasesize = SPIFLASH_BLOCK_SIZE;
  243. } else {
  244. cmd24 = ROM_ERASE_4K;
  245. cmd32 = ROM_ERASE_4K_32BIT;
  246. delay = flash->param->tse;
  247. erasesize = SPIFLASH_SECTOR_SIZE;
  248. }
  249. if (sector_mask & 1) {
  250. MSG("\rupdate: erasing %2uK at 0x%06x... ", erasesize >> 10, addr);
  251. rv = spiflash_write_enable(flash);
  252. if (rv)
  253. return rv;
  254. cmd = spiflash_setup_addrcmd(flash, addr, cmd24, cmd32, cmdbuf);
  255. rv = flash->ops->spi_write(flash->cookie, cmdbuf, cmd - cmdbuf,
  256. NULL, 0, flash->param->tshsl2);
  257. if (rv)
  258. return rv;
  259. rv = spiflash_wait_status(flash, delay, 3, 0);
  260. if (rv)
  261. return rv;
  262. }
  263. addr += erasesize;
  264. sector_mask >>= (erasesize >> SPIFLASH_SECTOR_SHIFT);
  265. }
  266. MSG("ok\n");
  267. return 0;
  268. }
  269. /*
  270. * from: current flash contents
  271. * to: desired flash contents
  272. *
  273. * These are assumed to be aligned full block buffers
  274. */
  275. enum flashmem_status {
  276. FMS_DONE, /* All done, no programming needed */
  277. FMS_PROGRAM, /* Can be programmed */
  278. FMS_ERASE, /* Needs erase before programming */
  279. FMS_NOTCHECKED /* Not checked yet */
  280. };
  281. static enum flashmem_status
  282. spiflash_memcmp(const void *from, const void *to, size_t len)
  283. {
  284. const uint32_t *pf = from;
  285. const uint32_t *pt = to;
  286. const uint32_t *pfend = (const uint32_t *)((const char *)from + len);
  287. uint32_t doprog = 0;
  288. uint32_t doerase = 0;
  289. while (pf < pfend) {
  290. uint32_t f = *pf++;
  291. uint32_t t = *pt++;
  292. doprog |= f ^ t; /* Need programming if any data mismatch */
  293. doerase |= ~f & t; /* Need erasing if any 0 -> 1 */
  294. }
  295. return doerase ? FMS_ERASE : doprog ? FMS_PROGRAM : FMS_DONE;
  296. }
  297. /*
  298. * Check a block for sectors which need erasing and pages which need
  299. * programming; the prog_mask is 256 bits long and so span multiple words.
  300. *
  301. * The desired input is spz->dbuf and the existing flash content should be
  302. * already read into spz->vbuf.
  303. *
  304. */
  305. static void spiflash_check_block(spz_stream *spz, uint32_t addr,
  306. uint32_t *erase_mask, uint32_t *prog_mask)
  307. {
  308. const uint8_t *p, *q;
  309. unsigned int page;
  310. *erase_mask = 0;
  311. memset(prog_mask, 0, SPIFLASH_BLOCK_SIZE/SPIFLASH_PAGE_SIZE/8);
  312. p = spz->vbuf;
  313. q = spz->dbuf;
  314. for (page = 0; page < SPIFLASH_BLOCK_SIZE/SPIFLASH_PAGE_SIZE; page++) {
  315. enum flashmem_status status;
  316. switch (spiflash_memcmp(p, q, SPIFLASH_PAGE_SIZE)) {
  317. case FMS_ERASE:
  318. *erase_mask |= UINT32_C(1) <<
  319. (page >> (SPIFLASH_SECTOR_SHIFT-SPIFLASH_PAGE_SHIFT));
  320. break;
  321. case FMS_PROGRAM:
  322. prog_mask[page >> 5] |= UINT32_C(1) << (page & 31);
  323. break;
  324. default:
  325. /* Nothing to do! */
  326. break;
  327. }
  328. p += SPIFLASH_PAGE_SIZE;
  329. q += SPIFLASH_PAGE_SIZE;
  330. }
  331. }
  332. static int spiflash_flash_chunk(spz_stream *spz)
  333. {
  334. unsigned int data_left = spz->header.len;
  335. unsigned int addr = spz->header.addr;
  336. int rv;
  337. while (data_left && !spz->err) {
  338. unsigned int pre_padding = addr & (SPIFLASH_BLOCK_SIZE-1);
  339. unsigned int post_padding;
  340. unsigned int bytes;
  341. bytes = SPIFLASH_BLOCK_SIZE - pre_padding;
  342. post_padding = 0;
  343. if (bytes > data_left) {
  344. post_padding = bytes - data_left;
  345. bytes = data_left;
  346. }
  347. /* Read the current content of this block into vbuf */
  348. rv = spiflash_read(spz->flash, addr, spz->vbuf, SPIFLASH_BLOCK_SIZE);
  349. if (rv)
  350. goto err;
  351. /* Copy any invariant chunk */
  352. if (pre_padding)
  353. memcpy(spz->dbuf, spz->vbuf, pre_padding);
  354. if (post_padding)
  355. memcpy(spz->dbuf+SPIFLASH_BLOCK_SIZE-post_padding,
  356. spz->vbuf+SPIFLASH_BLOCK_SIZE-post_padding,
  357. post_padding);
  358. rv = spiflash_read_data(spz, spz->dbuf+pre_padding, bytes);
  359. if (rv != (int)bytes) {
  360. MSG("needed %u bytes got %d\n", rv);
  361. rv = Z_DATA_ERROR;
  362. goto err;
  363. }
  364. MSG("update: flash block at 0x%06x (%5u bytes):\n", addr, bytes);
  365. addr -= pre_padding;
  366. uint32_t erase_mask;
  367. uint32_t prog_mask[SPIFLASH_BLOCK_SIZE >> (SPIFLASH_PAGE_SHIFT+5)];
  368. spiflash_check_block(spz, addr, &erase_mask, prog_mask);
  369. if (erase_mask) {
  370. rv = spiflash_erase(spz->flash, addr, erase_mask);
  371. if (rv)
  372. goto err;
  373. /* Verify that the sector did erase */
  374. rv = spiflash_read(spz->flash, addr, spz->vbuf, SPIFLASH_BLOCK_SIZE);
  375. if (rv)
  376. goto err;
  377. spiflash_check_block(spz, addr, &erase_mask, prog_mask);
  378. if (erase_mask) {
  379. MSG("[erase mask = %04x] ", erase_mask);
  380. spz->err = SPIFLASH_ERR_ERASE_FAILED;
  381. goto err;
  382. }
  383. }
  384. unsigned int page;
  385. bool programmed = false;
  386. for (page = 0; page < (SPIFLASH_BLOCK_SIZE >> SPIFLASH_PAGE_SHIFT);
  387. page++) {
  388. uint32_t page_offs = page << SPIFLASH_PAGE_SHIFT;
  389. if (!(prog_mask[page >> 5] & (UINT32_C(1) << (page & 31))))
  390. continue; /* No need to program */
  391. programmed = true;
  392. udelay(100);
  393. MSG("\rupdate: writing at 0x%06x... ", addr + page_offs);
  394. rv = spiflash_program(spz->flash, addr + page_offs,
  395. spz->dbuf + page_offs,
  396. SPIFLASH_PAGE_SIZE);
  397. if (rv)
  398. goto err;
  399. /* Verify that the page did write */
  400. rv = spiflash_read(spz->flash, addr + page_offs,
  401. spz->vbuf + page_offs,
  402. SPIFLASH_PAGE_SIZE);
  403. if (rv) {
  404. MSG("readback ");
  405. goto err;
  406. }
  407. if (memcmp(spz->dbuf + page_offs, spz->vbuf + page_offs,
  408. SPIFLASH_PAGE_SIZE)) {
  409. MSG("verify @ 0x%06x ", addr + page_offs);
  410. spz->err = SPIFLASH_ERR_PROGRAM_FAILED;
  411. goto err;
  412. }
  413. }
  414. if (programmed)
  415. MSG("ok\n");
  416. else
  417. MSG("update: nothing to write\n");
  418. addr += pre_padding + bytes;
  419. data_left -= bytes;
  420. }
  421. return spz->err;
  422. err:
  423. if (!spz->err)
  424. spz->err = rv;
  425. return spz->err;
  426. }
  427. /* Serial Flash Discoverable Parameter Table, see JESD216 */
  428. static int spiflash_get_sfdp(const struct spiflash *flash, void *sfdp)
  429. {
  430. static const uint8_t cmd_read_sfdp[] = { ROM_READ_SFDP, 0, 0, 0, 0 };
  431. return flash->ops->spi_read(flash->cookie, cmd_read_sfdp,
  432. sizeof cmd_read_sfdp, sfdp, SPIFLASH_SFDP_SIZE,
  433. flash->param->tshsl);
  434. }
  435. static void *spiflash_read_chunk_str(spz_stream *spz)
  436. {
  437. int rv;
  438. if (spz->header.len >= SPIFLASH_BLOCK_SIZE) {
  439. spz->err = Z_DATA_ERROR;
  440. return NULL;
  441. }
  442. rv = spiflash_read_data(spz, spz->dbuf, spz->header.len);
  443. if (spz->err) {
  444. return NULL;
  445. }
  446. if (rv != (int)spz->header.len) {
  447. spz->err = Z_DATA_ERROR;
  448. return NULL;
  449. }
  450. spz->dbuf[spz->header.len] = '\0';
  451. return spz->dbuf;
  452. }
  453. /* Skip a data chunk */
  454. static int spiflash_skip_chunk(spz_stream *spz)
  455. {
  456. unsigned int skip = spz->header.len;
  457. while (skip) {
  458. unsigned int block = min(skip, SPIFLASH_BLOCK_SIZE);
  459. int rv = spiflash_read_data(spz, spz->dbuf, block);
  460. if (spz->err)
  461. return spz->err;
  462. if (rv != (int)block) {
  463. return spz->err = Z_DATA_ERROR;
  464. }
  465. skip -= block;
  466. }
  467. return 0;
  468. }
  469. /* Process a data chunk; return a nonzero value if done */
  470. static int spiflash_process_chunk(spz_stream *spz)
  471. {
  472. int rv;
  473. char *str;
  474. rv = spiflash_read_data(spz, &spz->header, sizeof spz->header);
  475. if (spz->err)
  476. return spz->err;
  477. else if (!rv)
  478. return Z_STREAM_END;
  479. else if (rv != sizeof spz->header)
  480. return spz->err = Z_STREAM_ERROR;
  481. if (spz->header.magic != SPIFLASH_MAGIC) {
  482. MSG("update: bad chunk header magic 0x%08x\n", spz->header.magic);
  483. return spz->err = Z_DATA_ERROR;
  484. }
  485. switch (spz->header.type) {
  486. case FDT_END:
  487. return Z_STREAM_END; /* End of data - not an error */
  488. case FDT_DATA:
  489. if (!spz->flash->ops)
  490. return spiflash_skip_chunk(spz);
  491. else
  492. return spiflash_flash_chunk(spz);
  493. case FDT_TARGET:
  494. str = spiflash_read_chunk_str(spz);
  495. if (!str || strcmp(str, spz->flash->target)) {
  496. MSG("update: this firmware file targets \"%s\", need \"%s\"\n",
  497. str, spz->flash->target);
  498. return spz->err = Z_DATA_ERROR;
  499. }
  500. return Z_OK;
  501. case FDT_NOTE:
  502. str = spiflash_read_chunk_str(spz);
  503. MSG("update: %s\n", str);
  504. return Z_OK;
  505. default:
  506. if (spz->header.flags & FDF_OPTIONAL) {
  507. return spiflash_skip_chunk(spz);
  508. } else {
  509. MSG("update: unknown chunk type: %u\n", spz->header.type);
  510. return spz->err = Z_DATA_ERROR;
  511. }
  512. }
  513. }
  514. int spiflash_flash_file(const struct spiflash *flash, void *buf, size_t buflen)
  515. {
  516. spz_stream _spz;
  517. spz_stream * const spz = &_spz; /* For consistency in notation */
  518. int err = 0;
  519. memset(spz, 0, sizeof *spz);
  520. spz->zs.avail_in = buflen;
  521. spz->zs.next_in = buf;
  522. spz->flash = flash;
  523. err = spiflash_data_init(spz);
  524. if (err)
  525. return err;
  526. if (0 && flash->ops) {
  527. static const uint8_t read_sr_cmd[2] = { ROM_READ_SR1, ROM_READ_SR2 };
  528. uint8_t sr1;
  529. uint32_t *sfdp;
  530. sfdp = malloc(SPIFLASH_SFDP_SIZE);
  531. memset(sfdp, 0, SPIFLASH_SFDP_SIZE);
  532. /* Note: SFDP data is littleendian! */
  533. err = spiflash_get_sfdp(flash, sfdp);
  534. if (err)
  535. return err;
  536. for (int i = 0; i < SPIFLASH_SFDP_SIZE; i += 16) {
  537. MSG("%04x :", i);
  538. for (int j = 0; j < 16; j += 4) {
  539. MSG(" %08x", sfdp[(i+j) >> 2]);
  540. }
  541. MSG("\n");
  542. }
  543. if (sfdp[0] != 0x50444653) {
  544. MSG("update: invalid SFDP information read\n");
  545. return SPIFLASH_ERR_DETECT;
  546. }
  547. /*
  548. * If the flash is busy, try to reset it
  549. */
  550. err = spiflash_get_status(flash, ROM_READ_SR1, &sr1);
  551. if (err)
  552. return err;
  553. if (sr1 & 0x01) {
  554. udelay(60);
  555. err = spiflash_get_status(flash, ROM_READ_SR1, &sr1);
  556. if (err)
  557. return err;
  558. if (sr1 & 0x01) {
  559. MSG("update: flash busy, trying reset... ");
  560. err = spiflash_simple_command(flash, ROM_ENABLE_RESET);
  561. if (err)
  562. return err;
  563. err = spiflash_simple_command(flash, ROM_RESET);
  564. if (err)
  565. return err;
  566. udelay(60);
  567. err = spiflash_get_status(flash, ROM_READ_SR1, &sr1);
  568. if (err || (sr1 & 0x01)) {
  569. MSG("failed\n");
  570. return SPIFLASH_ERR_NOT_READY;
  571. }
  572. MSG("ok\n");
  573. }
  574. }
  575. }
  576. while (!spiflash_process_chunk(spz)) {
  577. /* Process data chunks until end */
  578. }
  579. err = spiflash_data_cleanup(spz);
  580. if (err)
  581. MSG("failed (err %d)\n", err);
  582. return err;
  583. }
  584. /*
  585. * Read unique serial number from flash. Note: returns id in
  586. * bigendian ("network") byte order.
  587. */
  588. int spiflash_read_id(const struct spiflash *flash, void *id)
  589. {
  590. static const uint8_t read_unique_id[] = { ROM_READ_UNIQUE_ID, 0, 0, 0, 0 };
  591. return flash->ops->spi_read(flash->cookie, read_unique_id,
  592. sizeof read_unique_id,
  593. id, SPIFLASH_ID_LEN, flash->param->tshsl);
  594. }
  595. /*
  596. * Read vendor and device ID from flash.
  597. */
  598. int spiflash_read_vdid(const struct spiflash *flash, void *vdid)
  599. {
  600. static const uint8_t read_vdid[] = { ROM_MANUFACTURER_DEVICE_ID, 0, 0, 0 };
  601. return flash->ops->spi_read(flash->cookie, read_vdid,
  602. sizeof read_vdid,
  603. vdid, SPIFLASH_VDID_LEN, flash->param->tshsl);
  604. }