Changeset 1477
- Timestamp:
- 12/20/11 02:54:19 (5 months ago)
- File:
-
- 1 edited
-
trunk/dediprog.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/dediprog.c
r1474 r1477 300 300 } 301 301 302 /* Bulk write interface, will read multiple page_size byte chunks aligned to page_size bytes. 303 * @start start address 304 * @len length 305 * @return 0 on success, 1 on failure 306 */ 307 static int dediprog_spi_bulk_write(struct flashctx *flash, uint8_t *buf, 308 unsigned int start, unsigned int len) 309 { 310 int ret; 311 unsigned int i; 312 /* USB transfer size must be 512, other sizes will NOT work at all. 313 * chunksize is the real data size per USB bulk transfer. The remaining 314 * space in a USB bulk transfer must be filled with 0xff padding. 315 */ 316 const unsigned int chunksize = flash->page_size; 317 const unsigned int count = len / chunksize; 318 const char count_and_chunk[] = {count & 0xff, 319 (count >> 8) & 0xff, 320 chunksize & 0xff, 321 (chunksize >> 8) & 0xff}; 322 char usbbuf[512]; 323 324 if ((start % chunksize) || (len % chunksize)) { 325 msg_perr("%s: Unaligned start=%i, len=%i! Please report a bug " 326 "at flashrom@flashrom.org\n", __func__, start, len); 327 return 1; 328 } 329 330 /* No idea if the hardware can handle empty writes, so chicken out. */ 331 if (!len) 332 return 0; 333 /* Command Write SPI Bulk. No idea which write command is used on the 334 * SPI side. 335 */ 336 ret = usb_control_msg(dediprog_handle, 0x42, 0x30, start % 0x10000, 337 start / 0x10000, (char *)count_and_chunk, 338 sizeof(count_and_chunk), DEFAULT_TIMEOUT); 339 if (ret != sizeof(count_and_chunk)) { 340 msg_perr("Command Write SPI Bulk failed, %i %s!\n", ret, 341 usb_strerror()); 342 return 1; 343 } 344 345 for (i = 0; i < count; i++) { 346 memset(usbbuf, 0xff, sizeof(usbbuf)); 347 memcpy(usbbuf, buf + i * chunksize, chunksize); 348 ret = usb_bulk_write(dediprog_handle, dediprog_endpoint, 349 usbbuf, 512, 350 DEFAULT_TIMEOUT); 351 if (ret != 512) { 352 msg_perr("SPI bulk write failed, expected %i, got %i " 353 "%s!\n", 512, ret, usb_strerror()); 354 return 1; 355 } 356 } 357 358 return 0; 359 } 360 302 361 static int dediprog_spi_write_256(struct flashctx *flash, uint8_t *buf, 303 362 unsigned int start, unsigned int len) 304 363 { 305 364 int ret; 365 const unsigned int chunksize = flash->page_size; 366 unsigned int residue = start % chunksize ? chunksize - start % chunksize : 0; 367 unsigned int bulklen; 306 368 307 369 dediprog_set_leds(PASS_OFF|BUSY_ON|ERROR_OFF); 308 370 309 /* No idea about the real limit. Maybe 12, maybe more, maybe less. */ 310 ret = spi_write_chunked(flash, buf, start, len, 12); 311 312 if (ret) 371 if (residue) { 372 msg_pdbg("Slow write for partial block from 0x%x, length 0x%x\n", 373 start, residue); 374 /* No idea about the real limit. Maybe 12, maybe more. */ 375 ret = spi_write_chunked(flash, buf, start, residue, 12); 376 if (ret) { 377 dediprog_set_leds(PASS_OFF|BUSY_OFF|ERROR_ON); 378 return ret; 379 } 380 } 381 382 /* Round down. */ 383 bulklen = (len - residue) / chunksize * chunksize; 384 ret = dediprog_spi_bulk_write(flash, buf + residue, start + residue, 385 bulklen); 386 if (ret) { 313 387 dediprog_set_leds(PASS_OFF|BUSY_OFF|ERROR_ON); 314 else 315 dediprog_set_leds(PASS_ON|BUSY_OFF|ERROR_OFF); 316 317 return ret; 388 return ret; 389 } 390 391 len -= residue + bulklen; 392 if (len) { 393 msg_pdbg("Slow write for partial block from 0x%x, length 0x%x\n", 394 start, len); 395 ret = spi_write_chunked(flash, buf + residue + bulklen, 396 start + residue + bulklen, len, 12); 397 if (ret) { 398 dediprog_set_leds(PASS_OFF|BUSY_OFF|ERROR_ON); 399 return ret; 400 } 401 } 402 403 dediprog_set_leds(PASS_ON|BUSY_OFF|ERROR_OFF); 404 return 0; 318 405 } 319 406 … … 491 578 if (ret != 0x1) { 492 579 msg_perr("Command F failed (%s)!\n", usb_strerror()); 580 return 1; 581 } 582 return 0; 583 } 584 585 /* Start/stop blinking? 586 * Present in eng_detect_blink.log with firmware 3.1.8 587 * Preceded by Command J 588 */ 589 static int dediprog_command_g(void) 590 { 591 int ret; 592 593 ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x03, NULL, 0x0, DEFAULT_TIMEOUT); 594 if (ret != 0x0) { 595 msg_perr("Command G failed (%s)!\n", usb_strerror()); 596 return 1; 597 } 598 return 0; 599 } 600 601 /* Something. 602 * Present in all logs with firmware 5.1.5 603 * Always preceded by Command Receive Device String 604 * Always followed by Command Set SPI Voltage nonzero 605 */ 606 static int dediprog_command_h(void) 607 { 608 int ret; 609 610 ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x05, NULL, 0x0, DEFAULT_TIMEOUT); 611 if (ret != 0x0) { 612 msg_perr("Command H failed (%s)!\n", usb_strerror()); 613 return 1; 614 } 615 return 0; 616 } 617 618 /* Shutdown for firmware 5.x? 619 * Present in all logs with firmware 5.1.5 620 * Often preceded by a SPI operation (Command Read SPI Bulk or Receive SPI) 621 * Always followed by Command Set SPI Voltage 0x0000 622 */ 623 static int dediprog_command_i(void) 624 { 625 int ret; 626 627 ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x06, NULL, 0x0, DEFAULT_TIMEOUT); 628 if (ret != 0x0) { 629 msg_perr("Command I failed (%s)!\n", usb_strerror()); 630 return 1; 631 } 632 return 0; 633 } 634 635 /* Start/stop blinking? 636 * Present in all logs with firmware 5.1.5 637 * Always preceded by Command Receive Device String on 5.1.5 638 * Always followed by Command Set SPI Voltage nonzero on 5.1.5 639 * Present in eng_detect_blink.log with firmware 3.1.8 640 * Preceded by Command B in eng_detect_blink.log 641 * Followed by Command G in eng_detect_blink.log 642 */ 643 static int dediprog_command_j(void) 644 { 645 int ret; 646 647 ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x07, NULL, 0x0, DEFAULT_TIMEOUT); 648 if (ret != 0x0) { 649 msg_perr("Command J failed (%s)!\n", usb_strerror()); 493 650 return 1; 494 651 } … … 559 716 msg_pspew("%s\n", __func__); 560 717 718 #if 0 719 /* Shutdown on firmware 5.x */ 720 if (dediprog_firmwareversion == 5) 721 if (dediprog_command_i()) 722 return 1; 723 #endif 724 561 725 /* URB 28. Command Set SPI Voltage to 0. */ 562 726 if (dediprog_set_spi_voltage(0x0))
Note: See TracChangeset
for help on using the changeset viewer.
