aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/moxa.c
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2008-04-30 03:53:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:42 -0400
commit5292bcd38e4bcd147905941b5e37b5b0da1a5577 (patch)
tree32bcc251b1e048b55f0e5a15c6ad7d1cce1c8fec /drivers/char/moxa.c
parent037182346f0991683cc7320a257c3f6089432cee (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/char/moxa.c')
-rw-r--r--drivers/char/moxa.c188
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
371static int moxa_load_c218(struct moxa_board_conf *brd, const void *ptr, 371static 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
449static 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;