diff options
author | Jiri Slaby <jirislaby@gmail.com> | 2008-04-30 03:53:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-30 11:29:42 -0400 |
commit | 5292bcd38e4bcd147905941b5e37b5b0da1a5577 (patch) | |
tree | 32bcc251b1e048b55f0e5a15c6ad7d1cce1c8fec /drivers | |
parent | 037182346f0991683cc7320a257c3f6089432cee (diff) |
Char: moxa, merge c2xx and c320 firmware loading
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Tested-by: Oyvind Aabling <Oyvind.Aabling@uni-c.dk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/moxa.c | 188 |
1 files changed, 69 insertions, 119 deletions
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 133819cf2c5c..fa58fa14b4cf 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -368,92 +368,40 @@ static int moxa_load_320b(struct moxa_board_conf *brd, const u8 *ptr, | |||
368 | return 0; | 368 | return 0; |
369 | } | 369 | } |
370 | 370 | ||
371 | static int moxa_load_c218(struct moxa_board_conf *brd, const void *ptr, | 371 | static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr, |
372 | size_t len) | 372 | size_t len) |
373 | { | 373 | { |
374 | void __iomem *baseAddr = brd->basemem; | 374 | void __iomem *baseAddr = brd->basemem; |
375 | const u16 *uptr = ptr; | 375 | const u16 *uptr = ptr; |
376 | size_t wlen, len2, j; | 376 | size_t wlen, len2, j; |
377 | unsigned int i, retry; | 377 | unsigned long key, loadbuf, loadlen, checksum, checksum_ok; |
378 | unsigned int i, retry, c320; | ||
378 | u16 usum, keycode; | 379 | u16 usum, keycode; |
379 | 380 | ||
380 | if (brd->boardType == MOXA_BOARD_CP204J) | 381 | c320 = brd->boardType == MOXA_BOARD_C320_PCI || |
381 | keycode = CP204J_KeyCode; | 382 | brd->boardType == MOXA_BOARD_C320_ISA; |
382 | else | 383 | keycode = (brd->boardType == MOXA_BOARD_CP204J) ? CP204J_KeyCode : |
383 | keycode = C218_KeyCode; | 384 | C218_KeyCode; |
384 | usum = 0; | ||
385 | wlen = len >> 1; | ||
386 | for (i = 0; i < wlen; i++) | ||
387 | usum += le16_to_cpu(uptr[i]); | ||
388 | retry = 0; | ||
389 | do { | ||
390 | wlen = len >> 1; | ||
391 | j = 0; | ||
392 | while (wlen) { | ||
393 | len2 = (wlen > 2048) ? 2048 : wlen; | ||
394 | wlen -= len2; | ||
395 | memcpy_toio(baseAddr + C218_LoadBuf, ptr + j, | ||
396 | len2 << 1); | ||
397 | j += len2 << 1; | ||
398 | |||
399 | writew(len2, baseAddr + C218DLoad_len); | ||
400 | writew(0, baseAddr + C218_key); | ||
401 | for (i = 0; i < 100; i++) { | ||
402 | if (readw(baseAddr + C218_key) == keycode) | ||
403 | break; | ||
404 | msleep(10); | ||
405 | } | ||
406 | if (readw(baseAddr + C218_key) != keycode) | ||
407 | return -EIO; | ||
408 | } | ||
409 | writew(0, baseAddr + C218DLoad_len); | ||
410 | writew(usum, baseAddr + C218check_sum); | ||
411 | writew(0, baseAddr + C218_key); | ||
412 | for (i = 0; i < 100; i++) { | ||
413 | if (readw(baseAddr + C218_key) == keycode) | ||
414 | break; | ||
415 | msleep(10); | ||
416 | } | ||
417 | retry++; | ||
418 | } while ((readb(baseAddr + C218chksum_ok) != 1) && (retry < 3)); | ||
419 | if (readb(baseAddr + C218chksum_ok) != 1) | ||
420 | return -EIO; | ||
421 | 385 | ||
422 | writew(0, baseAddr + C218_key); | 386 | switch (brd->boardType) { |
423 | for (i = 0; i < 100; i++) { | 387 | case MOXA_BOARD_CP204J: |
424 | if (readw(baseAddr + Magic_no) == Magic_code) | 388 | case MOXA_BOARD_C218_ISA: |
425 | break; | 389 | case MOXA_BOARD_C218_PCI: |
426 | msleep(10); | 390 | key = C218_key; |
427 | } | 391 | loadbuf = C218_LoadBuf; |
428 | if (readw(baseAddr + Magic_no) != Magic_code) | 392 | loadlen = C218DLoad_len; |
429 | return -EIO; | 393 | checksum = C218check_sum; |
430 | 394 | checksum_ok = C218chksum_ok; | |
431 | writew(1, baseAddr + Disable_IRQ); | 395 | break; |
432 | writew(0, baseAddr + Magic_no); | 396 | default: |
433 | for (i = 0; i < 100; i++) { | 397 | key = C320_key; |
434 | if (readw(baseAddr + Magic_no) == Magic_code) | 398 | keycode = C320_KeyCode; |
435 | break; | 399 | loadbuf = C320_LoadBuf; |
436 | msleep(10); | 400 | loadlen = C320DLoad_len; |
401 | checksum = C320check_sum; | ||
402 | checksum_ok = C320chksum_ok; | ||
403 | break; | ||
437 | } | 404 | } |
438 | if (readw(baseAddr + Magic_no) != Magic_code) | ||
439 | return -EIO; | ||
440 | |||
441 | moxaCard = 1; | ||
442 | brd->intNdx = baseAddr + IRQindex; | ||
443 | brd->intPend = baseAddr + IRQpending; | ||
444 | brd->intTable = baseAddr + IRQtable; | ||
445 | |||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | static int moxa_load_c320(struct moxa_board_conf *brd, const void *ptr, | ||
450 | size_t len) | ||
451 | { | ||
452 | void __iomem *baseAddr = brd->basemem; | ||
453 | const u16 *uptr = ptr; | ||
454 | size_t wlen, len2, j; | ||
455 | unsigned int i, retry; | ||
456 | u16 usum; | ||
457 | 405 | ||
458 | usum = 0; | 406 | usum = 0; |
459 | wlen = len >> 1; | 407 | wlen = len >> 1; |
@@ -466,33 +414,33 @@ static int moxa_load_c320(struct moxa_board_conf *brd, const void *ptr, | |||
466 | while (wlen) { | 414 | while (wlen) { |
467 | len2 = (wlen > 2048) ? 2048 : wlen; | 415 | len2 = (wlen > 2048) ? 2048 : wlen; |
468 | wlen -= len2; | 416 | wlen -= len2; |
469 | memcpy_toio(baseAddr + C320_LoadBuf, ptr + j, | 417 | memcpy_toio(baseAddr + loadbuf, ptr + j, len2 << 1); |
470 | len2 << 1); | ||
471 | j += len2 << 1; | 418 | j += len2 << 1; |
472 | writew(len2, baseAddr + C320DLoad_len); | 419 | |
473 | writew(0, baseAddr + C320_key); | 420 | writew(len2, baseAddr + loadlen); |
474 | for (i = 0; i < 10; i++) { | 421 | writew(0, baseAddr + key); |
475 | if (readw(baseAddr + C320_key) == C320_KeyCode) | 422 | for (i = 0; i < 100; i++) { |
423 | if (readw(baseAddr + key) == keycode) | ||
476 | break; | 424 | break; |
477 | msleep(10); | 425 | msleep(10); |
478 | } | 426 | } |
479 | if (readw(baseAddr + C320_key) != C320_KeyCode) | 427 | if (readw(baseAddr + key) != keycode) |
480 | return -EIO; | 428 | return -EIO; |
481 | } | 429 | } |
482 | writew(0, baseAddr + C320DLoad_len); | 430 | writew(0, baseAddr + loadlen); |
483 | writew(usum, baseAddr + C320check_sum); | 431 | writew(usum, baseAddr + checksum); |
484 | writew(0, baseAddr + C320_key); | 432 | writew(0, baseAddr + key); |
485 | for (i = 0; i < 10; i++) { | 433 | for (i = 0; i < 100; i++) { |
486 | if (readw(baseAddr + C320_key) == C320_KeyCode) | 434 | if (readw(baseAddr + key) == keycode) |
487 | break; | 435 | break; |
488 | msleep(10); | 436 | msleep(10); |
489 | } | 437 | } |
490 | retry++; | 438 | retry++; |
491 | } while ((readb(baseAddr + C320chksum_ok) != 1) && (retry < 3)); | 439 | } while ((readb(baseAddr + checksum_ok) != 1) && (retry < 3)); |
492 | if (readb(baseAddr + C320chksum_ok) != 1) | 440 | if (readb(baseAddr + checksum_ok) != 1) |
493 | return -EIO; | 441 | return -EIO; |
494 | 442 | ||
495 | writew(0, baseAddr + C320_key); | 443 | writew(0, baseAddr + key); |
496 | for (i = 0; i < 600; i++) { | 444 | for (i = 0; i < 600; i++) { |
497 | if (readw(baseAddr + Magic_no) == Magic_code) | 445 | if (readw(baseAddr + Magic_no) == Magic_code) |
498 | break; | 446 | break; |
@@ -501,14 +449,16 @@ static int moxa_load_c320(struct moxa_board_conf *brd, const void *ptr, | |||
501 | if (readw(baseAddr + Magic_no) != Magic_code) | 449 | if (readw(baseAddr + Magic_no) != Magic_code) |
502 | return -EIO; | 450 | return -EIO; |
503 | 451 | ||
504 | if (brd->busType == MOXA_BUS_TYPE_PCI) { /* ASIC board */ | 452 | if (c320) { |
505 | writew(0x3800, baseAddr + TMS320_PORT1); | 453 | if (brd->busType == MOXA_BUS_TYPE_PCI) { /* ASIC board */ |
506 | writew(0x3900, baseAddr + TMS320_PORT2); | 454 | writew(0x3800, baseAddr + TMS320_PORT1); |
507 | writew(28499, baseAddr + TMS320_CLOCK); | 455 | writew(0x3900, baseAddr + TMS320_PORT2); |
508 | } else { | 456 | writew(28499, baseAddr + TMS320_CLOCK); |
509 | writew(0x3200, baseAddr + TMS320_PORT1); | 457 | } else { |
510 | writew(0x3400, baseAddr + TMS320_PORT2); | 458 | writew(0x3200, baseAddr + TMS320_PORT1); |
511 | writew(19999, baseAddr + TMS320_CLOCK); | 459 | writew(0x3400, baseAddr + TMS320_PORT2); |
460 | writew(19999, baseAddr + TMS320_CLOCK); | ||
461 | } | ||
512 | } | 462 | } |
513 | writew(1, baseAddr + Disable_IRQ); | 463 | writew(1, baseAddr + Disable_IRQ); |
514 | writew(0, baseAddr + Magic_no); | 464 | writew(0, baseAddr + Magic_no); |
@@ -520,19 +470,21 @@ static int moxa_load_c320(struct moxa_board_conf *brd, const void *ptr, | |||
520 | if (readw(baseAddr + Magic_no) != Magic_code) | 470 | if (readw(baseAddr + Magic_no) != Magic_code) |
521 | return -EIO; | 471 | return -EIO; |
522 | 472 | ||
523 | j = readw(baseAddr + Module_cnt); | 473 | if (c320) { |
524 | if (j <= 0) | 474 | j = readw(baseAddr + Module_cnt); |
525 | return -EIO; | 475 | if (j <= 0) |
526 | brd->numPorts = j * 8; | 476 | return -EIO; |
527 | writew(j, baseAddr + Module_no); | 477 | brd->numPorts = j * 8; |
528 | writew(0, baseAddr + Magic_no); | 478 | writew(j, baseAddr + Module_no); |
529 | for (i = 0; i < 600; i++) { | 479 | writew(0, baseAddr + Magic_no); |
530 | if (readw(baseAddr + Magic_no) == Magic_code) | 480 | for (i = 0; i < 600; i++) { |
531 | break; | 481 | if (readw(baseAddr + Magic_no) == Magic_code) |
532 | msleep(10); | 482 | break; |
483 | msleep(10); | ||
484 | } | ||
485 | if (readw(baseAddr + Magic_no) != Magic_code) | ||
486 | return -EIO; | ||
533 | } | 487 | } |
534 | if (readw(baseAddr + Magic_no) != Magic_code) | ||
535 | return -EIO; | ||
536 | moxaCard = 1; | 488 | moxaCard = 1; |
537 | brd->intNdx = baseAddr + IRQindex; | 489 | brd->intNdx = baseAddr + IRQindex; |
538 | brd->intPend = baseAddr + IRQpending; | 490 | brd->intPend = baseAddr + IRQpending; |
@@ -549,17 +501,18 @@ static int moxa_load_code(struct moxa_board_conf *brd, const void *ptr, | |||
549 | int retval, i; | 501 | int retval, i; |
550 | 502 | ||
551 | if (len % 2) { | 503 | if (len % 2) { |
552 | printk(KERN_ERR "moxa: C2XX bios length is not even\n"); | 504 | printk(KERN_ERR "moxa: bios length is not even\n"); |
553 | return -EINVAL; | 505 | return -EINVAL; |
554 | } | 506 | } |
555 | 507 | ||
508 | retval = moxa_real_load_code(brd, ptr, len); /* may change numPorts */ | ||
509 | if (retval) | ||
510 | return retval; | ||
511 | |||
556 | switch (brd->boardType) { | 512 | switch (brd->boardType) { |
557 | case MOXA_BOARD_C218_ISA: | 513 | case MOXA_BOARD_C218_ISA: |
558 | case MOXA_BOARD_C218_PCI: | 514 | case MOXA_BOARD_C218_PCI: |
559 | case MOXA_BOARD_CP204J: | 515 | case MOXA_BOARD_CP204J: |
560 | retval = moxa_load_c218(brd, ptr, len); | ||
561 | if (retval) | ||
562 | return retval; | ||
563 | port = brd->ports; | 516 | port = brd->ports; |
564 | for (i = 0; i < brd->numPorts; i++, port++) { | 517 | for (i = 0; i < brd->numPorts; i++, port++) { |
565 | port->chkPort = 1; | 518 | port->chkPort = 1; |
@@ -579,9 +532,6 @@ static int moxa_load_code(struct moxa_board_conf *brd, const void *ptr, | |||
579 | } | 532 | } |
580 | break; | 533 | break; |
581 | default: | 534 | default: |
582 | retval = moxa_load_c320(brd, ptr, len); /* fills in numPorts */ | ||
583 | if (retval) | ||
584 | return retval; | ||
585 | port = brd->ports; | 535 | port = brd->ports; |
586 | for (i = 0; i < brd->numPorts; i++, port++) { | 536 | for (i = 0; i < brd->numPorts; i++, port++) { |
587 | port->chkPort = 1; | 537 | port->chkPort = 1; |