Skip to contentSkip to conversation

Support for NetUP Dual DVB-T/C CI RF card

PATCH In review Igor M. Liplianin 2 participants 8 messages Oct 3, 2010 – Oct 16, 2010

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Support for NetUP Dual DVB-T/C CI RF card

Patches to support for NetUP Dual DVB-T/C-CI RF from NetUP Inc.
http://linuxtv.org/wiki/index.php/NetUP_Dual_DVB_T_C_CI_RF

Features:

PCI-e x1
Supports two DVB-T/DVB-C transponders simultaneously Supports two analog audio/video channels simultaneously Independent descrambling of two transponders Hardware PID filtering

Components:

Conexant CX23885
STM STV0367 low-power and ultra-compact combo DVB-T/C single-chip receiver Xceive XC5000 silicon TV tuner
Altera FPGA for Common Interafce

The following changes since commit c8dd732fd119ce6d562d5fa82a10bbe75a376575:

V4L/DVB: gspca - sonixj: Have 0c45:6130 handled by sonixj instead of sn9c102 (2010-10-01
18:14:35 -0300)

are available in the git repository at:
http://udev.netup.ru/git/v4l-dvb.git netup-for-media-tree

Abylay Ospan (6):
cx23885: Altera FPGA CI interface reworked.
stv0367: change default value for AGC register.
stv0367: implement uncorrected blocks counter. cx23885, cimax2.c: Fix case of two CAM insertion irq. Fix CI code for NetUP Dual DVB-T/C CI RF card
Force xc5000 firmware loading for NetUP Dual DVB-T/C CI RF card

Igor M. Liplianin (14):
Altera FPGA firmware download module.
Altera FPGA based CI driver module.
Support for stv0367 multi-standard demodulator.
xc5000: add support for DVB-C tuning.
Initial commit to support NetUP Dual DVB-T/C CI RF card.
cx23885: implement tuner_bus parameter for cx23885_board structure.
cx23885: implement num_fds_portb, num_fds_portc parameters for cx23885_board structure.
stv0367: Fix potential divide error
cx23885: remove duplicate set interrupt mask
stv0367: coding style corrections
cx25840: Fix subdev registration and typo in cx25840-core.c
cx23885: 0xe becomes 0xc again for NetUP Dual DVB-S2
cx23885: disable MSI for NetUP cards, otherwise CI is not working cx23885, altera-ci: enable all PID's less than 0x20 in hardware PID filter.

 drivers/media/common/tuners/xc5000.c        |   18 +
 drivers/media/dvb/frontends/Kconfig         |    7 +
 drivers/media/dvb/frontends/Makefile        |    1 +
 drivers/media/dvb/frontends/stv0367.c       | 3419 +++++++++++++++++++++++++
 drivers/media/dvb/frontends/stv0367.h       |   62 +
 drivers/media/dvb/frontends/stv0367_priv.h  |  211 ++
 drivers/media/dvb/frontends/stv0367_regs.h  | 3614 +++++++++++++++++++++++++++
 drivers/media/video/cx23885/Kconfig         |   12 +-
 drivers/media/video/cx23885/Makefile        |    1 +
 drivers/media/video/cx23885/altera-ci.c     |  841 +++++++
 drivers/media/video/cx23885/altera-ci.h     |  102 +
 drivers/media/video/cx23885/cimax2.c        |   24 +-
 drivers/media/video/cx23885/cx23885-cards.c |  116 +-
 drivers/media/video/cx23885/cx23885-core.c  |   35 +-
 drivers/media/video/cx23885/cx23885-dvb.c   |  175 ++-
 drivers/media/video/cx23885/cx23885-reg.h   |    1 +
 drivers/media/video/cx23885/cx23885-video.c |    7 +-
 drivers/media/video/cx23885/cx23885.h       |    7 +-
 drivers/media/video/cx25840/cx25840-core.c  |    4 +-
 drivers/misc/Kconfig                        |    1 +
 drivers/misc/Makefile                       |    1 +
 drivers/misc/stapl-altera/Kconfig           |    8 +
 drivers/misc/stapl-altera/Makefile          |    3 +
 drivers/misc/stapl-altera/altera.c          | 2739 ++++++++++++++++++++
 drivers/misc/stapl-altera/jbicomp.c         |  163 ++
 drivers/misc/stapl-altera/jbiexprt.h        |   94 +
 drivers/misc/stapl-altera/jbijtag.c         | 1038 ++++++++
 drivers/misc/stapl-altera/jbijtag.h         |   83 +
 drivers/misc/stapl-altera/jbistub.c         |   70 +
 include/misc/altera.h                       |   49 +
 30 files changed, 12872 insertions(+), 34 deletions(-)
 create mode 100644 drivers/media/dvb/frontends/stv0367.c
 create mode 100644 drivers/media/dvb/frontends/stv0367.h
 create mode 100644 drivers/media/dvb/frontends/stv0367_priv.h
 create mode 100644 drivers/media/dvb/frontends/stv0367_regs.h
 create mode 100644 drivers/media/video/cx23885/altera-ci.c
 create mode 100644 drivers/media/video/cx23885/altera-ci.h
 create mode 100644 drivers/misc/stapl-altera/Kconfig
 create mode 100644 drivers/misc/stapl-altera/Makefile
 create mode 100644 drivers/misc/stapl-altera/altera.c
 create mode 100644 drivers/misc/stapl-altera/jbicomp.c
 create mode 100644 drivers/misc/stapl-altera/jbiexprt.h
 create mode 100644 drivers/misc/stapl-altera/jbijtag.c
 create mode 100644 drivers/misc/stapl-altera/jbijtag.h
 create mode 100644 drivers/misc/stapl-altera/jbistub.c
 create mode 100644 include/misc/altera.h
#1 lore raw

Em 03-10-2010 19:35, Igor M. Liplianin escreveu:

Quoted 18 lines

Patches to support for NetUP Dual DVB-T/C-CI RF from NetUP Inc.
http://linuxtv.org/wiki/index.php/NetUP_Dual_DVB_T_C_CI_RF

Features:

PCI-e x1
Supports two DVB-T/DVB-C transponders simultaneously Supports two analog audio/video channels simultaneously Independent descrambling of two transponders Hardware PID filtering

Components:

Conexant CX23885
STM STV0367 low-power and ultra-compact combo DVB-T/C single-chip receiver Xceive XC5000 silicon TV tuner
Altera FPGA for Common Interafce

Quoted 7 lines

The following changes since commit c8dd732fd119ce6d562d5fa82a10bbe75a376575:

V4L/DVB: gspca - sonixj: Have 0c45:6130 handled by sonixj instead of sn9c102 (2010-10-01
18:14:35 -0300)

are available in the git repository at:
http://udev.netup.ru/git/v4l-dvb.git netup-for-media-tree

Hmm... it is not working... perhaps you forgot to run git update-server-info.

The better would be to enable git protocol instead.

Quoted 46 lines

Abylay Ospan (6):
cx23885: Altera FPGA CI interface reworked.
stv0367: change default value for AGC register.
stv0367: implement uncorrected blocks counter. cx23885, cimax2.c: Fix case of two CAM insertion irq. Fix CI code for NetUP Dual DVB-T/C CI RF card
Force xc5000 firmware loading for NetUP Dual DVB-T/C CI RF card

Igor M. Liplianin (14):
Altera FPGA firmware download module.
Altera FPGA based CI driver module.
Support for stv0367 multi-standard demodulator.
xc5000: add support for DVB-C tuning.
Initial commit to support NetUP Dual DVB-T/C CI RF card.
cx23885: implement tuner_bus parameter for cx23885_board structure.
cx23885: implement num_fds_portb, num_fds_portc parameters for cx23885_board structure.
stv0367: Fix potential divide error
cx23885: remove duplicate set interrupt mask
stv0367: coding style corrections
cx25840: Fix subdev registration and typo in cx25840-core.c
cx23885: 0xe becomes 0xc again for NetUP Dual DVB-S2
cx23885: disable MSI for NetUP cards, otherwise CI is not working cx23885, altera-ci: enable all PID's less than 0x20 in hardware PID filter.

 drivers/media/common/tuners/xc5000.c        |   18 +
 drivers/media/dvb/frontends/Kconfig         |    7 +
 drivers/media/dvb/frontends/Makefile        |    1 +
 drivers/media/dvb/frontends/stv0367.c       | 3419 +++++++++++++++++++++++++
 drivers/media/dvb/frontends/stv0367.h       |   62 +
 drivers/media/dvb/frontends/stv0367_priv.h  |  211 ++
 drivers/media/dvb/frontends/stv0367_regs.h  | 3614 +++++++++++++++++++++++++++
 drivers/media/video/cx23885/Kconfig         |   12 +-
 drivers/media/video/cx23885/Makefile        |    1 +
 drivers/media/video/cx23885/altera-ci.c     |  841 +++++++
 drivers/media/video/cx23885/altera-ci.h     |  102 +
 drivers/media/video/cx23885/cimax2.c        |   24 +-
 drivers/media/video/cx23885/cx23885-cards.c |  116 +-
 drivers/media/video/cx23885/cx23885-core.c  |   35 +-
 drivers/media/video/cx23885/cx23885-dvb.c   |  175 ++-
 drivers/media/video/cx23885/cx23885-reg.h   |    1 +
 drivers/media/video/cx23885/cx23885-video.c |    7 +-
 drivers/media/video/cx23885/cx23885.h       |    7 +-
 drivers/media/video/cx25840/cx25840-core.c  |    4 +-
Quoted 11 lines
 drivers/misc/Kconfig                        |    1 +
 drivers/misc/Makefile                       |    1 +
 drivers/misc/stapl-altera/Kconfig           |    8 +
 drivers/misc/stapl-altera/Makefile          |    3 +
 drivers/misc/stapl-altera/altera.c          | 2739 ++++++++++++++++++++
 drivers/misc/stapl-altera/jbicomp.c         |  163 ++
 drivers/misc/stapl-altera/jbiexprt.h        |   94 +
 drivers/misc/stapl-altera/jbijtag.c         | 1038 ++++++++
 drivers/misc/stapl-altera/jbijtag.h         |   83 +
 drivers/misc/stapl-altera/jbistub.c         |   70 +
 include/misc/altera.h                       |   49 +

Hmm... that's new for me... a driver at misc?

Quoted 20 lines
 30 files changed, 12872 insertions(+), 34 deletions(-)
 create mode 100644 drivers/media/dvb/frontends/stv0367.c
 create mode 100644 drivers/media/dvb/frontends/stv0367.h
 create mode 100644 drivers/media/dvb/frontends/stv0367_priv.h
 create mode 100644 drivers/media/dvb/frontends/stv0367_regs.h
 create mode 100644 drivers/media/video/cx23885/altera-ci.c
 create mode 100644 drivers/media/video/cx23885/altera-ci.h
 create mode 100644 drivers/misc/stapl-altera/Kconfig
 create mode 100644 drivers/misc/stapl-altera/Makefile
 create mode 100644 drivers/misc/stapl-altera/altera.c
 create mode 100644 drivers/misc/stapl-altera/jbicomp.c
 create mode 100644 drivers/misc/stapl-altera/jbiexprt.h
 create mode 100644 drivers/misc/stapl-altera/jbijtag.c
 create mode 100644 drivers/misc/stapl-altera/jbijtag.h
 create mode 100644 drivers/misc/stapl-altera/jbistub.c
 create mode 100644 include/misc/altera.h

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#2 lore raw

Em 14-10-2010 14:48, Mauro Carvalho Chehab escreveu:

Quoted 21 lines

Em 03-10-2010 19:35, Igor M. Liplianin escreveu:

Quoted 20 lines

Patches to support for NetUP Dual DVB-T/C-CI RF from NetUP Inc.
http://linuxtv.org/wiki/index.php/NetUP_Dual_DVB_T_C_CI_RF

Features:

PCI-e x1
Supports two DVB-T/DVB-C transponders simultaneously Supports two analog audio/video channels simultaneously Independent descrambling of two transponders Hardware PID filtering

Components:

Conexant CX23885
STM STV0367 low-power and ultra-compact combo DVB-T/C single-chip receiver Xceive XC5000 silicon TV tuner
Altera FPGA for Common Interafce

The following changes since commit c8dd732fd119ce6d562d5fa82a10bbe75a376575:

Quoted 7 lines
Quoted 5 lines

V4L/DVB: gspca - sonixj: Have 0c45:6130 handled by sonixj instead of sn9c102 (2010-10-01
18:14:35 -0300)

are available in the git repository at:
http://udev.netup.ru/git/v4l-dvb.git netup-for-media-tree

Hmm... it is not working... perhaps you forgot to run git update-server-info.

It worked. It just took a very long time to update...

Quoted 12 lines
Quoted 11 lines
 drivers/misc/Kconfig                        |    1 +
 drivers/misc/Makefile                       |    1 +
 drivers/misc/stapl-altera/Kconfig           |    8 +
 drivers/misc/stapl-altera/Makefile          |    3 +
 drivers/misc/stapl-altera/altera.c          | 2739 ++++++++++++++++++++
 drivers/misc/stapl-altera/jbicomp.c         |  163 ++
 drivers/misc/stapl-altera/jbiexprt.h        |   94 +
 drivers/misc/stapl-altera/jbijtag.c         | 1038 ++++++++
 drivers/misc/stapl-altera/jbijtag.h         |   83 +
 drivers/misc/stapl-altera/jbistub.c         |   70 +
 include/misc/altera.h                       |   49 +
Quoted 1 line

Hmm... that's new for me... a driver at misc?

Hmm... a FPGA programming driver... Is it needed to for the DVB device to work, or it is used only when programming the device at the manufacturer?

Cheers,
Mauro.

#3 lore raw

В сообщении от 14 октября 2010 20:54:52 автор Mauro Carvalho Chehab написал:

Quoted 47 lines

Em 14-10-2010 14:48, Mauro Carvalho Chehab escreveu:

Quoted 24 lines

Em 03-10-2010 19:35, Igor M. Liplianin escreveu:

Quoted 23 lines

Patches to support for NetUP Dual DVB-T/C-CI RF from NetUP Inc.

http://linuxtv.org/wiki/index.php/NetUP_Dual_DVB_T_C_CI_RF

Features:

PCI-e x1
Supports two DVB-T/DVB-C transponders simultaneously Supports two analog audio/video channels simultaneously Independent descrambling of two transponders Hardware PID filtering

Components:

Conexant CX23885
STM STV0367 low-power and ultra-compact combo DVB-T/C single-chip receiver Xceive XC5000 silicon TV tuner
Altera FPGA for Common Interafce

The following changes since commit c8dd732fd119ce6d562d5fa82a10bbe75a376575:
V4L/DVB: gspca - sonixj: Have 0c45:6130 handled by sonixj instead of sn9c102 (2010-10-01

Quoted 7 lines
Quoted 4 lines

18:14:35 -0300)

are available in the git repository at:
http://udev.netup.ru/git/v4l-dvb.git netup-for-media-tree

Hmm... it is not working... perhaps you forgot to run git update-server-info.

It worked. It just took a very long time to update...

Quoted 12 lines
Quoted 11 lines
 drivers/misc/Kconfig                        |    1 +
 drivers/misc/Makefile                       |    1 +
 drivers/misc/stapl-altera/Kconfig           |    8 +
 drivers/misc/stapl-altera/Makefile          |    3 +
 drivers/misc/stapl-altera/altera.c          | 2739 ++++++++++++++++++++
 drivers/misc/stapl-altera/jbicomp.c         |  163 ++
 drivers/misc/stapl-altera/jbiexprt.h        |   94 +
 drivers/misc/stapl-altera/jbijtag.c         | 1038 ++++++++
 drivers/misc/stapl-altera/jbijtag.h         |   83 +
 drivers/misc/stapl-altera/jbistub.c         |   70 +
 include/misc/altera.h                       |   49 +
Quoted 4 lines
Quoted 1 line

Hmm... that's new for me... a driver at misc?

Hmm... a FPGA programming driver... Is it needed to for the DVB device to work, or it is used only when programming the device at the manufacturer?

Yes, it needed for DVB device to work. FPGA model used in device has not flash memory. Then FPGA itself drives CI and hardware PID filter.
We all realize, that FPGA programming not belongs to DVB only, it is more common. So maybe misc is the place.

Quoted 3 lines

Cheers,
Mauro.

Signature · 2 lines
Igor M. Liplianin
Microsoft Windows Free Zone - Linux used for all Computing Tasks
#4 lore raw

Em 14-10-2010 15:58, Igor M. Liplianin escreveu:

Quoted 48 lines

В сообщении от 14 октября 2010 20:54:52 автор Mauro Carvalho Chehab написал:

Quoted 47 lines

Em 14-10-2010 14:48, Mauro Carvalho Chehab escreveu:

Quoted 24 lines

Em 03-10-2010 19:35, Igor M. Liplianin escreveu:

Quoted 23 lines

Patches to support for NetUP Dual DVB-T/C-CI RF from NetUP Inc.

http://linuxtv.org/wiki/index.php/NetUP_Dual_DVB_T_C_CI_RF

Features:

PCI-e x1
Supports two DVB-T/DVB-C transponders simultaneously Supports two analog audio/video channels simultaneously Independent descrambling of two transponders Hardware PID filtering

Components:

Conexant CX23885
STM STV0367 low-power and ultra-compact combo DVB-T/C single-chip receiver Xceive XC5000 silicon TV tuner
Altera FPGA for Common Interafce

The following changes since commit c8dd732fd119ce6d562d5fa82a10bbe75a376575:
V4L/DVB: gspca - sonixj: Have 0c45:6130 handled by sonixj instead of sn9c102 (2010-10-01

Quoted 7 lines
Quoted 4 lines

18:14:35 -0300)

are available in the git repository at:
http://udev.netup.ru/git/v4l-dvb.git netup-for-media-tree

Hmm... it is not working... perhaps you forgot to run git update-server-info.

It worked. It just took a very long time to update...

Quoted 12 lines
Quoted 11 lines
 drivers/misc/Kconfig                        |    1 +
 drivers/misc/Makefile                       |    1 +
 drivers/misc/stapl-altera/Kconfig           |    8 +
 drivers/misc/stapl-altera/Makefile          |    3 +
 drivers/misc/stapl-altera/altera.c          | 2739 ++++++++++++++++++++
 drivers/misc/stapl-altera/jbicomp.c         |  163 ++
 drivers/misc/stapl-altera/jbiexprt.h        |   94 +
 drivers/misc/stapl-altera/jbijtag.c         | 1038 ++++++++
 drivers/misc/stapl-altera/jbijtag.h         |   83 +
 drivers/misc/stapl-altera/jbistub.c         |   70 +
 include/misc/altera.h                       |   49 +
Quoted 6 lines
Quoted 4 lines
Quoted 1 line

Hmm... that's new for me... a driver at misc?

Hmm... a FPGA programming driver... Is it needed to for the DVB device to work, or it is used only when programming the device at the manufacturer?

Yes, it needed for DVB device to work. FPGA model used in device has not flash memory. Then FPGA itself drives CI and hardware PID filter.

Hmm... interesting design.

Quoted 1 line

We all realize, that FPGA programming not belongs to DVB only, it is more common.

Agreed.

Quoted 1 line

So maybe misc is the place.

Maybe misc is the better place, not really sure. Well, I posted your altera patch to LKML, and just sent my review.

Better to continue those discussions on the thread where LKML is c/c, to allow more readers to be able to follow the entire discussions.

Cheers,
Mauro.

#5 lore raw
In reply to Igor M. Liplianin

Em 03-10-2010 19:35, Igor M. Liplianin escreveu:

Quoted 88 lines

Patches to support for NetUP Dual DVB-T/C-CI RF from NetUP Inc.
http://linuxtv.org/wiki/index.php/NetUP_Dual_DVB_T_C_CI_RF

Features:

PCI-e x1
Supports two DVB-T/DVB-C transponders simultaneously Supports two analog audio/video channels simultaneously Independent descrambling of two transponders Hardware PID filtering

Components:

Conexant CX23885
STM STV0367 low-power and ultra-compact combo DVB-T/C single-chip receiver Xceive XC5000 silicon TV tuner
Altera FPGA for Common Interafce

The following changes since commit c8dd732fd119ce6d562d5fa82a10bbe75a376575:

V4L/DVB: gspca - sonixj: Have 0c45:6130 handled by sonixj instead of sn9c102 (2010-10-01
18:14:35 -0300)

are available in the git repository at:
http://udev.netup.ru/git/v4l-dvb.git netup-for-media-tree

Abylay Ospan (6):
cx23885: Altera FPGA CI interface reworked.
stv0367: change default value for AGC register.
stv0367: implement uncorrected blocks counter. cx23885, cimax2.c: Fix case of two CAM insertion irq. Fix CI code for NetUP Dual DVB-T/C CI RF card
Force xc5000 firmware loading for NetUP Dual DVB-T/C CI RF card

Igor M. Liplianin (14):
Altera FPGA firmware download module.
Altera FPGA based CI driver module.
Support for stv0367 multi-standard demodulator.
xc5000: add support for DVB-C tuning.
Initial commit to support NetUP Dual DVB-T/C CI RF card.
cx23885: implement tuner_bus parameter for cx23885_board structure.
cx23885: implement num_fds_portb, num_fds_portc parameters for cx23885_board structure.
stv0367: Fix potential divide error
cx23885: remove duplicate set interrupt mask
stv0367: coding style corrections
cx25840: Fix subdev registration and typo in cx25840-core.c
cx23885: 0xe becomes 0xc again for NetUP Dual DVB-S2
cx23885: disable MSI for NetUP cards, otherwise CI is not working cx23885, altera-ci: enable all PID's less than 0x20 in hardware PID filter.

 drivers/media/common/tuners/xc5000.c        |   18 +
 drivers/media/dvb/frontends/Kconfig         |    7 +
 drivers/media/dvb/frontends/Makefile        |    1 +
 drivers/media/dvb/frontends/stv0367.c       | 3419 +++++++++++++++++++++++++
 drivers/media/dvb/frontends/stv0367.h       |   62 +
 drivers/media/dvb/frontends/stv0367_priv.h  |  211 ++
 drivers/media/dvb/frontends/stv0367_regs.h  | 3614 +++++++++++++++++++++++++++
 drivers/media/video/cx23885/Kconfig         |   12 +-
 drivers/media/video/cx23885/Makefile        |    1 +
 drivers/media/video/cx23885/altera-ci.c     |  841 +++++++
 drivers/media/video/cx23885/altera-ci.h     |  102 +
 drivers/media/video/cx23885/cimax2.c        |   24 +-
 drivers/media/video/cx23885/cx23885-cards.c |  116 +-
 drivers/media/video/cx23885/cx23885-core.c  |   35 +-
 drivers/media/video/cx23885/cx23885-dvb.c   |  175 ++-
 drivers/media/video/cx23885/cx23885-reg.h   |    1 +
 drivers/media/video/cx23885/cx23885-video.c |    7 +-
 drivers/media/video/cx23885/cx23885.h       |    7 +-
 drivers/media/video/cx25840/cx25840-core.c  |    4 +-
 drivers/misc/Kconfig                        |    1 +
 drivers/misc/Makefile                       |    1 +
 drivers/misc/stapl-altera/Kconfig           |    8 +
 drivers/misc/stapl-altera/Makefile          |    3 +
 drivers/misc/stapl-altera/altera.c          | 2739 ++++++++++++++++++++
 drivers/misc/stapl-altera/jbicomp.c         |  163 ++
 drivers/misc/stapl-altera/jbiexprt.h        |   94 +
 drivers/misc/stapl-altera/jbijtag.c         | 1038 ++++++++
 drivers/misc/stapl-altera/jbijtag.h         |   83 +
 drivers/misc/stapl-altera/jbistub.c         |   70 +
 include/misc/altera.h                       |   49 +
 30 files changed, 12872 insertions(+), 34 deletions(-)
 create mode 100644 drivers/media/dvb/frontends/stv0367.c
 create mode 100644 drivers/media/dvb/frontends/stv0367.h
 create mode 100644 drivers/media/dvb/frontends/stv0367_priv.h
 create mode 100644 drivers/media/dvb/frontends/stv0367_regs.h
 create mode 100644 drivers/media/video/cx23885/altera-ci.c
 create mode 100644 drivers/media/video/cx23885/altera-ci.h
 create mode 100644 drivers/misc/stapl-altera/Kconfig
Quoted 8 lines
 create mode 100644 drivers/misc/stapl-altera/Makefile
 create mode 100644 drivers/misc/stapl-altera/altera.c
 create mode 100644 drivers/misc/stapl-altera/jbicomp.c
 create mode 100644 drivers/misc/stapl-altera/jbiexprt.h
 create mode 100644 drivers/misc/stapl-altera/jbijtag.c
 create mode 100644 drivers/misc/stapl-altera/jbijtag.h
 create mode 100644 drivers/misc/stapl-altera/jbistub.c
 create mode 100644 include/misc/altera.h

Igor,

I did a quick look at Altera FPGA driver, and at the cx23885 changes for it to work with this device, I think the FPGA driver deserves some discussion at linux-kernel.

As there's a V4L/DVB device that depends on it, it is clear to me that the better is to merge the driver via my tree.

So, I'm basically sending your first patch to the mailing lists for review.

---

Quoted 1 line

From e1fd36695ae082ae89a3155cabb5a84181ae9df4 Mon Sep 17 00:00:00 2001

From: Igor M. Liplianin <[email protected]>
Date: Mon, 24 May 2010 13:09:23 +0300
Subject: Altera FPGA firmware download module.
Cc: Linux Media Mailing List <[email protected]>

It uses STAPL files and programs Altera FPGA through JTAG. Interface to JTAG must be provided from main device module, for example through cx23885 GPIO.

---
 drivers/misc/Kconfig                 |    1 +
 drivers/misc/Makefile                |    1 +
 drivers/misc/stapl-altera/Kconfig    |    8 +
 drivers/misc/stapl-altera/Makefile   |    3 +
 drivers/misc/stapl-altera/altera.c   | 2739 ++++++++++++++++++++++++++++++++++
 drivers/misc/stapl-altera/jbicomp.c  |  163 ++
 drivers/misc/stapl-altera/jbiexprt.h |   94 ++
 drivers/misc/stapl-altera/jbijtag.c  | 1038 +++++++++++++
 drivers/misc/stapl-altera/jbijtag.h  |   83 +
 drivers/misc/stapl-altera/jbistub.c  |   70 +
 include/misc/altera.h                |   49 +
 11 files changed, 4249 insertions(+), 0 deletions(-)
 create mode 100644 drivers/misc/stapl-altera/Kconfig
 create mode 100644 drivers/misc/stapl-altera/Makefile
 create mode 100644 drivers/misc/stapl-altera/altera.c
 create mode 100644 drivers/misc/stapl-altera/jbicomp.c
 create mode 100644 drivers/misc/stapl-altera/jbiexprt.h
 create mode 100644 drivers/misc/stapl-altera/jbijtag.c
 create mode 100644 drivers/misc/stapl-altera/jbijtag.h
 create mode 100644 drivers/misc/stapl-altera/jbistub.c
 create mode 100644 include/misc/altera.h
drivers/misc/Kconfig +1 -0
index 9b089df..3cfc47c 100644
@@ -367,5 +367,6 @@ source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
 source "drivers/misc/iwmc3200top/Kconfig"
+source "drivers/misc/stapl-altera/Kconfig"
 
 endif # MISC_DEVICES
drivers/misc/Makefile +1 -0
index 67552d6..58e794c 100644
@@ -32,3 +32,4 @@ obj-y				+= eeprom/
 obj-y				+= cb710/
 obj-$(CONFIG_VMWARE_BALLOON)	+= vmware_balloon.o
 obj-$(CONFIG_ARM_CHARLCD)	+= arm-charlcd.o
+obj-y				+= stapl-altera/
drivers/misc/stapl-altera/Kconfig new file +8 -0
new file mode 100644
index 0000000..19ba4a9
@@ -0,0 +1,8 @@
+comment "Altera FPGA firmware download module"
+
+config STAPL_ALTERA
+	tristate "Altera FPGA firmware download module"
+	depends on I2C
+	default m
+	help
+	  An Altera FPGA module. Say Y when you want to support this tool.
drivers/misc/stapl-altera/Makefile new file +3 -0
new file mode 100644
index 0000000..db56178
@@ -0,0 +1,3 @@
+stapl-altera-objs = jbistub.o jbijtag.o jbicomp.o altera.o
+
+obj-$(CONFIG_STAPL_ALTERA) += stapl-altera.o
drivers/misc/stapl-altera/altera.c new file +2739 -0

2,739 lines not on this page · raw message

drivers/misc/stapl-altera/jbicomp.c new file +163 -0

163 lines not on this page · raw message

drivers/misc/stapl-altera/jbiexprt.h new file +94 -0

77 lines not on this page · raw message

drivers/misc/stapl-altera/jbijtag.c new file +1038 -0

1,038 lines not on this page · raw message

drivers/misc/stapl-altera/jbijtag.h new file +83 -0

83 lines not on this page · raw message

drivers/misc/stapl-altera/jbistub.c new file +70 -0

70 lines not on this page · raw message

include/misc/altera.h new file +49 -0

49 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.7.1

Part of the diff is not shown here. View the raw message.

#6 lore raw

Em 14-10-2010 15:11, Mauro Carvalho Chehab escreveu:

Quoted 217 lines

Em 03-10-2010 19:35, Igor M. Liplianin escreveu:

Quoted 88 lines

Patches to support for NetUP Dual DVB-T/C-CI RF from NetUP Inc.
http://linuxtv.org/wiki/index.php/NetUP_Dual_DVB_T_C_CI_RF

Features:

PCI-e x1
Supports two DVB-T/DVB-C transponders simultaneously Supports two analog audio/video channels simultaneously Independent descrambling of two transponders Hardware PID filtering

Components:

Conexant CX23885
STM STV0367 low-power and ultra-compact combo DVB-T/C single-chip receiver Xceive XC5000 silicon TV tuner
Altera FPGA for Common Interafce

The following changes since commit c8dd732fd119ce6d562d5fa82a10bbe75a376575:

V4L/DVB: gspca - sonixj: Have 0c45:6130 handled by sonixj instead of sn9c102 (2010-10-01
18:14:35 -0300)

are available in the git repository at:
http://udev.netup.ru/git/v4l-dvb.git netup-for-media-tree

Abylay Ospan (6):
cx23885: Altera FPGA CI interface reworked.
stv0367: change default value for AGC register.
stv0367: implement uncorrected blocks counter. cx23885, cimax2.c: Fix case of two CAM insertion irq. Fix CI code for NetUP Dual DVB-T/C CI RF card
Force xc5000 firmware loading for NetUP Dual DVB-T/C CI RF card

Igor M. Liplianin (14):
Altera FPGA firmware download module.
Altera FPGA based CI driver module.
Support for stv0367 multi-standard demodulator.
xc5000: add support for DVB-C tuning.
Initial commit to support NetUP Dual DVB-T/C CI RF card.
cx23885: implement tuner_bus parameter for cx23885_board structure.
cx23885: implement num_fds_portb, num_fds_portc parameters for cx23885_board structure.
stv0367: Fix potential divide error
cx23885: remove duplicate set interrupt mask
stv0367: coding style corrections
cx25840: Fix subdev registration and typo in cx25840-core.c
cx23885: 0xe becomes 0xc again for NetUP Dual DVB-S2
cx23885: disable MSI for NetUP cards, otherwise CI is not working cx23885, altera-ci: enable all PID's less than 0x20 in hardware PID filter.

 drivers/media/common/tuners/xc5000.c        |   18 +
 drivers/media/dvb/frontends/Kconfig         |    7 +
 drivers/media/dvb/frontends/Makefile        |    1 +
 drivers/media/dvb/frontends/stv0367.c       | 3419 +++++++++++++++++++++++++
 drivers/media/dvb/frontends/stv0367.h       |   62 +
 drivers/media/dvb/frontends/stv0367_priv.h  |  211 ++
 drivers/media/dvb/frontends/stv0367_regs.h  | 3614 +++++++++++++++++++++++++++
 drivers/media/video/cx23885/Kconfig         |   12 +-
 drivers/media/video/cx23885/Makefile        |    1 +
 drivers/media/video/cx23885/altera-ci.c     |  841 +++++++
 drivers/media/video/cx23885/altera-ci.h     |  102 +
 drivers/media/video/cx23885/cimax2.c        |   24 +-
 drivers/media/video/cx23885/cx23885-cards.c |  116 +-
 drivers/media/video/cx23885/cx23885-core.c  |   35 +-
 drivers/media/video/cx23885/cx23885-dvb.c   |  175 ++-
 drivers/media/video/cx23885/cx23885-reg.h   |    1 +
 drivers/media/video/cx23885/cx23885-video.c |    7 +-
 drivers/media/video/cx23885/cx23885.h       |    7 +-
 drivers/media/video/cx25840/cx25840-core.c  |    4 +-
 drivers/misc/Kconfig                        |    1 +
 drivers/misc/Makefile                       |    1 +
 drivers/misc/stapl-altera/Kconfig           |    8 +
 drivers/misc/stapl-altera/Makefile          |    3 +
 drivers/misc/stapl-altera/altera.c          | 2739 ++++++++++++++++++++
 drivers/misc/stapl-altera/jbicomp.c         |  163 ++
 drivers/misc/stapl-altera/jbiexprt.h        |   94 +
 drivers/misc/stapl-altera/jbijtag.c         | 1038 ++++++++
 drivers/misc/stapl-altera/jbijtag.h         |   83 +
 drivers/misc/stapl-altera/jbistub.c         |   70 +
 include/misc/altera.h                       |   49 +
 30 files changed, 12872 insertions(+), 34 deletions(-)
 create mode 100644 drivers/media/dvb/frontends/stv0367.c
 create mode 100644 drivers/media/dvb/frontends/stv0367.h
 create mode 100644 drivers/media/dvb/frontends/stv0367_priv.h
 create mode 100644 drivers/media/dvb/frontends/stv0367_regs.h
 create mode 100644 drivers/media/video/cx23885/altera-ci.c
 create mode 100644 drivers/media/video/cx23885/altera-ci.h
 create mode 100644 drivers/misc/stapl-altera/Kconfig
Quoted 8 lines
 create mode 100644 drivers/misc/stapl-altera/Makefile
 create mode 100644 drivers/misc/stapl-altera/altera.c
 create mode 100644 drivers/misc/stapl-altera/jbicomp.c
 create mode 100644 drivers/misc/stapl-altera/jbiexprt.h
 create mode 100644 drivers/misc/stapl-altera/jbijtag.c
 create mode 100644 drivers/misc/stapl-altera/jbijtag.h
 create mode 100644 drivers/misc/stapl-altera/jbistub.c
 create mode 100644 include/misc/altera.h

Igor,

I did a quick look at Altera FPGA driver, and at the cx23885 changes for it to work with this device, I think the FPGA driver deserves some discussion at linux-kernel.

As there's a V4L/DVB device that depends on it, it is clear to me that the better is to merge the driver via my tree.

So, I'm basically sending your first patch to the mailing lists for review.

---

From e1fd36695ae082ae89a3155cabb5a84181ae9df4 Mon Sep 17 00:00:00 2001
From: Igor M. Liplianin <[email protected]>
Date: Mon, 24 May 2010 13:09:23 +0300
Subject: Altera FPGA firmware download module.
Cc: Linux Media Mailing List <[email protected]>

It uses STAPL files and programs Altera FPGA through JTAG. Interface to JTAG must be provided from main device module, for example through cx23885 GPIO.

---
 drivers/misc/Kconfig                 |    1 +
 drivers/misc/Makefile                |    1 +
 drivers/misc/stapl-altera/Kconfig    |    8 +
 drivers/misc/stapl-altera/Makefile   |    3 +
 drivers/misc/stapl-altera/altera.c   | 2739 ++++++++++++++++++++++++++++++++++
 drivers/misc/stapl-altera/jbicomp.c  |  163 ++
 drivers/misc/stapl-altera/jbiexprt.h |   94 ++
 drivers/misc/stapl-altera/jbijtag.c  | 1038 +++++++++++++
 drivers/misc/stapl-altera/jbijtag.h  |   83 +
 drivers/misc/stapl-altera/jbistub.c  |   70 +
 include/misc/altera.h                |   49 +
 11 files changed, 4249 insertions(+), 0 deletions(-)
 create mode 100644 drivers/misc/stapl-altera/Kconfig
 create mode 100644 drivers/misc/stapl-altera/Makefile
 create mode 100644 drivers/misc/stapl-altera/altera.c
 create mode 100644 drivers/misc/stapl-altera/jbicomp.c
 create mode 100644 drivers/misc/stapl-altera/jbiexprt.h
 create mode 100644 drivers/misc/stapl-altera/jbijtag.c
 create mode 100644 drivers/misc/stapl-altera/jbijtag.h
 create mode 100644 drivers/misc/stapl-altera/jbistub.c
 create mode 100644 include/misc/altera.h
drivers/misc/Kconfig +1 -0
index 9b089df..3cfc47c 100644
@@ -367,5 +367,6 @@ source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
 source "drivers/misc/iwmc3200top/Kconfig"
+source "drivers/misc/stapl-altera/Kconfig"
 
 endif # MISC_DEVICES
drivers/misc/Makefile +1 -0
index 67552d6..58e794c 100644
@@ -32,3 +32,4 @@ obj-y				+= eeprom/
 obj-y				+= cb710/
 obj-$(CONFIG_VMWARE_BALLOON)	+= vmware_balloon.o
 obj-$(CONFIG_ARM_CHARLCD)	+= arm-charlcd.o
+obj-y				+= stapl-altera/
drivers/misc/stapl-altera/Kconfig new file +8 -0
new file mode 100644
index 0000000..19ba4a9
@@ -0,0 +1,8 @@
+comment "Altera FPGA firmware download module"
+
+config STAPL_ALTERA
+	tristate "Altera FPGA firmware download module"
+	depends on I2C
+	default m
+	help
+	  An Altera FPGA module. Say Y when you want to support this tool.
drivers/misc/stapl-altera/Makefile new file +3 -0
new file mode 100644
index 0000000..db56178
@@ -0,0 +1,3 @@
+stapl-altera-objs = jbistub.o jbijtag.o jbicomp.o altera.o
+
+obj-$(CONFIG_STAPL_ALTERA) += stapl-altera.o
drivers/misc/stapl-altera/altera.c new file +23 -0
new file mode 100644
index 0000000..9628d9c
@@ -0,0 +1,2739 @@
+/*
+ * altera.c
+ *
+ * altera FPGA driver
+ *
+ * Copyright (C) Altera Corporation 1998-2001
+ * Copyright (C) 2010 NetUP Inc.
+ * Copyright (C) 2010 Igor M. Liplianin <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

drivers/misc/stapl-altera/altera.c line 33

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+ */
+
+#include <linux/firmware.h>
+#include <linux/slab.h>
+#include <misc/altera.h>
+#include "jbiexprt.h"
+
+static int verbose = 1;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "enable debugging information");

Better to call it as "debug".

Quoted 6 lines
drivers/misc/stapl-altera/altera.c new file +6 -0
+
+MODULE_DESCRIPTION("altera FPGA kernel module");
+MODULE_AUTHOR("Igor M. Liplianin  <[email protected]>");
+MODULE_LICENSE("GPL");
+
+#include "jbijtag.h"

drivers/misc/stapl-altera/altera.c line 49

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+
+#define JBI_STACK_SIZE 128
+
+#define JBIC_MESSAGE_LENGTH 1024
+
+/* This macro checks if a code address is inside the code section */
+#define CHECK_PC \
+	if ((pc < code_section) || (pc >= debug_section)) { \
+		status = JBIC_BOUNDS_ERROR; \
+	}

This is ugly: a macro with 3 hidden arguments... you might define it as:

#define check_pc(pc, code_section, debug_section) \
+ (((pc < code_section) || (pc >= debug_section)) ? JBIC_BOUNDS_ERROR : 0)

and call it as:

	status = check_pc(pc, code_section, debug_section);

But I suspect that the better would be do do, instead:

	if ((pc < code_section) || (pc >= debug_section)) 
		goto jbic_bounds_error;

on all places you're using it.

Quoted 23 lines
drivers/misc/stapl-altera/altera.c new file +23 -0
+
+#define dprintk(args...) \
+	if (verbose) { \
+		printk(KERN_DEBUG args); \
+	}
+
+char *error_text[] = {
+	/* JBIC_SUCCESS            0 */ "success",
+	/* JBIC_OUT_OF_MEMORY      1 */ "out of memory",
+	/* JBIC_IO_ERROR           2 */ "file access error",
+	/* JAMC_SYNTAX_ERROR       3 */ "syntax error",
+	/* JBIC_UNEXPECTED_END     4 */ "unexpected end of file",
+	/* JBIC_UNDEFINED_SYMBOL   5 */ "undefined symbol",
+	/* JAMC_REDEFINED_SYMBOL   6 */ "redefined symbol",
+	/* JBIC_INTEGER_OVERFLOW   7 */ "integer overflow",
+	/* JBIC_DIVIDE_BY_ZERO     8 */ "divide by zero",
+	/* JBIC_CRC_ERROR          9 */ "CRC mismatch",
+	/* JBIC_INTERNAL_ERROR    10 */ "internal error",
+	/* JBIC_BOUNDS_ERROR      11 */ "bounds error",
+	/* JAMC_TYPE_MISMATCH     12 */ "type mismatch",
+	/* JAMC_ASSIGN_TO_CONST   13 */ "assignment to constant",
+	/* JAMC_NEXT_UNEXPECTED   14 */ "NEXT unexpected",
+	/* JAMC_POP_UNEXPECTED    15 */ "POP unexpected",

drivers/misc/stapl-altera/altera.c line 82

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+	/* JAMC_RETURN_UNEXPECTED 16 */ "RETURN unexpected",
+	/* JAMC_ILLEGAL_SYMBOL    17 */ "illegal symbol name",
+	/* JBIC_VECTOR_MAP_FAILED 18 */ "vector signal name not found",
+	/* JBIC_USER_ABORT        19 */ "execution cancelled",
+	/* JBIC_STACK_OVERFLOW    20 */ "stack overflow",
+	/* JBIC_ILLEGAL_OPCODE    21 */ "illegal instruction code",
+	/* JAMC_PHASE_ERROR       22 */ "phase error",
+	/* JAMC_SCOPE_ERROR       23 */ "scope error",
+	/* JBIC_ACTION_NOT_FOUND  24 */ "action not found",
+};

The better would be to use standard Unix error codes here.

Quoted 13 lines
drivers/misc/stapl-altera/altera.c new file +13 -0
+
+#define MAX_ERROR_CODE (int)((sizeof(error_text)/sizeof(error_text[0]))+1)
+
+/* This function checks if enough parameters are available on the stack. */
+static int jbi_check_stack(int stack_ptr, int count, int *status)
+{
+	if (stack_ptr < count) {
+		*status = JBIC_STACK_OVERFLOW;
+		return 0;
+	}
+
+	return 1;
+}

drivers/misc/stapl-altera/altera.c line 105

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+
+static int jbi_strlen(char *string)
+{
+	int len = 0;
+
+	while (string[len] != '\0')
+		++len;
+
+	return len;
+}

Linux has strlen. Don't re-invent the wheel.

Quoted 47 lines
drivers/misc/stapl-altera/altera.c new file +47 -0
+
+static void jbi_ltoa(char *buffer, s32 number)
+{
+	int index = 0;
+	int rev_index = 0;
+	char reverse[32];
+
+	if (number < 0L) {
+		buffer[index++] = '-';
+		number = 0 - number;
+	} else if (number == 0)
+		buffer[index++] = '0';
+
+	while (number != 0) {
+		reverse[rev_index++] = (char)((number % 10) + '0');
+		number /= 10;
+	}
+
+	while (rev_index > 0)
+		buffer[index++] = reverse[--rev_index];
+
+	buffer[index] = '\0';
+}
+
+static char jbi_toupper(char ch)
+{
+	return (char)(((ch >= 'a') && (ch <= 'z')) ? (ch + 'A' - 'a') : ch);
+}
+
+static int jbi_stricmp(char *left, char *right)
+{
+	int result = 0;
+	char l, r;
+
+	do {
+		l = jbi_toupper(*left);
+		r = jbi_toupper(*right);
+		result = l - r;
+		++left;
+		++right;
+	} while ((result == 0) && (l != '\0') && (r != '\0'));
+
+	return result;
+}
+
+static void jbi_strncpy(char *left, char *right, int count)
+{

drivers/misc/stapl-altera/altera.c line 162

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+	char ch;
+
+	do {
+		*left = *right;
+		ch = *right;
+		++left;
+		++right;
+		--count;
+	} while ((ch != '\0') && (count != 0));
+}

Linux has functions for the above. Don't re-invent the wheel.

Quoted 7 lines
drivers/misc/stapl-altera/altera.c new file +7 -0
+
+static void jbi_make_dword(u8 *buf, u32 num)
+{
+	buf[0] = (u8) num;
+	buf[1] = (u8)(num >> 8L);
+	buf[2] = (u8)(num >> 16L);
+	buf[3] = (u8)(num >> 24L);

drivers/misc/stapl-altera/altera.c line 179

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+}
+
+static u32 jbi_get_dword(u8 *buf)
+{
+	return
+	    (((u32)buf[0]) |
+	     (((u32)buf[1]) << 8L) |
+	     (((u32)buf[2]) << 16L) |
+	     (((u32)buf[3]) << 24L));
+}

Use the proper Linux functions to handle big/little endian.

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+
+static void jbi_export_integer(char *key, s32 value)
+{
+	dprintk("Export: key = \"%s\", value = %d\n", key, value);
+}
+
+#define HEX_LINE_CHARS 72
+#define HEX_LINE_BITS (HEX_LINE_CHARS * 4)
+
+static char conv_to_hex(u32 value)

drivers/misc/stapl-altera/altera.c line 199

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+{
+	char c;
+
+	if (value > 9)
+		c = (char)(value + ('A' - 10));
+	else
+		c = (char)(value + '0');
+
+	return c;
+}

There are some Linux functions for this also.

Quoted 120 lines
drivers/misc/stapl-altera/altera.c new file +120 -0
+
+static void jbi_export_boolean_array(char *key, u8 *data, s32 count)
+{
+	char string[HEX_LINE_CHARS + 1];
+	s32 i, offset;
+	u32 size, line, lines, linebits, value, j, k;
+
+	if (count > HEX_LINE_BITS) {
+		dprintk("Export: key = \"%s\", %d bits, value = HEX\n",
+							key, count);
+		lines = (count + (HEX_LINE_BITS - 1)) / HEX_LINE_BITS;
+
+		for (line = 0; line < lines; ++line) {
+			if (line < (lines - 1)) {
+				linebits = HEX_LINE_BITS;
+				size = HEX_LINE_CHARS;
+				offset = count - ((line + 1) * HEX_LINE_BITS);
+			} else {
+				linebits =
+					count - ((lines - 1) * HEX_LINE_BITS);
+				size = (linebits + 3) / 4;
+				offset = 0L;
+			}
+
+			string[size] = '\0';
+			j = size - 1;
+			value = 0;
+
+			for (k = 0; k < linebits; ++k) {
+				i = k + offset;
+				if (data[i >> 3] & (1 << (i & 7)))
+					value |= (1 << (i & 3));
+				if ((i & 3) == 3) {
+					string[j] = conv_to_hex(value);
+					value = 0;
+					--j;
+				}
+			}
+			if ((k & 3) > 0)
+				string[j] = conv_to_hex(value);
+
+			dprintk("%s\n", string);
+		}
+
+	} else {
+		size = (count + 3) / 4;
+		string[size] = '\0';
+		j = size - 1;
+		value = 0;
+
+		for (i = 0; i < count; ++i) {
+			if (data[i >> 3] & (1 << (i & 7)))
+				value |= (1 << (i & 3));
+			if ((i & 3) == 3) {
+				string[j] = conv_to_hex(value);
+				value = 0;
+				--j;
+			}
+		}
+		if ((i & 3) > 0)
+			string[j] = conv_to_hex(value);
+
+		dprintk("Export: key = \"%s\", %d bits, value = HEX %s\n",
+			key, count, string);
+	}
+}
+
+static JBI_RETURN_TYPE jbi_execute(struct altera_config *astate,
+				u8 *program,
+				s32 program_size,
+				s32 *error_address,
+				int *exit_code,
+				int *format_version)
+{
+	static char message_buffer[JBIC_MESSAGE_LENGTH + 1];
+	static long stack[JBI_STACK_SIZE] = {0L};/*64 bits*/
+	JBI_RETURN_TYPE status = JBIC_SUCCESS;
+	u32 first_word = 0L;
+	u32 action_table = 0L;
+	u32 proc_table = 0L;
+	u32 string_table = 0L;
+	u32 symbol_table = 0L;
+	u32 data_section = 0L;
+	u32 code_section = 0L;
+	u32 debug_section = 0L;
+	u32 action_count = 0L;
+	u32 proc_count = 0L;
+	u32 symbol_count = 0L;
+	long *variables = NULL;/*64bits*/
+	s32 *variable_size = NULL;
+	char *attributes = NULL;
+	u8 *proc_attributes = NULL;
+	u32 pc;
+	u32 opcode_address;
+	u32 args[3];
+	u32 opcode;
+	u32 name_id;
+	u8 charbuf[4];
+	long long_temp;/*64bits*/
+	u32 variable_id;
+	u8 *charptr_temp;
+	u8 *charptr_temp2;
+	long *longptr_temp;
+	int version = 0;
+	int delta = 0;
+	int stack_ptr = 0;
+	u32 arg_count;
+	int done = 0;
+	int bad_opcode = 0;
+	u32 count;
+	u32 index;
+	u32 index2;
+	s32 long_count;
+	s32 long_index;
+	s32 long_index2;
+	u32 i;
+	u32 j;
+	u32 uncompressed_size;
+	u32 offset;
+	u32 value;

drivers/misc/stapl-altera/altera.c line 329

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+	int current_proc = 0;
+	int reverse;
+
+	char *name;
+
+	dprintk("%s\n", __func__);
+
+	/* Read header information */
+	if (program_size > 52L) {
+		first_word    = GET_DWORD(0);

GET_DWORD here masks the fact that it is reading a dword data, from a variable called "program". Please, don't do that. Also, again, what this function actually does is to convert a data using a given endiannes.
As it is defined as:

	#define GET_BYTE(x) (program[x])
	#define GET_DWORD(x) \
		(((((u32) GET_BYTE(x)) << 24L) & 0xFF000000L) | \
		((((u32) GET_BYTE((x)+1)) << 16L) & 0x00FF0000L) | \
		((((u32) GET_BYTE((x)+2)) << 8L) & 0x0000FF00L) | \
		(((u32) GET_BYTE((x)+3)) & 0x000000FFL))

you're getting a 32 bits encoded as little endian. So, the Linux way for it would be to use, instead:

	get_unaligned_le32(&program[0]);

(the same applies to all cases of GET_BYTE/GET_WORD/GET_DWORD)

Quoted 19 lines
drivers/misc/stapl-altera/altera.c new file +19 -0
+		version = (int)(first_word & 1L);
+		*format_version = version + 1;
+		delta = version * 8;
+
+		action_table  = GET_DWORD(4);
+		proc_table    = GET_DWORD(8);
+		string_table  = GET_DWORD(4 + delta);
+		symbol_table  = GET_DWORD(16 + delta);
+		data_section  = GET_DWORD(20 + delta);
+		code_section  = GET_DWORD(24 + delta);
+		debug_section = GET_DWORD(28 + delta);
+		action_count  = GET_DWORD(40 + delta);
+		proc_count    = GET_DWORD(44 + delta);
+		symbol_count  = GET_DWORD(48 + (2 * delta));
+	}
+
+	if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) {
+		done = 1;
+		status = JBIC_IO_ERROR;

drivers/misc/stapl-altera/altera.c line 358

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+		goto exit_done;
+	}
+
+	if (symbol_count <= 0)
+		goto exit_done;
+	/* 64 bits */
+	variables = kmalloc((u32)symbol_count * sizeof(long), GFP_KERNEL);
+
+	if (variables == NULL)
+		status = JBIC_OUT_OF_MEMORY;

status = -ENOMEM;

Quoted 14 lines
drivers/misc/stapl-altera/altera.c new file +14 -0
+
+	if (status == JBIC_SUCCESS) {
+		variable_size = kmalloc(
+			(u32)symbol_count * sizeof(s32), GFP_KERNEL);
+
+		if (variable_size == NULL)
+			status = JBIC_OUT_OF_MEMORY;
+	}
+
+	if (status == JBIC_SUCCESS) {
+		attributes = (char *)
+				kmalloc((u32)symbol_count, GFP_KERNEL);
+
+		if (attributes == NULL)

drivers/misc/stapl-altera/altera.c line 382

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+			status = JBIC_OUT_OF_MEMORY;
+	}
+
+	if ((status == JBIC_SUCCESS) && (version > 0)) {
+		proc_attributes = (u8 *)
+				kmalloc((u32)proc_count, GFP_KERNEL);
+
+		if (proc_attributes == NULL)
+			status = JBIC_OUT_OF_MEMORY;
+	}

Same for all above: -ENOMEM.

Quoted 178 lines
drivers/misc/stapl-altera/altera.c new file +178 -0
+
+	if (status != JBIC_SUCCESS)
+		goto exit_done;
+
+	delta = version * 2;
+
+	for (i = 0; i < (u32)symbol_count; ++i) {
+		offset = (u32)
+			(symbol_table + ((11 + delta) * i));
+
+		value = GET_DWORD(offset + 3 + delta);
+
+		attributes[i] = GET_BYTE(offset);
+
+		/* use bit 7 of attribute byte to indicate that
+		this buffer was dynamically allocated
+		and should be freed later */
+		attributes[i] &= 0x7f;
+
+		variable_size[i] = GET_DWORD(offset + 7 + delta);
+
+		/*
+		Attribute bits:
+		bit 0: 0 = read-only, 1 = read-write
+		bit 1: 0 = not compressed, 1 = compressed
+		bit 2: 0 = not initialized, 1 = initialized
+		bit 3: 0 = scalar, 1 = array
+		bit 4: 0 = Boolean, 1 = integer
+		bit 5: 0 = declared variable,
+			1 = compiler created temporary variable
+		*/
+
+		if ((attributes[i] & 0x0c) == 0x04)
+			/* initialized scalar variable */
+			variables[i] = value;
+		else if ((attributes[i] & 0x1e) == 0x0e) {
+			/* initialized compressed
+			Boolean array */
+			uncompressed_size = jbi_get_dword(
+				&program[data_section + value]);
+
+			/* allocate a buffer for the
+			uncompressed data */
+			variables[i] = (long)kmalloc(uncompressed_size,
+								GFP_KERNEL);
+			dprintk("%s: var=%lx, (s32)var=%x\n", __func__,
+					variables[i], (s32)variables[i]);
+			if (variables[i] == 0L)
+				status = JBIC_OUT_OF_MEMORY;
+			else {
+				/* set flag so buffer
+				will be freed later */
+				attributes[i] |= 0x80;
+
+				/* uncompress the data */
+				if (jbi_uncompress(&program[data_section +
+									value],
+						variable_size[i],
+						(u8 *)variables[i],/*64 bits*/
+						uncompressed_size,
+						version) != uncompressed_size)
+					/* decompression failed */
+					status = JBIC_IO_ERROR;
+				else /*64 bits?*/
+					variable_size[i] =
+							uncompressed_size * 8L;
+
+			}
+		} else if ((attributes[i] & 0x1e) == 0x0c) {
+			/* initialized Boolean array */
+			/*64 bits*/
+			variables[i] = value + data_section + (long)program;
+		} else if ((attributes[i] & 0x1c) == 0x1c) {
+			/* initialized integer array */
+			variables[i] = value + data_section;
+		} else if ((attributes[i] & 0x0c) == 0x08) {
+			/* uninitialized array */
+
+			/* flag attributes so
+			that memory is freed */
+			attributes[i] |= 0x80;
+
+			if (variable_size[i] > 0) {
+				u32 size;
+
+				if (attributes[i] & 0x10)
+					/* integer array */
+					size = (u32)(variable_size[i] *
+								sizeof(s32));
+				else
+					/* Boolean array */
+					size = (u32)
+						((variable_size[i] + 7L) / 8L);
+				/*64 bits*/
+				variables[i] = (long)kmalloc(size, GFP_KERNEL);
+
+				if (variables[i] == 0) {
+					status = JBIC_OUT_OF_MEMORY;
+				} else {
+					/* zero out memory */
+					for (j = 0; j < size; ++j)
+						/*64 bits*/
+						((u8 *)(variables[i]))[j] = 0;
+
+				}
+			} else
+				variables[i] = 0;
+
+		} else
+			variables[i] = 0;
+
+	}
+
+exit_done:
+	if (status != JBIC_SUCCESS)
+		done = 1;
+
+	jbi_init_jtag();
+
+	pc = code_section;
+	message_buffer[0] = '\0';
+
+	/*
+	For JBC version 2, we will execute the procedures corresponding to
+	the selected ACTION */
+	if (version > 0) {
+		if (astate->action == NULL) {
+			status = JBIC_ACTION_NOT_FOUND;
+			done = 1;
+		} else {
+			int action_found = 0;
+			for (i = 0; (i < action_count) && !action_found; ++i) {
+				name_id = GET_DWORD(action_table + (12 * i));
+
+				name = (char *)&program[string_table + name_id];
+
+				if (jbi_stricmp(astate->action, name) == 0) {
+					action_found = 1;
+					current_proc = (int)
+							GET_DWORD(action_table +
+								(12 * i) + 8);
+				}
+			}
+
+			if (!action_found) {
+				status = JBIC_ACTION_NOT_FOUND;
+				done = 1;
+			}
+		}
+
+		if (status == JBIC_SUCCESS) {
+			int first_time = 1;
+			i = current_proc;
+			while ((i != 0) || first_time) {
+				first_time = 0;
+				/* check procedure attribute byte */
+				proc_attributes[i] = (u8)
+						(GET_BYTE(proc_table +
+								(13 * i) + 8) &
+									0x03);
+
+				/*
+				BIT0 - OPTIONAL
+				BIT1 - RECOMMENDED
+				BIT6 - FORCED OFF
+				BIT7 - FORCED ON
+				*/
+
+				i = (u32)GET_DWORD(proc_table + (13 * i) + 4);
+			}
+
+			/*
+			Set current_proc to the first procedure to be executed
+			*/
+			i = current_proc;
+			while ((i != 0) &&
+				((proc_attributes[i] == 1) ||
+				((proc_attributes[i] & 0xc0) == 0x40))) {

drivers/misc/stapl-altera/altera.c line 570

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+				i = (u32)GET_DWORD(proc_table + (13 * i) + 4);
+			}
+
+			if ((i != 0) || ((i == 0) && (current_proc == 0) &&
+				((proc_attributes[0] != 1) &&
+				((proc_attributes[0] & 0xc0) != 0x40)))) {
+				current_proc = i;
+				pc = code_section +
+					GET_DWORD(proc_table + (13 * i) + 9);
+				CHECK_PC;

See my comments above. The code will look cleaner if you use, instead of the macro, something like:

	if ((pc < code_section) || (pc >= debug_section)) 
		goto jbic_bounds_error;

(if you can simply abort the programming due to the error)

or

	if ((pc < code_section) || (pc >= debug_section)) 
		status = <error code>;

if you really need to program everything even knowing in advance that an error happened.

Quoted 30 lines
drivers/misc/stapl-altera/altera.c new file +30 -0
+			} else
+				/* there are no procedures to execute! */
+				done = 1;
+
+		}
+	}
+
+	message_buffer[0] = '\0';
+
+	while (!done) {
+		opcode = (u32)(GET_BYTE(pc) & 0xff);
+		opcode_address = pc;
+		++pc;
+
+		if (verbose > 1)
+			printk("opcode: %02x\n", opcode);
+
+		arg_count = (opcode >> 6) & 3;
+		for (i = 0; i < arg_count; ++i) {
+			args[i] = GET_DWORD(pc);
+			pc += 4;
+		}
+
+		switch (opcode) {
+		case 0x00: /* NOP  */
+			break;
+		case 0x01: /* DUP  */
+			if (jbi_check_stack(stack_ptr, 1, &status)) {
+				stack[stack_ptr] = stack[stack_ptr - 1];
+				++stack_ptr;

drivers/misc/stapl-altera/altera.c line 610

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+			}
+			break;
+		case 0x02: /* SWP  */
+			if (jbi_check_stack(stack_ptr, 2, &status)) {
+				long_temp = stack[stack_ptr - 2];
+				stack[stack_ptr - 2] = stack[stack_ptr - 1];
+				stack[stack_ptr - 1] = long_temp;
+			}
+			break;
+		case 0x03: /* ADD  */

hmm... the better would be to do:

enum altera_fpga_opcode {
	OP_NOP = 0,
	OP_DUP = 1,
	OP_SWP = 2,
	OP_ADD = 3,
	...
};

switch (obcode) {
case OP_NOP:

	/* do something */

...
}

The rest of the driver have the same problems as pointed above.

Please fix, and submit a version 2.

Thanks,
Mauro

Quoted 3,662 lines
drivers/misc/stapl-altera/altera.c new file +2129 -0
+			if (jbi_check_stack(stack_ptr, 2, &status)) {
+				--stack_ptr;
+				stack[stack_ptr - 1] += stack[stack_ptr];
+			}
+			break;
+		case 0x04: /* SUB  */
+			if (jbi_check_stack(stack_ptr, 2, &status)) {
+				--stack_ptr;
+				stack[stack_ptr - 1] -= stack[stack_ptr];
+			}
+			break;
+		case 0x05: /* MULT */
+			if (jbi_check_stack(stack_ptr, 2, &status)) {
+				--stack_ptr;
+				stack[stack_ptr - 1] *= stack[stack_ptr];
+			}
+			break;
+		case 0x06: /* DIV  */
+			if (jbi_check_stack(stack_ptr, 2, &status)) {
+				--stack_ptr;
+				stack[stack_ptr - 1] /= stack[stack_ptr];
+			}
+			break;
+		case 0x07: /* MOD  */
+			if (jbi_check_stack(stack_ptr, 2, &status)) {
+				--stack_ptr;
+				stack[stack_ptr - 1] %= stack[stack_ptr];
+			}
+			break;
+		case 0x08: /* SHL  */
+			if (jbi_check_stack(stack_ptr, 2, &status)) {
+				--stack_ptr;
+				stack[stack_ptr - 1] <<= stack[stack_ptr];
+			}
+			break;
+		case 0x09: /* SHR  */
+			if (jbi_check_stack(stack_ptr, 2, &status)) {
+				--stack_ptr;
+				stack[stack_ptr - 1] >>= stack[stack_ptr];
+			}
+			break;
+		case 0x0A: /* NOT  */
+			if (jbi_check_stack(stack_ptr, 1, &status))
+				stack[stack_ptr - 1] ^= (-1L);
+
+			break;
+		case 0x0B: /* AND  */
+			if (jbi_check_stack(stack_ptr, 2, &status)) {
+				--stack_ptr;
+				stack[stack_ptr - 1] &= stack[stack_ptr];
+			}
+			break;
+		case 0x0C: /* OR   */
+			if (jbi_check_stack(stack_ptr, 2, &status)) {
+				--stack_ptr;
+				stack[stack_ptr - 1] |= stack[stack_ptr];
+			}
+			break;
+		case 0x0D: /* XOR */
+			if (jbi_check_stack(stack_ptr, 2, &status)) {
+				--stack_ptr;
+				stack[stack_ptr - 1] ^= stack[stack_ptr];
+			}
+			break;
+		case 0x0E: /* INV */
+			if (!jbi_check_stack(stack_ptr, 1, &status))
+				break;
+			stack[stack_ptr - 1] = stack[stack_ptr - 1] ? 0L : 1L;
+			break;
+		case 0x0F: /* GT */
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			--stack_ptr;
+			stack[stack_ptr - 1] =
+				(stack[stack_ptr - 1] > stack[stack_ptr]) ?
+									1L : 0L;
+
+			break;
+		case 0x10: /* LT */
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			--stack_ptr;
+			stack[stack_ptr - 1] =
+				(stack[stack_ptr - 1] < stack[stack_ptr]) ?
+									1L : 0L;
+
+			break;
+		case 0x11: /* RET  */
+			if ((version > 0) && (stack_ptr == 0)) {
+				/*
+				We completed one of the main procedures
+				of an ACTION.
+				Find the next procedure
+				to be executed and jump to it.
+				If there are no more procedures, then EXIT.
+				*/
+				i = (u32)
+					GET_DWORD(proc_table +
+						(13 * current_proc) + 4);
+				while ((i != 0) &&
+					((proc_attributes[i] == 1) ||
+					((proc_attributes[i] & 0xc0) == 0x40)))
+					i = (u32)
+						GET_DWORD(proc_table +
+								(13 * i) + 4);
+
+				if (i == 0) {
+					/*
+					there are no procedures to execute! */
+					done = 1;
+					*exit_code = 0;	/* success */
+				} else {
+					current_proc = i;
+					pc = code_section +
+							GET_DWORD(proc_table +
+								(13 * i) + 9);
+					CHECK_PC;
+				}
+
+			} else
+				if (jbi_check_stack(stack_ptr, 1, &status)) {
+					pc = stack[--stack_ptr] + code_section;
+					CHECK_PC;
+					if (pc == code_section)
+						status = JBIC_BOUNDS_ERROR;
+
+				}
+
+			break;
+		case 0x12: /* CMPS */
+			/*
+			Array short compare
+			...stack 0 is source 1 value
+			...stack 1 is source 2 value
+			...stack 2 is mask value
+			...stack 3 is count
+			*/
+			if (jbi_check_stack(stack_ptr, 4, &status)) {
+				s32 a = stack[--stack_ptr];
+				s32 b = stack[--stack_ptr];
+				long_temp = stack[--stack_ptr];
+				count = (u32)stack[stack_ptr - 1];
+
+				if ((count < 1) || (count > 32))
+					status = JBIC_BOUNDS_ERROR;
+				else {
+					long_temp &= ((-1L) >> (32 - count));
+
+					stack[stack_ptr - 1] =
+					((a & long_temp) == (b & long_temp))
+								? 1L : 0L;
+				}
+			}
+			break;
+		case 0x13: /* PINT */
+			/*
+			PRINT add integer
+			...stack 0 is integer value
+			*/
+			if (!jbi_check_stack(stack_ptr, 1, &status))
+				break;
+			jbi_ltoa(&message_buffer[jbi_strlen(message_buffer)],
+						stack[--stack_ptr]);
+			break;
+		case 0x14: /* PRNT */
+			/* PRINT finish */
+			if (verbose)
+				printk(message_buffer, "\n");
+
+			message_buffer[0] = '\0';
+			break;
+		case 0x15: /* DSS  */
+			/*
+			DRSCAN short
+			...stack 0 is scan data
+			...stack 1 is count
+			*/
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			long_temp = stack[--stack_ptr];
+			count = (u32)stack[--stack_ptr];
+			jbi_make_dword(charbuf, long_temp);
+			status = jbi_do_drscan(astate, count, charbuf, 0);
+			break;
+		case 0x16: /* DSSC */
+			/*
+			DRSCAN short with capture
+			...stack 0 is scan data
+			...stack 1 is count
+			*/
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			long_temp = stack[--stack_ptr];
+			count = (u32)stack[stack_ptr - 1];
+			jbi_make_dword(charbuf, long_temp);
+			status = jbi_swap_dr(astate, count, charbuf,
+							0, charbuf, 0);
+			stack[stack_ptr - 1] = jbi_get_dword(charbuf);
+			break;
+		case 0x17: /* ISS  */
+			/*
+			IRSCAN short
+			...stack 0 is scan data
+			...stack 1 is count
+			*/
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			long_temp = stack[--stack_ptr];
+			count = (u32)stack[--stack_ptr];
+			jbi_make_dword(charbuf, long_temp);
+			status = jbi_do_irscan(astate, count, charbuf, 0);
+			break;
+		case 0x18: /* ISSC */
+			/*
+			IRSCAN short with capture
+			...stack 0 is scan data
+			...stack 1 is count
+			*/
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			long_temp = stack[--stack_ptr];
+			count = (u32)stack[stack_ptr - 1];
+			jbi_make_dword(charbuf, long_temp);
+			status = jbi_swap_ir(astate, count, charbuf,
+							0, charbuf, 0);
+			stack[stack_ptr - 1] = jbi_get_dword(charbuf);
+			break;
+		case 0x19: /* VSS  */
+			/*
+			VECTOR short
+			...stack 0 is scan data
+			...stack 1 is count
+			*/
+			bad_opcode = 1;
+			break;
+		case 0x1A: /* VSSC */
+			/*
+			VECTOR short with capture
+			...stack 0 is scan data
+			...stack 1 is count
+			*/
+			bad_opcode = 1;
+			break;
+		case 0x1B: /* VMPF */
+			/* VMAP finish */
+			bad_opcode = 1;
+			break;
+		case 0x1C: /* DPR  */
+			if (!jbi_check_stack(stack_ptr, 1, &status))
+				break;
+			count = (u32)stack[--stack_ptr];
+			status = jbi_set_dr_preamble(count, 0, NULL);
+			break;
+		case 0x1D: /* DPRL */
+			/*
+			DRPRE with literal data
+			...stack 0 is count
+			...stack 1 is literal data
+			*/
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			count = (u32)stack[--stack_ptr];
+			long_temp = stack[--stack_ptr];
+			jbi_make_dword(charbuf, long_temp);
+			status = jbi_set_dr_preamble(count, 0, charbuf);
+			break;
+		case 0x1E: /* DPO  */
+			/*
+			DRPOST
+			...stack 0 is count
+			*/
+			if (jbi_check_stack(stack_ptr, 1, &status)) {
+				count = (u32)stack[--stack_ptr];
+				status = jbi_set_dr_postamble(count, 0, NULL);
+			}
+			break;
+		case 0x1F: /* DPOL */
+			/*
+			DRPOST with literal data
+			...stack 0 is count
+			...stack 1 is literal data
+			*/
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			count = (u32)stack[--stack_ptr];
+			long_temp = stack[--stack_ptr];
+			jbi_make_dword(charbuf, long_temp);
+			status = jbi_set_dr_postamble(count, 0, charbuf);
+			break;
+		case 0x20: /* IPR  */
+			if (jbi_check_stack(stack_ptr, 1, &status)) {
+				count = (u32)stack[--stack_ptr];
+				status = jbi_set_ir_preamble(count, 0, NULL);
+			}
+			break;
+		case 0x21: /* IPRL */
+			/*
+			IRPRE with literal data
+			...stack 0 is count
+			...stack 1 is literal data
+			*/
+			if (jbi_check_stack(stack_ptr, 2, &status)) {
+				count = (u32)stack[--stack_ptr];
+				long_temp = stack[--stack_ptr];
+				jbi_make_dword(charbuf, long_temp);
+				status = jbi_set_ir_preamble(count, 0, charbuf);
+			}
+			break;
+		case 0x22: /* IPO  */
+			/*
+			IRPOST
+			...stack 0 is count
+			*/
+			if (jbi_check_stack(stack_ptr, 1, &status)) {
+				count = (u32)stack[--stack_ptr];
+				status = jbi_set_ir_postamble(count, 0, NULL);
+			}
+			break;
+		case 0x23: /* IPOL */
+			/*
+			IRPOST with literal data
+			...stack 0 is count
+			...stack 1 is literal data
+			*/
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			count = (u32)stack[--stack_ptr];
+			long_temp = stack[--stack_ptr];
+			jbi_make_dword(charbuf, long_temp);
+			status = jbi_set_ir_postamble(count, 0, charbuf);
+			break;
+		case 0x24: /* PCHR */
+			if (jbi_check_stack(stack_ptr, 1, &status)) {
+				u8 ch;
+				count = jbi_strlen(message_buffer);
+				ch = (char) stack[--stack_ptr];
+				if ((ch < 1) || (ch > 127)) {
+					/*
+					character code out of range
+					instead of flagging an error,
+					force the value to 127 */
+					ch = 127;
+				}
+				message_buffer[count] = ch;
+				message_buffer[count + 1] = '\0';
+			}
+			break;
+		case 0x25: /* EXIT */
+			if (jbi_check_stack(stack_ptr, 1, &status))
+				*exit_code = (int) stack[--stack_ptr];
+
+			done = 1;
+			break;
+		case 0x26: /* EQU  */
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			--stack_ptr;
+			stack[stack_ptr - 1] =
+				(stack[stack_ptr - 1] == stack[stack_ptr]) ?
+									1L : 0L;
+			break;
+		case 0x27: /* POPT  */
+			if (jbi_check_stack(stack_ptr, 1, &status))
+				--stack_ptr;
+
+			break;
+		case 0x28: /* TRST  */
+			bad_opcode = 1;
+			break;
+
+		case 0x29: /* FRQ   */
+			bad_opcode = 1;
+			break;
+		case 0x2A: /* FRQU  */
+			bad_opcode = 1;
+			break;
+		case 0x2B: /* PD32  */
+			bad_opcode = 1;
+			break;
+		case 0x2C: /* ABS   */
+			if (!jbi_check_stack(stack_ptr, 1, &status))
+				break;
+			if (stack[stack_ptr - 1] < 0)
+				stack[stack_ptr - 1] = 0 - stack[stack_ptr - 1];
+
+			break;
+		case 0x2D: /* BCH0  */
+			/*
+			Batch operation 0
+			SWP
+			SWPN 7
+			SWP
+			SWPN 6
+			DUPN 8
+			SWPN 2
+			SWP
+			DUPN 6
+			DUPN 6
+			*/
+
+			/* SWP  */
+			if (jbi_check_stack(stack_ptr, 2, &status)) {
+				long_temp = stack[stack_ptr - 2];
+				stack[stack_ptr - 2] = stack[stack_ptr - 1];
+				stack[stack_ptr - 1] = long_temp;
+			}
+
+			/* SWPN 7 */
+			index = 7 + 1;
+			if (jbi_check_stack(stack_ptr, index, &status)) {
+				long_temp = stack[stack_ptr - index];
+				stack[stack_ptr - index] = stack[stack_ptr - 1];
+				stack[stack_ptr - 1] = long_temp;
+			}
+
+			/* SWP  */
+			if (jbi_check_stack(stack_ptr, 2, &status)) {
+				long_temp = stack[stack_ptr - 2];
+				stack[stack_ptr - 2] = stack[stack_ptr - 1];
+				stack[stack_ptr - 1] = long_temp;
+			}
+
+			/* SWPN 6 */
+			index = 6 + 1;
+			if (jbi_check_stack(stack_ptr, index, &status)) {
+				long_temp = stack[stack_ptr - index];
+				stack[stack_ptr - index] = stack[stack_ptr - 1];
+				stack[stack_ptr - 1] = long_temp;
+			}
+
+			/* DUPN 8 */
+			index = 8 + 1;
+			if (jbi_check_stack(stack_ptr, index, &status)) {
+				stack[stack_ptr] = stack[stack_ptr - index];
+				++stack_ptr;
+			}
+
+			/* SWPN 2 */
+			index = 2 + 1;
+			if (jbi_check_stack(stack_ptr, index, &status)) {
+				long_temp = stack[stack_ptr - index];
+				stack[stack_ptr - index] = stack[stack_ptr - 1];
+				stack[stack_ptr - 1] = long_temp;
+			}
+
+			/* SWP  */
+			if (jbi_check_stack(stack_ptr, 2, &status)) {
+				long_temp = stack[stack_ptr - 2];
+				stack[stack_ptr - 2] = stack[stack_ptr - 1];
+				stack[stack_ptr - 1] = long_temp;
+			}
+
+			/* DUPN 6 */
+			index = 6 + 1;
+			if (jbi_check_stack(stack_ptr, index, &status)) {
+				stack[stack_ptr] = stack[stack_ptr - index];
+				++stack_ptr;
+			}
+
+			/* DUPN 6 */
+			index = 6 + 1;
+			if (jbi_check_stack(stack_ptr, index, &status)) {
+				stack[stack_ptr] = stack[stack_ptr - index];
+				++stack_ptr;
+			}
+			break;
+		case 0x2E: /* BCH1  */
+			/*
+			Batch operation 1
+			SWPN 8
+			SWP
+			SWPN 9
+			SWPN 3
+			SWP
+			SWPN 2
+			SWP
+			SWPN 7
+			SWP
+			SWPN 6
+			DUPN 5
+			DUPN 5
+			*/
+			bad_opcode = 1;
+			break;
+		case 0x2F: /* PSH0  */
+			stack[stack_ptr++] = 0;
+			break;
+		case 0x40: /* PSHL */
+			stack[stack_ptr++] = (s32) args[0];
+			break;
+		case 0x41: /* PSHV */
+			stack[stack_ptr++] = variables[args[0]];
+			break;
+		case 0x42: /* JMP  */
+			pc = args[0] + code_section;
+			CHECK_PC;
+			break;
+		case 0x43: /* CALL */
+			stack[stack_ptr++] = pc;
+			pc = args[0] + code_section;
+			CHECK_PC;
+			break;
+		case 0x44: /* NEXT */
+			/*
+			Process FOR / NEXT loop
+			...argument 0 is variable ID
+			...stack 0 is step value
+			...stack 1 is end value
+			...stack 2 is top address
+			*/
+			if (jbi_check_stack(stack_ptr, 3, &status)) {
+				s32 step = stack[stack_ptr - 1];
+				s32 end = stack[stack_ptr - 2];
+				s32 top = stack[stack_ptr - 3];
+				s32 iterator = variables[args[0]];
+				int break_out = 0;
+
+				if (step < 0) {
+					if (iterator <= end)
+						break_out = 1;
+				} else if (iterator >= end)
+					break_out = 1;
+
+				if (break_out) {
+					stack_ptr -= 3;
+				} else {
+					variables[args[0]] = iterator + step;
+					pc = top + code_section;
+					CHECK_PC;
+				}
+			}
+			break;
+		case 0x45: /* PSTR */
+			/*
+			PRINT add string
+			...argument 0 is string ID
+			*/
+			count = jbi_strlen(message_buffer);
+			jbi_strncpy(&message_buffer[count],
+				(char *)&program[string_table + args[0]],
+				JBIC_MESSAGE_LENGTH - count);
+			message_buffer[JBIC_MESSAGE_LENGTH] = '\0';
+			break;
+		case 0x46: /* VMAP */
+			/*
+			VMAP add signal name
+			...argument 0 is string ID
+			*/
+			bad_opcode = 1;
+			break;
+		case 0x47: /* SINT */
+			/*
+			STATE intermediate state
+			...argument 0 is state code
+			*/
+			status = jbi_goto_jtag_state(astate, (int) args[0]);
+			break;
+		case 0x48: /* ST   */
+			/*
+			STATE final state
+			...argument 0 is state code
+			*/
+			status = jbi_goto_jtag_state(astate, (int) args[0]);
+			break;
+		case 0x49: /* ISTP */
+			/*
+			IRSTOP state
+			...argument 0 is state code
+			*/
+			status = jbi_set_irstop_state((int) args[0]);
+			break;
+		case 0x4A: /* DSTP */
+			/*
+			DRSTOP state
+			...argument 0 is state code
+			*/
+			status = jbi_set_drstop_state((int) args[0]);
+			break;
+
+		case 0x4B: /* SWPN */
+			/*
+			Exchange top with Nth stack value
+			...argument 0 is 0-based stack entry
+			to swap with top element
+			*/
+			index = ((int) args[0]) + 1;
+			if (jbi_check_stack(stack_ptr, index, &status)) {
+				long_temp = stack[stack_ptr - index];
+				stack[stack_ptr - index] = stack[stack_ptr - 1];
+				stack[stack_ptr - 1] = long_temp;
+			}
+			break;
+		case 0x4C: /* DUPN */
+			/*
+			Duplicate Nth stack value
+			...argument 0 is 0-based stack entry to duplicate
+			*/
+			index = ((int) args[0]) + 1;
+			if (jbi_check_stack(stack_ptr, index, &status)) {
+				stack[stack_ptr] = stack[stack_ptr - index];
+				++stack_ptr;
+			}
+			break;
+		case 0x4D: /* POPV */
+			/*
+			* Pop stack into scalar variable
+			...argument 0 is variable ID
+			...stack 0 is value
+			*/
+			if (jbi_check_stack(stack_ptr, 1, &status))
+				variables[args[0]] = stack[--stack_ptr];
+
+			break;
+		case 0x4E: /* POPE */
+			/*
+			Pop stack into integer array element
+			...argument 0 is variable ID
+			...stack 0 is array index
+			...stack 1 is value
+			*/
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			variable_id = (u32)args[0];
+
+			/*
+			If variable is read-only,
+			convert to writable array */
+			if ((version > 0) &&
+				((attributes[variable_id] & 0x9c) == 0x1c)) {
+				/* Allocate a writable buffer for this array */
+				count = (u32)variable_size[variable_id];
+				long_temp = variables[variable_id];
+				/*64 bits*/
+				longptr_temp = (long *)
+					kmalloc(count * sizeof(long),
+								GFP_KERNEL);
+				/*64 bits*/
+				variables[variable_id] = (long)longptr_temp;
+
+				if (variables[variable_id] == 0) {
+					status = JBIC_OUT_OF_MEMORY;
+					break;
+				}
+
+				/* copy previous contents into buffer */
+				for (i = 0; i < count; ++i) {
+					/*64 QWORD?*/
+					longptr_temp[i] = GET_DWORD(long_temp);
+					long_temp += sizeof(long);/*64*/
+				}
+
+				/*
+				set bit 7 - buffer was
+				dynamically allocated */
+				attributes[variable_id] |= 0x80;
+
+				/* clear bit 2 - variable is writable */
+				attributes[variable_id] &= ~0x04;
+				attributes[variable_id] |= 0x01;
+
+			}
+
+			/* check that variable is a writable integer array */
+			if ((attributes[variable_id] & 0x1c) != 0x18)
+				status = JBIC_BOUNDS_ERROR;
+			else {
+				/*64 bits*/
+				longptr_temp = (long *)variables[variable_id];
+
+				/* pop the array index */
+				index = (u32)stack[--stack_ptr];
+
+				/* pop the value and store it into the array */
+				longptr_temp[index] = stack[--stack_ptr];
+			}
+
+			break;
+		case 0x4F: /* POPA */
+			/*
+			Pop stack into Boolean array
+			...argument 0 is variable ID
+			...stack 0 is count
+			...stack 1 is array index
+			...stack 2 is value
+			*/
+			if (!jbi_check_stack(stack_ptr, 3, &status))
+				break;
+			variable_id = (u32)args[0];
+
+			/*
+			If variable is read-only, convert to writable array */
+			if ((version > 0) &&
+				((attributes[variable_id] & 0x9c) == 0x0c)) {
+				/* Allocate a writable buffer for this array */
+				long_temp =
+					(variable_size[variable_id] + 7L) >> 3L;
+				charptr_temp2 = (u8 *)variables[variable_id];
+				charptr_temp =
+					kmalloc((u32)long_temp, GFP_KERNEL);
+				/*64 bits*/
+				variables[variable_id] = (long)charptr_temp;
+
+				if (variables[variable_id] == 0) {
+					status = JBIC_OUT_OF_MEMORY;
+					break;
+				}
+
+				/* zero the buffer */
+				for (long_index = 0L;
+					long_index < long_temp;
+					++long_index) {
+					charptr_temp[long_index] = 0;
+				}
+
+				/* copy previous contents into buffer */
+				for (long_index = 0L;
+					long_index < variable_size[variable_id];
+					++long_index) {
+					long_index2 = long_index;
+
+					if (charptr_temp2[long_index2 >> 3] &
+						(1 << (long_index2 & 7))) {
+						charptr_temp[long_index >> 3] |=
+							(1 << (long_index & 7));
+					}
+				}
+
+				/*
+				set bit 7 - buffer was dynamically allocated */
+				attributes[variable_id] |= 0x80;
+
+				/* clear bit 2 - variable is writable */
+				attributes[variable_id] &= ~0x04;
+				attributes[variable_id] |= 0x01;
+
+			}
+
+			/*
+			check that variable is
+			a writable Boolean array */
+			if ((attributes[variable_id] & 0x1c) != 0x08) {
+				status = JBIC_BOUNDS_ERROR;
+				break;
+			}
+
+			charptr_temp = (u8 *)variables[variable_id];
+
+			/* pop the count (number of bits to copy) */
+			long_count = stack[--stack_ptr];
+
+			/* pop the array index */
+			long_index = stack[--stack_ptr];
+
+			reverse = 0;
+
+			if (version > 0) {
+				/*
+				stack 0 = array right index
+				stack 1 = array left index */
+
+				if (long_index > long_count) {
+					reverse = 1;
+					long_temp = long_count;
+					long_count = 1 + long_index -
+								long_count;
+					long_index = long_temp;
+
+					/* reverse POPA is not supported */
+					status = JBIC_BOUNDS_ERROR;
+					break;
+				} else
+					long_count = 1 + long_count -
+								long_index;
+
+			}
+
+			/* pop the data */
+			long_temp = stack[--stack_ptr];
+
+			if (long_count < 1) {
+				status = JBIC_BOUNDS_ERROR;
+				break;
+			}
+
+			for (i = 0; i < (u32)long_count; ++i) {
+				if (long_temp & (1L << (s32) i))
+					charptr_temp[long_index >> 3L] |=
+						(1L << (long_index & 7L));
+				else
+					charptr_temp[long_index >> 3L] &=
+						~(u32)(1L << (long_index & 7L));
+
+				++long_index;
+			}
+
+			break;
+		case 0x50: /* JMPZ */
+			/*
+			Pop stack and branch if zero
+			...argument 0 is address
+			...stack 0 is condition value
+			*/
+			if (jbi_check_stack(stack_ptr, 1, &status)) {
+				if (stack[--stack_ptr] == 0) {
+					pc = args[0] + code_section;
+					CHECK_PC;
+				}
+			}
+			break;
+		case 0x51: /* DS   */
+		case 0x52: /* IS   */
+			/*
+			DRSCAN
+			IRSCAN
+			...argument 0 is scan data variable ID
+			...stack 0 is array index
+			...stack 1 is count
+			*/
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			long_index = stack[--stack_ptr];
+			long_count = stack[--stack_ptr];
+			reverse = 0;
+			if (version > 0) {
+				/*
+				stack 0 = array right index
+				stack 1 = array left index
+				stack 2 = count */
+				long_temp = long_count;
+				long_count = stack[--stack_ptr];
+
+				if (long_index > long_temp) {
+					reverse = 1;
+					long_index = long_temp;
+				}
+			}
+
+			charptr_temp = (u8 *)variables[args[0]];
+
+			if (reverse) {
+				/*
+				allocate a buffer and reverse the data order */
+				charptr_temp2 = charptr_temp;
+				charptr_temp = kmalloc((long_count >> 3) + 1,
+								GFP_KERNEL);
+				if (charptr_temp == NULL) {
+					status = JBIC_OUT_OF_MEMORY;
+					break;
+				}
+
+				long_temp = long_index + long_count - 1;
+				long_index2 = 0;
+				while (long_index2 < long_count) {
+					if (charptr_temp2[long_temp >> 3] &
+							(1 << (long_temp & 7)))
+						charptr_temp[long_index2 >> 3] |= (1 << (long_index2 & 7));
+					else
+						charptr_temp[long_index2 >> 3] &= ~(1 << (long_index2 & 7));
+
+					--long_temp;
+					++long_index2;
+				}
+			}
+
+			if (opcode == 0x51) /* DS */
+				status = jbi_do_drscan(astate, (u32)long_count,
+						charptr_temp, (u32)long_index);
+			else /* IS */
+				status = jbi_do_irscan(astate, (u32)long_count,
+						charptr_temp, (u32)long_index);
+
+			if (reverse && (charptr_temp != NULL))
+				kfree(charptr_temp);
+
+			break;
+		case 0x53: /* DPRA */
+			/*
+			DRPRE with array data
+			...argument 0 is variable ID
+			...stack 0 is array index
+			...stack 1 is count
+			*/
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			index = (u32)stack[--stack_ptr];
+			count = (u32)stack[--stack_ptr];
+
+			if (version > 0)
+				/*
+				stack 0 = array right index
+				stack 1 = array left index */
+				count = 1 + count - index;
+
+			charptr_temp = (u8 *)variables[args[0]];
+			status = jbi_set_dr_preamble(count, index,
+							charptr_temp);
+			break;
+		case 0x54: /* DPOA */
+			/*
+			DRPOST with array data
+			...argument 0 is variable ID
+			...stack 0 is array index
+			...stack 1 is count
+			*/
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			index = (u32)stack[--stack_ptr];
+			count = (u32)stack[--stack_ptr];
+
+			if (version > 0)
+				/*
+				stack 0 = array right index
+				stack 1 = array left index */
+				count = 1 + count - index;
+
+			charptr_temp = (u8 *)variables[args[0]];
+			status = jbi_set_dr_postamble(count, index,
+							charptr_temp);
+			break;
+		case 0x55: /* IPRA */
+			/*
+			IRPRE with array data
+			...argument 0 is variable ID
+			...stack 0 is array index
+			...stack 1 is count
+			*/
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			index = (u32)stack[--stack_ptr];
+			count = (u32)stack[--stack_ptr];
+
+			if (version > 0)
+				/*
+				stack 0 = array right index
+				stack 1 = array left index */
+				count = 1 + count - index;
+
+			charptr_temp = (u8 *)variables[args[0]];
+			status = jbi_set_ir_preamble(count, index,
+							charptr_temp);
+
+			break;
+		case 0x56: /* IPOA */
+			/*
+			IRPOST with array data
+			...argument 0 is variable ID
+			...stack 0 is array index
+			...stack 1 is count
+			*/
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			index = (u32)stack[--stack_ptr];
+			count = (u32)stack[--stack_ptr];
+
+			if (version > 0)
+				/*
+				stack 0 = array right index
+				stack 1 = array left index */
+				count = 1 + count - index;
+
+			charptr_temp = (u8 *)variables[args[0]];
+			status = jbi_set_ir_postamble(count, index,
+							charptr_temp);
+
+			break;
+		case 0x57: /* EXPT */
+			/*
+			EXPORT
+			...argument 0 is string ID
+			...stack 0 is integer expression
+			*/
+			if (jbi_check_stack(stack_ptr, 1, &status)) {
+				name = (char *)&program[string_table + args[0]];
+				long_temp = stack[--stack_ptr];
+				jbi_export_integer(name, long_temp);
+			}
+			break;
+		case 0x58: /* PSHE */
+			/*
+			Push integer array element
+			...argument 0 is variable ID
+			...stack 0 is array index
+			*/
+			if (!jbi_check_stack(stack_ptr, 1, &status))
+				break;
+			variable_id = (u32)args[0];
+			index = (u32)stack[stack_ptr - 1];
+
+			/* check variable type */
+			if ((attributes[variable_id] & 0x1f) == 0x19) {
+				/* writable integer array */
+				longptr_temp = (long *)variables[variable_id];
+				stack[stack_ptr - 1] = longptr_temp[index];
+			} else if ((attributes[variable_id] & 0x1f) == 0x1c) {
+				/* read-only integer array */
+				long_temp = variables[variable_id] +
+						(sizeof(long) * index);/*64*/
+				stack[stack_ptr - 1] = GET_DWORD(long_temp);
+			} else
+				status = JBIC_BOUNDS_ERROR;
+
+			break;
+		case 0x59: /* PSHA */
+			/*
+			Push Boolean array
+			...argument 0 is variable ID
+			...stack 0 is count
+			...stack 1 is array index
+			*/
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			variable_id = (u32)args[0];
+
+			/* check that variable is a Boolean array */
+			if ((attributes[variable_id] & 0x18) != 0x08) {
+				status = JBIC_BOUNDS_ERROR;
+				break;
+			}
+
+			charptr_temp = (u8 *)variables[variable_id];
+
+			/* pop the count (number of bits to copy) */
+			count = (u32)stack[--stack_ptr];
+
+			/* pop the array index */
+			index = (u32)stack[stack_ptr - 1];
+
+			if (version > 0)
+				/* stack 0 = array right index */
+				/* stack 1 = array left index */
+				count = 1 + count - index;
+
+			if ((count < 1) || (count > 32)) {
+				status = JBIC_BOUNDS_ERROR;
+				break;
+			}
+
+			long_temp = 0L;
+
+			for (i = 0; i < count; ++i)
+				if (charptr_temp[(i + index) >> 3] &
+						(1 << ((i + index) & 7)))
+					long_temp |= (1L << i);
+
+			stack[stack_ptr - 1] = long_temp;
+
+			break;
+		case 0x5A: /* DYNA */
+			/*
+			Dynamically change size of array
+			...argument 0 is variable ID
+			...stack 0 is new size
+			*/
+			if (!jbi_check_stack(stack_ptr, 1, &status))
+				break;
+			variable_id = (u32)args[0];
+			long_temp = stack[--stack_ptr];
+
+			if (long_temp > variable_size[variable_id]) {
+				variable_size[variable_id] = long_temp;
+
+				if (attributes[variable_id] & 0x10)
+					/* allocate integer array */
+					long_temp *= sizeof(long);
+				else
+					/* allocate Boolean array */
+					long_temp = (long_temp + 7) >> 3;
+
+				/*
+				If the buffer was previously allocated,
+				free it */
+				if ((attributes[variable_id] & 0x80) &&
+						(variables[variable_id] != 0)) {
+					kfree((void *)variables[variable_id]);
+					variables[variable_id] = 0;
+				}
+
+				/*
+				Allocate a new buffer
+				of the requested size */
+				/*64 bits*/
+				variables[variable_id] = (long)
+					kmalloc((u32)long_temp, GFP_KERNEL);
+
+				if (variables[variable_id] == 0) {
+					status = JBIC_OUT_OF_MEMORY;
+					break;
+				}
+
+				/*
+				Set the attribute bit to indicate that
+				this buffer was dynamically allocated and
+				should be freed later */
+				attributes[variable_id] |= 0x80;
+
+				/* zero out memory */
+				count = (u32)
+					((variable_size[variable_id] + 7L) /
+									8L);
+				charptr_temp = (u8 *)(variables[variable_id]);
+				for (index = 0; index < count; ++index)
+					charptr_temp[index] = 0;
+
+			}
+
+			break;
+		case 0x5B: /* EXPR */
+			bad_opcode = 1;
+			break;
+		case 0x5C: /* EXPV */
+			/*
+			Export Boolean array
+			...argument 0 is string ID
+			...stack 0 is variable ID
+			...stack 1 is array right index
+			...stack 2 is array left index
+			*/
+			if (!jbi_check_stack(stack_ptr, 3, &status))
+				break;
+			if (version == 0) {
+				/* EXPV is not supported in JBC 1.0 */
+				bad_opcode = 1;
+				break;
+			}
+			name = (char *)&program[string_table + args[0]];
+			variable_id = (u32)stack[--stack_ptr];
+			long_index = stack[--stack_ptr];/* right indx */
+			long_index2 = stack[--stack_ptr];/* left indx */
+
+			if (long_index > long_index2) {
+				/* reverse indices not supported */
+				status = JBIC_BOUNDS_ERROR;
+				break;
+			}
+
+			long_count = 1 + long_index2 - long_index;
+
+			charptr_temp = (u8 *)variables[variable_id];
+			charptr_temp2 = NULL;
+
+			if ((long_index & 7L) != 0) {
+				s32 k = long_index;
+				charptr_temp2 = kmalloc((u32)
+					((long_count + 7L) / 8L), GFP_KERNEL);
+				if (charptr_temp2 == NULL) {
+					status = JBIC_OUT_OF_MEMORY;
+					break;
+				}
+
+				for (i = 0; i < (u32)long_count; ++i) {
+					if (charptr_temp[k >> 3] &
+							(1 << (k & 7)))
+						charptr_temp2[i >> 3] |=
+								(1 << (i & 7));
+					else
+						charptr_temp2[i >> 3] &=
+								~(1 << (i & 7));
+
+					++k;
+				}
+				charptr_temp = charptr_temp2;
+
+			} else if (long_index != 0)
+				charptr_temp = &charptr_temp[long_index >> 3];
+
+			jbi_export_boolean_array(name, charptr_temp,
+							long_count);
+
+			/* free allocated buffer */
+			if (((long_index & 7L) != 0) && (charptr_temp2 != NULL))
+				kfree(charptr_temp2);
+
+			break;
+		case 0x80: { /* COPY */
+			/*
+			Array copy
+			...argument 0 is dest ID
+			...argument 1 is source ID
+			...stack 0 is count
+			...stack 1 is dest index
+			...stack 2 is source index
+			*/
+			s32 copy_count;
+			s32 copy_index;
+			s32 copy_index2;
+			s32 destleft;
+			s32 src_count;
+			s32 dest_count;
+			int src_reverse = 0;
+			int dest_reverse = 0;
+
+			if (!jbi_check_stack(stack_ptr, 3, &status))
+				break;
+
+			copy_count = stack[--stack_ptr];
+			copy_index = stack[--stack_ptr];
+			copy_index2 = stack[--stack_ptr];
+			reverse = 0;
+
+			if (version > 0) {
+				/*
+				stack 0 = source right index
+				stack 1 = source left index
+				stack 2 = destination right index
+				stack 3 = destination left index */
+				destleft = stack[--stack_ptr];
+
+				if (copy_count > copy_index) {
+					src_reverse = 1;
+					reverse = 1;
+					src_count = 1 + copy_count - copy_index;
+					/* copy_index = source start index */
+				} else {
+					src_count = 1 + copy_index - copy_count;
+					/* source start index */
+					copy_index = copy_count;
+				}
+
+				if (copy_index2 > destleft) {
+					dest_reverse = 1;
+					reverse = !reverse;
+					dest_count = 1 + copy_index2 - destleft;
+					/* destination start index */
+					copy_index2 = destleft;
+				} else
+					dest_count = 1 + destleft - copy_index2;
+					/*
+					copy_index2 = destination start index */
+
+				copy_count = (src_count < dest_count) ?
+							src_count : dest_count;
+
+				if ((src_reverse || dest_reverse) &&
+					(src_count != dest_count))
+					/*
+					If either the source or destination
+					is reversed, we can't tolerate
+					a length mismatch, because we
+					"left justify" the arrays when copying.
+					This won't work correctly
+					with reversed arrays. */
+					status = JBIC_BOUNDS_ERROR;
+
+			}
+
+			count = (u32)copy_count;
+			index = (u32)copy_index;
+			index2 = (u32)copy_index2;
+
+			/*
+			If destination is a read-only array, allocate a buffer
+			and convert it to a writable array */
+			variable_id = (u32)args[1];
+			if ((version > 0) &&
+				((attributes[variable_id] & 0x9c) == 0x0c)) {
+				/* Allocate a writable buffer for this array */
+				long_temp =
+					(variable_size[variable_id] + 7L) >> 3L;
+				charptr_temp2 = (u8 *)variables[variable_id];
+				charptr_temp =
+					kmalloc((u32)long_temp, GFP_KERNEL);
+				/*64 bits*/
+				variables[variable_id] = (long)charptr_temp;
+
+				if (variables[variable_id] == 0) {
+					status = JBIC_OUT_OF_MEMORY;
+					break;
+				}
+
+				/* zero the buffer */
+				for (long_index = 0L; long_index < long_temp;
+								++long_index)
+					charptr_temp[long_index] = 0;
+
+				/* copy previous contents into buffer */
+				for (long_index = 0L;
+					long_index < variable_size[variable_id];
+								++long_index) {
+					long_index2 = long_index;
+
+					if (charptr_temp2[long_index2 >> 3] &
+						(1 << (long_index2 & 7)))
+						charptr_temp[long_index >> 3] |=
+							(1 << (long_index & 7));
+
+				}
+
+				/*
+				set bit 7 - buffer was dynamically allocated */
+				attributes[variable_id] |= 0x80;
+
+				/* clear bit 2 - variable is writable */
+				attributes[variable_id] &= ~0x04;
+				attributes[variable_id] |= 0x01;
+			}
+
+			charptr_temp = (u8 *)variables[args[1]];
+			charptr_temp2 = (u8 *)variables[args[0]];
+
+			/* check that destination is a writable Boolean array */
+			if ((attributes[args[1]] & 0x1c) != 0x08) {
+				status = JBIC_BOUNDS_ERROR;
+				break;
+			}
+
+			if (count < 1) {
+				status = JBIC_BOUNDS_ERROR;
+				break;
+			}
+
+			if (reverse)
+				index2 += (count - 1);
+
+			for (i = 0; i < count; ++i) {
+				if (charptr_temp2[index >> 3] &
+							(1 << (index & 7)))
+					charptr_temp[index2 >> 3] |=
+							(1 << (index2 & 7));
+				else
+					charptr_temp[index2 >> 3] &=
+						~(u32)(1 << (index2 & 7));
+
+				++index;
+				if (reverse)
+					--index2;
+				else
+					++index2;
+			}
+
+			break;
+		}
+		case 0x81: /* REVA */
+			/*
+			ARRAY COPY reversing bit order
+			...argument 0 is dest ID
+			...argument 1 is source ID
+			...stack 0 is dest index
+			...stack 1 is source index
+			...stack 2 is count
+			*/
+			bad_opcode = 1;
+			break;
+		case 0x82: /* DSC  */
+		case 0x83: { /* ISC  */
+			/*
+			DRSCAN with capture
+			IRSCAN with capture
+			...argument 0 is scan data variable ID
+			...argument 1 is capture variable ID
+			...stack 0 is capture index
+			...stack 1 is scan data index
+			...stack 2 is count
+			*/
+			s32 scan_right, scan_left;
+			s32 capture_count = 0;
+			s32 scan_count = 0;
+			s32 capture_index;
+			s32 scan_index;
+
+			if (!jbi_check_stack(stack_ptr, 3, &status))
+				break;
+
+			capture_index = stack[--stack_ptr];
+			scan_index = stack[--stack_ptr];
+
+			if (version > 0) {
+				/*
+				stack 0 = capture right index
+				stack 1 = capture left index
+				stack 2 = scan right index
+				stack 3 = scan left index
+				stack 4 = count */
+				scan_right = stack[--stack_ptr];
+				scan_left = stack[--stack_ptr];
+				capture_count = 1 + scan_index - capture_index;
+				scan_count = 1 + scan_left - scan_right;
+				scan_index = scan_right;
+			}
+
+			long_count = stack[--stack_ptr];
+			/*
+			If capture array is read-only, allocate a buffer
+			and convert it to a writable array */
+			variable_id = (u32)args[1];
+			if ((version > 0) &&
+				((attributes[variable_id] & 0x9c) == 0x0c)) {
+				/* Allocate a writable buffer for this array */
+				long_temp =
+					(variable_size[variable_id] + 7L) >> 3L;
+				charptr_temp2 = (u8 *)variables[variable_id];
+				charptr_temp =
+					kmalloc((u32)long_temp, GFP_KERNEL);
+				variables[variable_id] = (long)charptr_temp;
+
+				if (variables[variable_id] == 0) {
+					status = JBIC_OUT_OF_MEMORY;
+					break;
+				}
+
+				/* zero the buffer */
+				for (long_index = 0L; long_index < long_temp;
+								++long_index)
+					charptr_temp[long_index] = 0;
+
+				/* copy previous contents into buffer */
+				for (long_index = 0L;
+					long_index < variable_size[variable_id];
+								++long_index) {
+					long_index2 = long_index;
+
+					if (charptr_temp2[long_index2 >> 3] &
+						(1 << (long_index2 & 7)))
+						charptr_temp[long_index >> 3] |=
+							(1 << (long_index & 7));
+
+				}
+
+				/*
+				set bit 7 - buffer was
+				dynamically allocated */
+				attributes[variable_id] |= 0x80;
+
+				/* clear bit 2 - variable is writable */
+				attributes[variable_id] &= ~0x04;
+				attributes[variable_id] |= 0x01;
+
+			}
+
+			charptr_temp = (u8 *)variables[args[0]];
+			charptr_temp2 = (u8 *)variables[args[1]];
+
+			if ((version > 0) &&
+					((long_count > capture_count) ||
+					(long_count > scan_count))) {
+				status = JBIC_BOUNDS_ERROR;
+				break;
+			}
+
+			/*
+			check that capture array
+			is a writable Boolean array */
+			if ((attributes[args[1]] & 0x1c) != 0x08) {
+				status = JBIC_BOUNDS_ERROR;
+				break;
+			}
+
+			if (status == JBIC_SUCCESS) {
+				if (opcode == 0x82) /* DSC */
+					status = jbi_swap_dr(astate,
+							(u32)long_count,
+							charptr_temp,
+							(u32)scan_index,
+							charptr_temp2,
+							(u32)capture_index);
+				else /* ISC */
+					status = jbi_swap_ir(astate,
+							(u32)long_count,
+							charptr_temp,
+							(u32)scan_index,
+							charptr_temp2,
+							(u32)capture_index);
+
+			}
+
+			break;
+		}
+		case 0x84: /* WAIT */
+			/*
+			WAIT
+			...argument 0 is wait state
+			...argument 1 is end state
+			...stack 0 is cycles
+			...stack 1 is microseconds
+			*/
+			if (!jbi_check_stack(stack_ptr, 2, &status))
+				break;
+			long_temp = stack[--stack_ptr];
+
+			if (long_temp != 0L)
+				status = jbi_do_wait_cycles(astate, long_temp,
+								(u32)args[0]);
+
+			long_temp = stack[--stack_ptr];
+
+			if ((status == JBIC_SUCCESS) && (long_temp != 0L))
+				status = jbi_do_wait_microseconds(astate,
+								long_temp,
+								(u32)args[0]);
+
+			if ((status == JBIC_SUCCESS) && (args[1] != args[0]))
+				status = jbi_goto_jtag_state(astate,
+								(u32)args[1]);
+
+			if (version > 0) {
+				--stack_ptr; /* throw away MAX cycles */
+				--stack_ptr; /* throw away MAX microseconds */
+			}
+			break;
+		case 0x85: /* VS   */
+			/*
+			VECTOR
+			...argument 0 is dir data variable ID
+			...argument 1 is scan data variable ID
+			...stack 0 is dir array index
+			...stack 1 is scan array index
+			...stack 2 is count
+			*/
+			bad_opcode = 1;
+			break;
+		case 0xC0: { /* CMPA */
+			/*
+			Array compare
+			...argument 0 is source 1 ID
+			...argument 1 is source 2 ID
+			...argument 2 is mask ID
+			...stack 0 is source 1 index
+			...stack 1 is source 2 index
+			...stack 2 is mask index
+			...stack 3 is count
+			*/
+			s32 a, b;
+			u8 *source1 = (u8 *)variables[args[0]];
+			u8 *source2 = (u8 *)variables[args[1]];
+			u8 *mask = (u8 *)variables[args[2]];
+			u32 index1;
+			u32 index2;
+			u32 mask_index;
+
+			if (!jbi_check_stack(stack_ptr, 4, &status))
+				break;
+
+			index1 = stack[--stack_ptr];
+			index2 = stack[--stack_ptr];
+			mask_index = stack[--stack_ptr];
+			long_count = stack[--stack_ptr];
+
+			if (version > 0) {
+				/*
+				stack 0 = source 1 right index
+				stack 1 = source 1 left index
+				stack 2 = source 2 right index
+				stack 3 = source 2 left index
+				stack 4 = mask right index
+				stack 5 = mask left index */
+				s32 mask_right = stack[--stack_ptr];
+				s32 mask_left = stack[--stack_ptr];
+				/* source 1 count */
+				a = 1 + index2 - index1;
+				/* source 2 count */
+				b = 1 + long_count - mask_index;
+				a = (a < b) ? a : b;
+				/* mask count */
+				b = 1 + mask_left - mask_right;
+				a = (a < b) ? a : b;
+				/* source 2 start index */
+				index2 = mask_index;
+				/* mask start index */
+				mask_index = mask_right;
+				long_count = a;
+			}
+
+			long_temp = 1L;
+
+			if (long_count < 1)
+				status = JBIC_BOUNDS_ERROR;
+			else {
+				count = (u32)long_count;
+
+				for (i = 0; i < count; ++i) {
+					if (mask[mask_index >> 3] &
+						(1 << (mask_index & 7))) {
+						a = source1[index1 >> 3] &
+							(1 << (index1 & 7))
+								? 1 : 0;
+						b = source2[index2 >> 3] &
+							(1 << (index2 & 7))
+								? 1 : 0;
+
+						if (a != b) /* failure */
+							long_temp = 0L;
+					}
+					++index1;
+					++index2;
+					++mask_index;
+				}
+			}
+
+			stack[stack_ptr++] = long_temp;
+
+			break;
+		}
+		case 0xC1: /* VSC  */
+			/*
+			VECTOR with capture
+			...argument 0 is dir data variable ID
+			...argument 1 is scan data variable ID
+			...argument 2 is capture variable ID
+			...stack 0 is capture index
+			...stack 1 is scan data index
+			...stack 2 is dir data index
+			...stack 3 is count
+			*/
+			bad_opcode = 1;
+			break;
+		default:
+			/* Unrecognized opcode -- ERROR! */
+			bad_opcode = 1;
+			break;
+		}
+
+		if (bad_opcode)
+			status = JBIC_ILLEGAL_OPCODE;
+
+		if ((stack_ptr < 0) || (stack_ptr >= JBI_STACK_SIZE))
+			status = JBIC_STACK_OVERFLOW;
+
+		if (status != JBIC_SUCCESS) {
+			done = 1;
+			*error_address = (s32)(opcode_address - code_section);
+		}
+	}
+
+	jbi_free_jtag_padding_buffers(astate/*, reset_jtag*/);
+
+	/* Free all dynamically allocated arrays */
+	if ((attributes != NULL) && (variables != NULL)) {
+		for (i = 0; i < (u32)symbol_count; ++i) {
+			if ((attributes[i] & 0x80) && (variables[i] != 0))
+				kfree((void *)variables[i]);
+
+		}
+	}
+
+	if (variables != NULL)
+		kfree(variables);
+
+	if (variable_size != NULL)
+		kfree(variable_size);
+
+	if (attributes != NULL)
+		kfree(attributes);
+
+	if (proc_attributes != NULL)
+		kfree(proc_attributes);
+
+	return status;
+}
+
+static JBI_RETURN_TYPE jbi_get_note(u8 *program, s32 program_size,
+			s32 *offset, char *key, char *value, int length)
+/*
+Gets key and value of NOTE fields in the JBC file.
+Can be called in two modes:  if offset pointer is NULL,
+then the function searches for note fields which match
+the key string provided.  If offset is not NULL, then
+the function finds the next note field of any key,
+starting at the offset specified by the offset pointer.
+Returns JBIC_SUCCESS for success, else appropriate error code	*/
+{
+	JBI_RETURN_TYPE status = JBIC_UNEXPECTED_END;
+	u32 note_strings = 0L;
+	u32 note_table = 0L;
+	u32 note_count = 0L;
+	u32 first_word = 0L;
+	int version = 0;
+	int delta = 0;
+	char *key_ptr;
+	char *value_ptr;
+	int i;
+
+	/* Read header information */
+	if (program_size > 52L) {
+		first_word    = GET_DWORD(0);
+		version = (int)(first_word & 1L);
+		delta = version * 8;
+
+		note_strings  = GET_DWORD(8 + delta);
+		note_table    = GET_DWORD(12 + delta);
+		note_count    = GET_DWORD(44 + (2 * delta));
+	}
+
+	if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) {
+		status = JBIC_IO_ERROR;
+		return status;
+	}
+
+	if (note_count <= 0L)
+		return status;
+
+	if (offset == NULL) {
+		/*
+		We will search for the first note with a specific key,
+		and return only the value */
+		for (i = 0; (i < (int)note_count) &&
+						(status != JBIC_SUCCESS); ++i) {
+			key_ptr = (char *)
+					&program[note_strings +
+					GET_DWORD(note_table + (8 * i))];
+			if ((key != NULL) && (jbi_stricmp(key, key_ptr) == 0)) {
+				status = JBIC_SUCCESS;
+
+				value_ptr = (char *)
+					&program[note_strings +
+					GET_DWORD(note_table + (8 * i) + 4)];
+
+				if (value != NULL)
+					jbi_strncpy(value, value_ptr, length);
+
+			}
+		}
+	} else {
+		/*
+		We will search for the next note, regardless of the key,
+		and return both the value and the key */
+
+		i = (int)*offset;
+
+		if ((i >= 0) && (i < (int) note_count)) {
+			status = JBIC_SUCCESS;
+
+			if (key != NULL)
+				jbi_strncpy(key,
+					(char *)&program[note_strings +
+					GET_DWORD(note_table + (8 * i))],
+					length);
+
+			if (value != NULL)
+				jbi_strncpy(value,
+					(char *)&program[note_strings +
+					GET_DWORD(note_table + (8 * i) + 4)],
+					length);
+
+			*offset = i + 1;
+		}
+	}
+
+	return status;
+}
+
+static JBI_RETURN_TYPE jbi_check_crc(u8 *program, s32 program_size)
+{
+	JBI_RETURN_TYPE status = JBIC_SUCCESS;
+	u16 local_expected = 0,
+	    local_actual = 0,
+	    shift_reg = 0xffff;
+	int bit, feedback;
+	u8 databyte;
+	u32 i;
+	u32 crc_section = 0L;
+	u32 first_word = 0L;
+	int version = 0;
+	int delta = 0;
+
+	if (program_size > 52L) {
+		first_word  = GET_DWORD(0);
+		version = (int)(first_word & 1L);
+		delta = version * 8;
+
+		crc_section = GET_DWORD(32 + delta);
+	}
+
+	if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
+		status = JBIC_IO_ERROR;
+
+	if (crc_section >= (u32)program_size)
+		status = JBIC_IO_ERROR;
+
+	if (status == JBIC_SUCCESS) {
+		local_expected = (u16)GET_WORD(crc_section);
+
+		for (i = 0; i < crc_section; ++i) {
+			databyte = GET_BYTE(i);
+			for (bit = 0; bit < 8; bit++) {
+				feedback = (databyte ^ shift_reg) & 0x01;
+				shift_reg >>= 1;
+				if (feedback)
+					shift_reg ^= 0x8408;
+
+				databyte >>= 1;
+			}
+		}
+
+		local_actual = (u16)~shift_reg;
+
+		if (local_expected != local_actual)
+			status = JBIC_CRC_ERROR;
+
+	}
+
+	if (verbose || (status == JBIC_CRC_ERROR)) {
+		switch (status) {
+		case JBIC_SUCCESS:
+			printk(KERN_INFO "CRC matched: CRC value = %04X\n",
+								local_actual);
+			break;
+		case JBIC_CRC_ERROR:
+			printk(KERN_ERR "CRC mismatch: expected %04X, "
+				"actual %04X\n", local_expected, local_actual);
+			break;
+		case JBIC_UNEXPECTED_END:
+			printk(KERN_ERR "Expected CRC not found, "
+				"actual CRC = %04X\n", local_actual);
+			break;
+		case JBIC_IO_ERROR:
+			printk(KERN_ERR "Error: Format isn't recognized.\n");
+			break;
+		default:
+			printk(KERN_ERR "CRC function returned error code %d\n",
+									status);
+			break;
+		}
+	}
+
+	return status;
+}
+
+static JBI_RETURN_TYPE jbi_get_file_info(u8 *program,
+					s32 program_size,
+					int *format_version,
+					int *action_count,
+					int *procedure_count)
+{
+	JBI_RETURN_TYPE status = JBIC_IO_ERROR;
+	u32 first_word = 0;
+	int version = 0;
+
+	if (program_size <= 52L)
+		return status;
+
+	first_word = GET_DWORD(0);
+
+	if ((first_word == 0x4A414D00L) || (first_word == 0x4A414D01L)) {
+		status = JBIC_SUCCESS;
+
+		version = (int)(first_word & 1L);
+		*format_version = version + 1;
+
+		if (version > 0) {
+			*action_count = (int)GET_DWORD(48);
+			*procedure_count = (int)GET_DWORD(52);
+		}
+	}
+
+	return status;
+}
+
+static JBI_RETURN_TYPE jbi_get_action_info(u8 *program,
+					s32 program_size,
+					int index,
+					char **name,
+					char **description,
+					struct JBI_PROCINFO **procedure_list)
+{
+	JBI_RETURN_TYPE status = JBIC_IO_ERROR;
+	struct JBI_PROCINFO *procptr = NULL;
+	struct JBI_PROCINFO *tmpptr = NULL;
+	u32 first_word = 0L;
+	u32 action_table = 0L;
+	u32 proc_table = 0L;
+	u32 string_table = 0L;
+	u32 note_strings = 0L;
+	u32 action_count = 0L;
+	u32 proc_count = 0L;
+	u32 act_name_id = 0L;
+	u32 act_desc_id = 0L;
+	u32 act_proc_id = 0L;
+	u32 act_proc_name = 0L;
+	u8 act_proc_attribute = 0;
+
+	if (program_size <= 52L)
+		return status;
+	/* Read header information */
+	first_word = GET_DWORD(0);
+
+	if (first_word != 0x4A414D01L)
+		return status;
+
+	action_table = GET_DWORD(4);
+	proc_table   = GET_DWORD(8);
+	string_table = GET_DWORD(12);
+	note_strings = GET_DWORD(16);
+	action_count = GET_DWORD(48);
+	proc_count   = GET_DWORD(52);
+
+	if (index >= (int)action_count)
+		return status;
+
+	act_name_id = GET_DWORD(action_table + (12 * index));
+	act_desc_id = GET_DWORD(action_table + (12 * index) + 4);
+	act_proc_id = GET_DWORD(action_table + (12 * index) + 8);
+
+	*name = (char *)&program[string_table + act_name_id];
+
+	if (act_desc_id < (note_strings - string_table))
+		*description = (char *)&program[string_table + act_desc_id];
+
+	do {
+		act_proc_name = GET_DWORD(proc_table + (13 * act_proc_id));
+		act_proc_attribute = (u8)
+			(GET_BYTE(proc_table + (13 * act_proc_id) + 8) & 0x03);
+
+		procptr = (struct JBI_PROCINFO *)
+				kmalloc(sizeof(struct JBI_PROCINFO),
+								GFP_KERNEL);
+
+		if (procptr == NULL)
+			status = JBIC_OUT_OF_MEMORY;
+		else {
+			procptr->name = (char *)
+					&program[string_table + act_proc_name];
+			procptr->attributes = act_proc_attribute;
+			procptr->next = NULL;
+
+			/* add record to end of linked list */
+			if (*procedure_list == NULL)
+				*procedure_list = procptr;
+			else {
+				tmpptr = *procedure_list;
+				while (tmpptr->next != NULL)
+					tmpptr = tmpptr->next;
+				tmpptr->next = procptr;
+			}
+		}
+
+		act_proc_id = GET_DWORD(proc_table + (13 * act_proc_id) + 4);
+	} while ((act_proc_id != 0) && (act_proc_id < proc_count));
+
+	return status;
+}
+
+int altera_init(struct altera_config *config, const struct firmware *fw)
+{
+	static struct altera_config *astate;
+	static u8 key[33] = {0};
+	static u8 value[257] = {0};
+	char *action_name = NULL;
+	char *description = NULL;
+	char *exit_string = NULL;
+	struct JBI_PROCINFO *procedure_list = NULL;
+	struct JBI_PROCINFO *procptr = NULL;
+	JBI_RETURN_TYPE exec_result = JBIC_SUCCESS;
+	int exit_code = 0;
+	int format_version = 0;
+	int action_count = 0;
+	int procedure_count = 0;
+	int index = 0;
+	s32 offset = 0L;
+	s32 error_address = 0L;
+
+	astate = kzalloc(sizeof(struct altera_config), GFP_KERNEL);
+	if (!astate)
+		return -ENOMEM;
+
+	memcpy(astate, config, sizeof(struct altera_config));
+	if (!astate->jtag_io) {
+		printk(KERN_INFO "%s: using byteblaster!\n", __func__);
+		astate->jtag_io = netup_jtag_io_lpt;
+	}
+
+	jbi_check_crc((u8 *)fw->data, fw->size);
+
+	if (verbose) {
+		jbi_get_file_info((u8 *)fw->data, fw->size, &format_version,
+					&action_count, &procedure_count);
+		printk(KERN_INFO "File format is %s ByteCode format\n",
+			(format_version == 2) ? "Jam STAPL" :
+						"pre-standardized Jam 1.1");
+		while (jbi_get_note((u8 *)fw->data, fw->size,
+					&offset, key, value, 256) == 0)
+			printk(KERN_INFO "NOTE \"%s\" = \"%s\"\n", key, value);
+	}
+
+	if (verbose && (format_version == 2) && (action_count > 0)) {
+		printk(KERN_INFO "\nActions available in this file:\n");
+		for (index = 0; index < action_count; ++index) {
+			jbi_get_action_info((u8 *)fw->data, fw->size,
+						index, &action_name,
+						&description,
+						&procedure_list);
+
+			if (description == NULL)
+				printk(KERN_INFO "%s\n", action_name);
+			else
+				printk(KERN_INFO "%s \"%s\"\n", action_name,
+						description);
+
+			procptr = procedure_list;
+			while (procptr != NULL) {
+				if (procptr->attributes != 0)
+					printk(KERN_INFO "    %s (%s)\n",
+						procptr->name,
+						(procptr->attributes == 1) ?
+						"optional" : "recommended");
+
+				procedure_list = procptr->next;
+				kfree(procptr);
+				procptr = procedure_list;
+			}
+		}
+
+		printk(KERN_INFO "\n");
+	}
+
+	exec_result = jbi_execute(astate, (u8 *)fw->data, fw->size,
+				&error_address, &exit_code, &format_version);
+
+	if (exec_result == JBIC_SUCCESS) {
+		if (format_version == 2) {
+			switch (exit_code) {
+			case  0:
+				exit_string = "Success";
+				break;
+			case  1:
+				exit_string = "Checking chain failure";
+				break;
+			case  2:
+				exit_string = "Reading IDCODE failure";
+				break;
+			case  3:
+				exit_string = "Reading USERCODE failure";
+				break;
+			case  4:
+				exit_string = "Reading UESCODE failure";
+				break;
+			case  5:
+				exit_string = "Entering ISP failure";
+				break;
+			case  6:
+				exit_string = "Unrecognized device";
+				break;
+			case  7:
+				exit_string = "Device revision is "
+						"not supported";
+				break;
+			case  8:
+				exit_string = "Erase failure";
+				break;
+			case  9:
+				exit_string = "Device is not blank";
+				break;
+			case 10:
+				exit_string = "Device programming failure";
+				break;
+			case 11:
+				exit_string = "Device verify failure";
+				break;
+			case 12:
+				exit_string = "Read failure";
+				break;
+			case 13:
+				exit_string = "Calculating checksum failure";
+				break;
+			case 14:
+				exit_string = "Setting security bit failure";
+				break;
+			case 15:
+				exit_string = "Querying security bit failure";
+				break;
+			case 16:
+				exit_string = "Exiting ISP failure";
+				break;
+			case 17:
+				exit_string = "Performing system test failure";
+				break;
+			default:
+				exit_string = "Unknown exit code";
+				break;
+			}
+		} else {
+			switch (exit_code) {
+			case 0:
+				exit_string = "Success";
+				break;
+			case 1:
+				exit_string = "Illegal initialization values";
+				break;
+			case 2:
+				exit_string = "Unrecognized device";
+				break;
+			case 3:
+				exit_string = "Device revision is "
+						"not supported";
+				break;
+			case 4:
+				exit_string = "Device programming failure";
+				break;
+			case 5:
+				exit_string = "Device is not blank";
+				break;
+			case 6:
+				exit_string = "Device verify failure";
+				break;
+			case 7:
+				exit_string = "SRAM configuration failure";
+				break;
+			default:
+				exit_string = "Unknown exit code";
+				break;
+			}
+		}
+
+		printk(KERN_INFO "Exit code = %d... %s\n", exit_code,
+							exit_string);
+	} else if ((format_version == 2) &&
+			(exec_result == JBIC_ACTION_NOT_FOUND)) {
+		if ((astate->action == NULL) || (*astate->action == '\0'))
+			printk(KERN_ERR "Error: no action specified for "
+				"Jam STAPL file.\nProgram terminated.\n");
+		else
+			printk(KERN_ERR "Error: action \"%s\" is not supported "
+				"for this Jam STAPL file.\n"
+				"Program terminated.\n",
+				astate->action);
+
+	} else if (exec_result < MAX_ERROR_CODE) {
+		printk(KERN_ERR "Error at address %d: %s.\n"
+			"Program terminated.\n",
+			error_address, error_text[exec_result]);
+	} else
+		printk(KERN_ERR "Unknown error code %d\n", exec_result);
+
+	if (astate != NULL) {
+		kfree(astate);
+		astate = NULL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(altera_init);
drivers/misc/stapl-altera/jbicomp.c new file +163 -0
new file mode 100644
index 0000000..5e09ec7
@@ -0,0 +1,163 @@
+/*
+ * jbicomp.c
+ *
+ * altera FPGA driver
+ *
+ * Copyright (C) Altera Corporation 1998-2001
+ * Copyright (C) 2010 NetUP Inc.
+ * Copyright (C) 2010 Igor M. Liplianin <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include "jbiexprt.h"
+
+#define	SHORT_BITS		16
+#define	CHAR_BITS		8
+#define	DATA_BLOB_LENGTH	3
+#define	MATCH_DATA_LENGTH	8192
+#define JBI_ACA_REQUEST_SIZE	1024
+#define JBI_ACA_BUFFER_SIZE	(MATCH_DATA_LENGTH + JBI_ACA_REQUEST_SIZE)
+
+u32 jbi_in_length = 0L;
+u32 jbi_in_index = 0L;	/* byte index into compressed array */
+u32 jbi_bits_avail = CHAR_BITS;
+
+/*
+The following functions implement incremental decompression of Boolean
+array data, using a small memory window.
+This algorithm works by searching previous bytes in the data that match
+the current data. If a match is found, then the offset and length of
+the matching data can replace the actual data in the output.
+Memory usage is reduced by maintaining a "window" buffer which contains/
+the uncompressed data for one 8K page, plus some extra amount specified/
+by JBI_ACA_REQUEST_SIZE.  The function jbi_uncompress_page() is used to/
+request a subrange of the uncompressed data, starting at a particular
+bit position and extending a maximum of JBI_ACA_REQUEST_SIZE bytes. */
+
+static u32 jbi_bits_required(u32 n)
+/*
+Calculate the minimum number of bits required to represent n.
+Returns number of bits. */
+{
+	u32 result = SHORT_BITS;
+
+	if (n == 0)
+		result = 1;
+	else {
+		/* Look for the highest non-zero bit position */
+		while ((n & (1 << (SHORT_BITS - 1))) == 0) {
+			n <<= 1;
+			--result;
+		}
+	}
+
+	return result;
+}
+
+static u32 jbi_read_packed(u8 *buffer, u32 bits)
+/*
+Read the next value from the input array "buffer"
+Read only "bits" bits from the array. The amount of
+bits that have already been read from "buffer" is
+stored internally to this function.
+Returns up to 16 bit value or -1 if buffer overrun. */
+{
+	u32 result = 0;
+	u32 shift = 0;
+	u32 databyte = 0;
+
+	while (bits > 0) {
+		databyte = buffer[jbi_in_index];
+		result |= (((databyte >> (CHAR_BITS - jbi_bits_avail))
+			& (0xff >> (CHAR_BITS - jbi_bits_avail))) << shift);
+
+		if (bits <= jbi_bits_avail) {
+			result &= (0xffff >> (SHORT_BITS - (bits + shift)));
+			jbi_bits_avail -= bits;
+			bits = 0;
+		} else {
+			++jbi_in_index;
+			shift += jbi_bits_avail;
+			bits -= jbi_bits_avail;
+			jbi_bits_avail = CHAR_BITS;
+		}
+	}
+
+	return result;
+}
+
+u32 jbi_uncompress(u8 *in, u32 in_length, u8 *out, u32 out_length, s32 version)
+/*
+Uncompress data in "in" and write result to "out".
+Returns length of uncompressed data or -1 if:
+	1) out_length is too small
+	2) Internal error in the code
+	3) in doesn't contain ACA compressed data. */
+{
+	u32 i, j, data_length = 0L;
+	u32 offset, length;
+	u32 match_data_length = MATCH_DATA_LENGTH;
+
+	if (version > 0)
+		--match_data_length;
+
+	jbi_in_length = in_length;
+	jbi_bits_avail = CHAR_BITS;
+	jbi_in_index = 0L;
+	for (i = 0; i < out_length; ++i)
+		out[i] = 0;
+
+	/* Read number of bytes in data. */
+	for (i = 0; i < sizeof(in_length); ++i) {
+		data_length = data_length | ((u32)
+			jbi_read_packed(in, CHAR_BITS) << (i * CHAR_BITS));
+	}
+
+	if (data_length > out_length) {
+		data_length = 0L;
+		return data_length;
+	}
+
+	i = 0;
+	while (i < data_length) {
+		/* A 0 bit indicates literal data. */
+		if (jbi_read_packed(in, 1) == 0) {
+			for (j = 0; j < DATA_BLOB_LENGTH; ++j) {
+				if (i < data_length) {
+					out[i] = (u8)jbi_read_packed(in,
+								CHAR_BITS);
+					i++;
+				}
+			}
+		} else {
+			/* A 1 bit indicates offset/length to follow. */
+			offset = jbi_read_packed(in, jbi_bits_required((s16)
+					(i > match_data_length ?
+						match_data_length : i)));
+			length = jbi_read_packed(in, CHAR_BITS);
+			for (j = 0; j < length; ++j) {
+				if (i < data_length) {
+					out[i] = out[i - offset];
+					i++;
+				}
+			}
+		}
+	}
+
+	return data_length;
+}
drivers/misc/stapl-altera/jbiexprt.h new file +94 -0
new file mode 100644
index 0000000..351ddf3
@@ -0,0 +1,94 @@
+/*
+ * jbiexprt.h
+ *
+ * altera FPGA driver
+ *
+ * Copyright (C) Altera Corporation 1998-2001
+ * Copyright (C) 2010 NetUP Inc.
+ * Copyright (C) 2010 Igor M. Liplianin <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef INC_JBIEXPRT_H
+#define INC_JBIEXPRT_H
+
+/* Return codes from most JBI functions */
+
+#define JBI_RETURN_TYPE int
+
+#define JBIC_SUCCESS            0
+#define JBIC_OUT_OF_MEMORY      1
+#define JBIC_IO_ERROR           2
+/* #define JAMC_SYNTAX_ERROR       3 */
+#define JBIC_UNEXPECTED_END     4
+#define JBIC_UNDEFINED_SYMBOL   5
+/* #define JAMC_REDEFINED_SYMBOL   6 */
+#define JBIC_INTEGER_OVERFLOW   7
+#define JBIC_DIVIDE_BY_ZERO     8
+#define JBIC_CRC_ERROR          9
+#define JBIC_INTERNAL_ERROR    10
+#define JBIC_BOUNDS_ERROR      11
+/* #define JAMC_TYPE_MISMATCH     12 */
+/* #define JAMC_ASSIGN_TO_CONST   13 */
+/* #define JAMC_NEXT_UNEXPECTED   14 */
+/* #define JAMC_POP_UNEXPECTED    15 */
+/* #define JAMC_RETURN_UNEXPECTED 16 */
+/* #define JAMC_ILLEGAL_SYMBOL    17 */
+#define JBIC_VECTOR_MAP_FAILED 18
+#define JBIC_USER_ABORT        19
+#define JBIC_STACK_OVERFLOW    20
+#define JBIC_ILLEGAL_OPCODE    21
+/* #define JAMC_PHASE_ERROR       22 */
+/* #define JAMC_SCOPE_ERROR       23 */
+#define JBIC_ACTION_NOT_FOUND  24
+
+/* Macro Definitions */
+
+/* #define PROGRAM_PTR u8 *
+*/
+#define GET_BYTE(x) (program[x])
++
+#define GET_WORD(x) \
+	(((((u16) GET_BYTE(x)) << 8) & 0xFF00) | \
+	(((u16) GET_BYTE((x)+1)) & 0x00FF))
+
+#define GET_DWORD(x) \
+	(((((u32) GET_BYTE(x)) << 24L) & 0xFF000000L) | \
+	((((u32) GET_BYTE((x)+1)) << 16L) & 0x00FF0000L) | \
+	((((u32) GET_BYTE((x)+2)) << 8L) & 0x0000FF00L) | \
+	(((u32) GET_BYTE((x)+3)) & 0x000000FFL))
+
+/* #define GET_QWORD(x) \
+	(((((long)    GET_BYTE(x)) << 56L) & 0xFF00000000000000L) | \
+	((((long) GET_BYTE((x)+1)) << 48L) & 0xFF000000000000L) | \
[… more lines in the raw message]

Lines of this file are not shown. View the raw message.

drivers/misc/stapl-altera/jbijtag.c new file +1038 -0
new file mode 100644
index 0000000..b7645e5

Lines of this file are not shown. View the raw message.

drivers/misc/stapl-altera/jbijtag.h new file +83 -0
new file mode 100644
index 0000000..d31f302

Lines of this file are not shown. View the raw message.

drivers/misc/stapl-altera/jbistub.c new file +70 -0
new file mode 100644
index 0000000..9194afe

Lines of this file are not shown. View the raw message.

include/misc/altera.h new file +49 -0
new file mode 100644
index 0000000..bf6d878

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Part of the diff is not shown here. View the raw message.

#7 lore raw

В сообщении от 14 октября 2010 21:59:07 автор Mauro Carvalho Chehab написал:

Quoted 909 lines

Em 14-10-2010 15:11, Mauro Carvalho Chehab escreveu:

Quoted 232 lines

Em 03-10-2010 19:35, Igor M. Liplianin escreveu:

Quoted 94 lines

Patches to support for NetUP Dual DVB-T/C-CI RF from NetUP Inc.

http://linuxtv.org/wiki/index.php/NetUP_Dual_DVB_T_C_CI_RF

Features:

PCI-e x1
Supports two DVB-T/DVB-C transponders simultaneously Supports two analog audio/video channels simultaneously Independent descrambling of two transponders Hardware PID filtering

Components:

Conexant CX23885
STM STV0367 low-power and ultra-compact combo DVB-T/C single-chip receiver Xceive XC5000 silicon TV tuner
Altera FPGA for Common Interafce

The following changes since commit c8dd732fd119ce6d562d5fa82a10bbe75a376575:
V4L/DVB: gspca - sonixj: Have 0c45:6130 handled by sonixj instead of sn9c102 (2010-10-01

18:14:35 -0300)

are available in the git repository at:
http://udev.netup.ru/git/v4l-dvb.git netup-for-media-tree

Abylay Ospan (6):
cx23885: Altera FPGA CI interface reworked.
stv0367: change default value for AGC register.
stv0367: implement uncorrected blocks counter. cx23885, cimax2.c: Fix case of two CAM insertion irq. Fix CI code for NetUP Dual DVB-T/C CI RF card
Force xc5000 firmware loading for NetUP Dual DVB-T/C CI RF card

Igor M. Liplianin (14):
Altera FPGA firmware download module.
Altera FPGA based CI driver module.
Support for stv0367 multi-standard demodulator.
xc5000: add support for DVB-C tuning.
Initial commit to support NetUP Dual DVB-T/C CI RF card.
cx23885: implement tuner_bus parameter for cx23885_board structure. cx23885: implement num_fds_portb, num_fds_portc parameters for cx23885_board structure. stv0367: Fix potential divide error
cx23885: remove duplicate set interrupt mask
stv0367: coding style corrections
cx25840: Fix subdev registration and typo in cx25840-core.c
cx23885: 0xe becomes 0xc again for NetUP Dual DVB-S2
cx23885: disable MSI for NetUP cards, otherwise CI is not working cx23885, altera-ci: enable all PID's less than 0x20 in hardware PID filter.

 drivers/media/common/tuners/xc5000.c        |   18 +
 drivers/media/dvb/frontends/Kconfig         |    7 +
 drivers/media/dvb/frontends/Makefile        |    1 +
 drivers/media/dvb/frontends/stv0367.c       | 3419
 +++++++++++++++++++++++++ drivers/media/dvb/frontends/stv0367.h      
 |   62 +
 drivers/media/dvb/frontends/stv0367_priv.h  |  211 ++
 drivers/media/dvb/frontends/stv0367_regs.h  | 3614
 +++++++++++++++++++++++++++ drivers/media/video/cx23885/Kconfig       
  |   12 +-
 drivers/media/video/cx23885/Makefile        |    1 +
 drivers/media/video/cx23885/altera-ci.c     |  841 +++++++
 drivers/media/video/cx23885/altera-ci.h     |  102 +
 drivers/media/video/cx23885/cimax2.c        |   24 +-
 drivers/media/video/cx23885/cx23885-cards.c |  116 +-
 drivers/media/video/cx23885/cx23885-core.c  |   35 +-
 drivers/media/video/cx23885/cx23885-dvb.c   |  175 ++-
 drivers/media/video/cx23885/cx23885-reg.h   |    1 +
 drivers/media/video/cx23885/cx23885-video.c |    7 +-
 drivers/media/video/cx23885/cx23885.h       |    7 +-
 drivers/media/video/cx25840/cx25840-core.c  |    4 +-
 drivers/misc/Kconfig                        |    1 +
 drivers/misc/Makefile                       |    1 +
 drivers/misc/stapl-altera/Kconfig           |    8 +
 drivers/misc/stapl-altera/Makefile          |    3 +
 drivers/misc/stapl-altera/altera.c          | 2739 ++++++++++++++++++++
 drivers/misc/stapl-altera/jbicomp.c         |  163 ++
 drivers/misc/stapl-altera/jbiexprt.h        |   94 +
 drivers/misc/stapl-altera/jbijtag.c         | 1038 ++++++++
 drivers/misc/stapl-altera/jbijtag.h         |   83 +
 drivers/misc/stapl-altera/jbistub.c         |   70 +
 include/misc/altera.h                       |   49 +
 30 files changed, 12872 insertions(+), 34 deletions(-)
 create mode 100644 drivers/media/dvb/frontends/stv0367.c
 create mode 100644 drivers/media/dvb/frontends/stv0367.h
 create mode 100644 drivers/media/dvb/frontends/stv0367_priv.h
 create mode 100644 drivers/media/dvb/frontends/stv0367_regs.h
 create mode 100644 drivers/media/video/cx23885/altera-ci.c
 create mode 100644 drivers/media/video/cx23885/altera-ci.h
 create mode 100644 drivers/misc/stapl-altera/Kconfig
Quoted 8 lines
 create mode 100644 drivers/misc/stapl-altera/Makefile
 create mode 100644 drivers/misc/stapl-altera/altera.c
 create mode 100644 drivers/misc/stapl-altera/jbicomp.c
 create mode 100644 drivers/misc/stapl-altera/jbiexprt.h
 create mode 100644 drivers/misc/stapl-altera/jbijtag.c
 create mode 100644 drivers/misc/stapl-altera/jbijtag.h
 create mode 100644 drivers/misc/stapl-altera/jbistub.c
 create mode 100644 include/misc/altera.h

Igor,

I did a quick look at Altera FPGA driver, and at the cx23885 changes for it to work with this device, I think the FPGA driver deserves some discussion at linux-kernel.

As there's a V4L/DVB device that depends on it, it is clear to me that the better is to merge the driver via my tree.

So, I'm basically sending your first patch to the mailing lists for review.

---

From e1fd36695ae082ae89a3155cabb5a84181ae9df4 Mon Sep 17 00:00:00 2001
From: Igor M. Liplianin <[email protected]>
Date: Mon, 24 May 2010 13:09:23 +0300
Subject: Altera FPGA firmware download module.
Cc: Linux Media Mailing List <[email protected]>

It uses STAPL files and programs Altera FPGA through JTAG. Interface to JTAG must be provided from main device module, for example through cx23885 GPIO.

---

 drivers/misc/Kconfig                 |    1 +
 drivers/misc/Makefile                |    1 +
 drivers/misc/stapl-altera/Kconfig    |    8 +
 drivers/misc/stapl-altera/Makefile   |    3 +
 drivers/misc/stapl-altera/altera.c   | 2739
 ++++++++++++++++++++++++++++++++++ drivers/misc/stapl-altera/jbicomp.c 
 |  163 ++
 drivers/misc/stapl-altera/jbiexprt.h |   94 ++
 drivers/misc/stapl-altera/jbijtag.c  | 1038 +++++++++++++
 drivers/misc/stapl-altera/jbijtag.h  |   83 +
 drivers/misc/stapl-altera/jbistub.c  |   70 +
 include/misc/altera.h                |   49 +
 11 files changed, 4249 insertions(+), 0 deletions(-)
 create mode 100644 drivers/misc/stapl-altera/Kconfig
 create mode 100644 drivers/misc/stapl-altera/Makefile
 create mode 100644 drivers/misc/stapl-altera/altera.c
 create mode 100644 drivers/misc/stapl-altera/jbicomp.c
 create mode 100644 drivers/misc/stapl-altera/jbiexprt.h
 create mode 100644 drivers/misc/stapl-altera/jbijtag.c
 create mode 100644 drivers/misc/stapl-altera/jbijtag.h
 create mode 100644 drivers/misc/stapl-altera/jbistub.c
 create mode 100644 include/misc/altera.h
drivers/misc/Kconfig +1 -0
index 9b089df..3cfc47c 100644
@@ -367,5 +367,6 @@ source "drivers/misc/c2port/Kconfig"
 
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
 source "drivers/misc/iwmc3200top/Kconfig"
 
+source "drivers/misc/stapl-altera/Kconfig"

endif # MISC_DEVICES

drivers/misc/Makefile +1 -0
index 67552d6..58e794c 100644
@@ -32,3 +32,4 @@ obj-y				+= eeprom/
 
 obj-y				+= cb710/
 obj-$(CONFIG_VMWARE_BALLOON)	+= vmware_balloon.o
 obj-$(CONFIG_ARM_CHARLCD)	+= arm-charlcd.o
 
+obj-y				+= stapl-altera/
(quoted diff) +0 -0

b/drivers/misc/stapl-altera/Kconfig new file mode 100644 index 0000000..19ba4a9

drivers/misc/stapl-altera/Kconfig new file +8 -0
@@ -0,0 +1,8 @@
+comment "Altera FPGA firmware download module"
+
+config STAPL_ALTERA
+	tristate "Altera FPGA firmware download module"
+	depends on I2C
+	default m
+	help
+	  An Altera FPGA module. Say Y when you want to support this tool.
(quoted diff) +0 -0

b/drivers/misc/stapl-altera/Makefile new file mode 100644 index 0000000..db56178

drivers/misc/stapl-altera/Makefile new file +3 -0
@@ -0,0 +1,3 @@
+stapl-altera-objs = jbistub.o jbijtag.o jbicomp.o altera.o
+
+obj-$(CONFIG_STAPL_ALTERA) += stapl-altera.o
(quoted diff) +0 -0

b/drivers/misc/stapl-altera/altera.c new file mode 100644 index 0000000..9628d9c

drivers/misc/stapl-altera/altera.c new file +23 -0
@@ -0,0 +1,2739 @@
+/*
+ * altera.c
+ *
+ * altera FPGA driver
+ *
+ * Copyright (C) Altera Corporation 1998-2001
+ * Copyright (C) 2010 NetUP Inc.
+ * Copyright (C) 2010 Igor M. Liplianin <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

drivers/misc/stapl-altera/altera.c line 33

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+ */
+
+#include <linux/firmware.h>
+#include <linux/slab.h>
+#include <misc/altera.h>
+#include "jbiexprt.h"
+
+static int verbose = 1;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "enable debugging information");

Better to call it as "debug".

Quoted 6 lines
drivers/misc/stapl-altera/altera.c new file +6 -0
+
+MODULE_DESCRIPTION("altera FPGA kernel module");
+MODULE_AUTHOR("Igor M. Liplianin  <[email protected]>");
+MODULE_LICENSE("GPL");
+
+#include "jbijtag.h"

drivers/misc/stapl-altera/altera.c line 49

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+
+#define JBI_STACK_SIZE 128
+
+#define JBIC_MESSAGE_LENGTH 1024
+
+/* This macro checks if a code address is inside the code section */
+#define CHECK_PC \
+	if ((pc < code_section) || (pc >= debug_section)) { \
+		status = JBIC_BOUNDS_ERROR; \
+	}

This is ugly: a macro with 3 hidden arguments... you might define it as:

#define check_pc(pc, code_section, debug_section) \

(quoted diff) +1 -0
+	(((pc < code_section) || (pc >= debug_section)) ? JBIC_BOUNDS_ERROR : 0)

and call it as:

	status = check_pc(pc, code_section, debug_section);

But I suspect that the better would be do do, instead:

	if ((pc < code_section) || (pc >= debug_section))
		goto jbic_bounds_error;

on all places you're using it.

Quoted 23 lines
drivers/misc/stapl-altera/altera.c new file +23 -0
+
+#define dprintk(args...) \
+	if (verbose) { \
+		printk(KERN_DEBUG args); \
+	}
+
+char *error_text[] = {
+	/* JBIC_SUCCESS            0 */ "success",
+	/* JBIC_OUT_OF_MEMORY      1 */ "out of memory",
+	/* JBIC_IO_ERROR           2 */ "file access error",
+	/* JAMC_SYNTAX_ERROR       3 */ "syntax error",
+	/* JBIC_UNEXPECTED_END     4 */ "unexpected end of file",
+	/* JBIC_UNDEFINED_SYMBOL   5 */ "undefined symbol",
+	/* JAMC_REDEFINED_SYMBOL   6 */ "redefined symbol",
+	/* JBIC_INTEGER_OVERFLOW   7 */ "integer overflow",
+	/* JBIC_DIVIDE_BY_ZERO     8 */ "divide by zero",
+	/* JBIC_CRC_ERROR          9 */ "CRC mismatch",
+	/* JBIC_INTERNAL_ERROR    10 */ "internal error",
+	/* JBIC_BOUNDS_ERROR      11 */ "bounds error",
+	/* JAMC_TYPE_MISMATCH     12 */ "type mismatch",
+	/* JAMC_ASSIGN_TO_CONST   13 */ "assignment to constant",
+	/* JAMC_NEXT_UNEXPECTED   14 */ "NEXT unexpected",
+	/* JAMC_POP_UNEXPECTED    15 */ "POP unexpected",

drivers/misc/stapl-altera/altera.c line 82

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+	/* JAMC_RETURN_UNEXPECTED 16 */ "RETURN unexpected",
+	/* JAMC_ILLEGAL_SYMBOL    17 */ "illegal symbol name",
+	/* JBIC_VECTOR_MAP_FAILED 18 */ "vector signal name not found",
+	/* JBIC_USER_ABORT        19 */ "execution cancelled",
+	/* JBIC_STACK_OVERFLOW    20 */ "stack overflow",
+	/* JBIC_ILLEGAL_OPCODE    21 */ "illegal instruction code",
+	/* JAMC_PHASE_ERROR       22 */ "phase error",
+	/* JAMC_SCOPE_ERROR       23 */ "scope error",
+	/* JBIC_ACTION_NOT_FOUND  24 */ "action not found",
+};

The better would be to use standard Unix error codes here.

Quoted 12 lines
drivers/misc/stapl-altera/altera.c new file +2 -0
+
+#define MAX_ERROR_CODE

(int)((sizeof(error_text)/sizeof(error_text[0]))+1) +
+/* This function checks if enough parameters are available on the stack. */ +static int jbi_check_stack(int stack_ptr, int count, int *status) +{

drivers/misc/stapl-altera/altera.c new file +7 -0
+	if (stack_ptr < count) {
+		*status = JBIC_STACK_OVERFLOW;
+		return 0;
+	}
+
+	return 1;
+}

drivers/misc/stapl-altera/altera.c line 105

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+
+static int jbi_strlen(char *string)
+{
+	int len = 0;
+
+	while (string[len] != '\0')
+		++len;
+
+	return len;
+}

Linux has strlen. Don't re-invent the wheel.

Quoted 47 lines
drivers/misc/stapl-altera/altera.c new file +47 -0
+
+static void jbi_ltoa(char *buffer, s32 number)
+{
+	int index = 0;
+	int rev_index = 0;
+	char reverse[32];
+
+	if (number < 0L) {
+		buffer[index++] = '-';
+		number = 0 - number;
+	} else if (number == 0)
+		buffer[index++] = '0';
+
+	while (number != 0) {
+		reverse[rev_index++] = (char)((number % 10) + '0');
+		number /= 10;
+	}
+
+	while (rev_index > 0)
+		buffer[index++] = reverse[--rev_index];
+
+	buffer[index] = '\0';
+}
+
+static char jbi_toupper(char ch)
+{
+	return (char)(((ch >= 'a') && (ch <= 'z')) ? (ch + 'A' - 'a') : ch);
+}
+
+static int jbi_stricmp(char *left, char *right)
+{
+	int result = 0;
+	char l, r;
+
+	do {
+		l = jbi_toupper(*left);
+		r = jbi_toupper(*right);
+		result = l - r;
+		++left;
+		++right;
+	} while ((result == 0) && (l != '\0') && (r != '\0'));
+
+	return result;
+}
+
+static void jbi_strncpy(char *left, char *right, int count)
+{

drivers/misc/stapl-altera/altera.c line 162

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+	char ch;
+
+	do {
+		*left = *right;
+		ch = *right;
+		++left;
+		++right;
+		--count;
+	} while ((ch != '\0') && (count != 0));
+}

Linux has functions for the above. Don't re-invent the wheel.

Quoted 7 lines
drivers/misc/stapl-altera/altera.c new file +7 -0
+
+static void jbi_make_dword(u8 *buf, u32 num)
+{
+	buf[0] = (u8) num;
+	buf[1] = (u8)(num >> 8L);
+	buf[2] = (u8)(num >> 16L);
+	buf[3] = (u8)(num >> 24L);

drivers/misc/stapl-altera/altera.c line 179

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+}
+
+static u32 jbi_get_dword(u8 *buf)
+{
+	return
+	    (((u32)buf[0]) |
+	     (((u32)buf[1]) << 8L) |
+	     (((u32)buf[2]) << 16L) |
+	     (((u32)buf[3]) << 24L));
+}

Use the proper Linux functions to handle big/little endian.

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+
+static void jbi_export_integer(char *key, s32 value)
+{
+	dprintk("Export: key = \"%s\", value = %d\n", key, value);
+}
+
+#define HEX_LINE_CHARS 72
+#define HEX_LINE_BITS (HEX_LINE_CHARS * 4)
+
+static char conv_to_hex(u32 value)

drivers/misc/stapl-altera/altera.c line 199

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+{
+	char c;
+
+	if (value > 9)
+		c = (char)(value + ('A' - 10));
+	else
+		c = (char)(value + '0');
+
+	return c;
+}

There are some Linux functions for this also.

Quoted 120 lines
drivers/misc/stapl-altera/altera.c new file +120 -0
+
+static void jbi_export_boolean_array(char *key, u8 *data, s32 count)
+{
+	char string[HEX_LINE_CHARS + 1];
+	s32 i, offset;
+	u32 size, line, lines, linebits, value, j, k;
+
+	if (count > HEX_LINE_BITS) {
+		dprintk("Export: key = \"%s\", %d bits, value = HEX\n",
+							key, count);
+		lines = (count + (HEX_LINE_BITS - 1)) / HEX_LINE_BITS;
+
+		for (line = 0; line < lines; ++line) {
+			if (line < (lines - 1)) {
+				linebits = HEX_LINE_BITS;
+				size = HEX_LINE_CHARS;
+				offset = count - ((line + 1) * HEX_LINE_BITS);
+			} else {
+				linebits =
+					count - ((lines - 1) * HEX_LINE_BITS);
+				size = (linebits + 3) / 4;
+				offset = 0L;
+			}
+
+			string[size] = '\0';
+			j = size - 1;
+			value = 0;
+
+			for (k = 0; k < linebits; ++k) {
+				i = k + offset;
+				if (data[i >> 3] & (1 << (i & 7)))
+					value |= (1 << (i & 3));
+				if ((i & 3) == 3) {
+					string[j] = conv_to_hex(value);
+					value = 0;
+					--j;
+				}
+			}
+			if ((k & 3) > 0)
+				string[j] = conv_to_hex(value);
+
+			dprintk("%s\n", string);
+		}
+
+	} else {
+		size = (count + 3) / 4;
+		string[size] = '\0';
+		j = size - 1;
+		value = 0;
+
+		for (i = 0; i < count; ++i) {
+			if (data[i >> 3] & (1 << (i & 7)))
+				value |= (1 << (i & 3));
+			if ((i & 3) == 3) {
+				string[j] = conv_to_hex(value);
+				value = 0;
+				--j;
+			}
+		}
+		if ((i & 3) > 0)
+			string[j] = conv_to_hex(value);
+
+		dprintk("Export: key = \"%s\", %d bits, value = HEX %s\n",
+			key, count, string);
+	}
+}
+
+static JBI_RETURN_TYPE jbi_execute(struct altera_config *astate,
+				u8 *program,
+				s32 program_size,
+				s32 *error_address,
+				int *exit_code,
+				int *format_version)
+{
+	static char message_buffer[JBIC_MESSAGE_LENGTH + 1];
+	static long stack[JBI_STACK_SIZE] = {0L};/*64 bits*/
+	JBI_RETURN_TYPE status = JBIC_SUCCESS;
+	u32 first_word = 0L;
+	u32 action_table = 0L;
+	u32 proc_table = 0L;
+	u32 string_table = 0L;
+	u32 symbol_table = 0L;
+	u32 data_section = 0L;
+	u32 code_section = 0L;
+	u32 debug_section = 0L;
+	u32 action_count = 0L;
+	u32 proc_count = 0L;
+	u32 symbol_count = 0L;
+	long *variables = NULL;/*64bits*/
+	s32 *variable_size = NULL;
+	char *attributes = NULL;
+	u8 *proc_attributes = NULL;
+	u32 pc;
+	u32 opcode_address;
+	u32 args[3];
+	u32 opcode;
+	u32 name_id;
+	u8 charbuf[4];
+	long long_temp;/*64bits*/
+	u32 variable_id;
+	u8 *charptr_temp;
+	u8 *charptr_temp2;
+	long *longptr_temp;
+	int version = 0;
+	int delta = 0;
+	int stack_ptr = 0;
+	u32 arg_count;
+	int done = 0;
+	int bad_opcode = 0;
+	u32 count;
+	u32 index;
+	u32 index2;
+	s32 long_count;
+	s32 long_index;
+	s32 long_index2;
+	u32 i;
+	u32 j;
+	u32 uncompressed_size;
+	u32 offset;
+	u32 value;

drivers/misc/stapl-altera/altera.c line 329

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+	int current_proc = 0;
+	int reverse;
+
+	char *name;
+
+	dprintk("%s\n", __func__);
+
+	/* Read header information */
+	if (program_size > 52L) {
+		first_word    = GET_DWORD(0);

GET_DWORD here masks the fact that it is reading a dword data, from a variable called "program". Please, don't do that. Also, again, what this function actually does is to convert a data using a given endiannes. As it is defined as:

	#define GET_BYTE(x) (program[x])
	#define GET_DWORD(x) \
		(((((u32) GET_BYTE(x)) << 24L) & 0xFF000000L) | \
		((((u32) GET_BYTE((x)+1)) << 16L) & 0x00FF0000L) | \
		((((u32) GET_BYTE((x)+2)) << 8L) & 0x0000FF00L) | \
		(((u32) GET_BYTE((x)+3)) & 0x000000FFL))

you're getting a 32 bits encoded as little endian. So, the Linux way for it would be to use, instead:

	get_unaligned_le32(&program[0]);

(the same applies to all cases of GET_BYTE/GET_WORD/GET_DWORD)

Quoted 19 lines
drivers/misc/stapl-altera/altera.c new file +19 -0
+		version = (int)(first_word & 1L);
+		*format_version = version + 1;
+		delta = version * 8;
+
+		action_table  = GET_DWORD(4);
+		proc_table    = GET_DWORD(8);
+		string_table  = GET_DWORD(4 + delta);
+		symbol_table  = GET_DWORD(16 + delta);
+		data_section  = GET_DWORD(20 + delta);
+		code_section  = GET_DWORD(24 + delta);
+		debug_section = GET_DWORD(28 + delta);
+		action_count  = GET_DWORD(40 + delta);
+		proc_count    = GET_DWORD(44 + delta);
+		symbol_count  = GET_DWORD(48 + (2 * delta));
+	}
+
+	if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) {
+		done = 1;
+		status = JBIC_IO_ERROR;

drivers/misc/stapl-altera/altera.c line 358

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+		goto exit_done;
+	}
+
+	if (symbol_count <= 0)
+		goto exit_done;
+	/* 64 bits */
+	variables = kmalloc((u32)symbol_count * sizeof(long), GFP_KERNEL);
+
+	if (variables == NULL)
+		status = JBIC_OUT_OF_MEMORY;

status = -ENOMEM;

Quoted 14 lines
drivers/misc/stapl-altera/altera.c new file +14 -0
+
+	if (status == JBIC_SUCCESS) {
+		variable_size = kmalloc(
+			(u32)symbol_count * sizeof(s32), GFP_KERNEL);
+
+		if (variable_size == NULL)
+			status = JBIC_OUT_OF_MEMORY;
+	}
+
+	if (status == JBIC_SUCCESS) {
+		attributes = (char *)
+				kmalloc((u32)symbol_count, GFP_KERNEL);
+
+		if (attributes == NULL)

drivers/misc/stapl-altera/altera.c line 382

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+			status = JBIC_OUT_OF_MEMORY;
+	}
+
+	if ((status == JBIC_SUCCESS) && (version > 0)) {
+		proc_attributes = (u8 *)
+				kmalloc((u32)proc_count, GFP_KERNEL);
+
+		if (proc_attributes == NULL)
+			status = JBIC_OUT_OF_MEMORY;
+	}

Same for all above: -ENOMEM.

Quoted 178 lines
drivers/misc/stapl-altera/altera.c new file +178 -0
+
+	if (status != JBIC_SUCCESS)
+		goto exit_done;
+
+	delta = version * 2;
+
+	for (i = 0; i < (u32)symbol_count; ++i) {
+		offset = (u32)
+			(symbol_table + ((11 + delta) * i));
+
+		value = GET_DWORD(offset + 3 + delta);
+
+		attributes[i] = GET_BYTE(offset);
+
+		/* use bit 7 of attribute byte to indicate that
+		this buffer was dynamically allocated
+		and should be freed later */
+		attributes[i] &= 0x7f;
+
+		variable_size[i] = GET_DWORD(offset + 7 + delta);
+
+		/*
+		Attribute bits:
+		bit 0: 0 = read-only, 1 = read-write
+		bit 1: 0 = not compressed, 1 = compressed
+		bit 2: 0 = not initialized, 1 = initialized
+		bit 3: 0 = scalar, 1 = array
+		bit 4: 0 = Boolean, 1 = integer
+		bit 5: 0 = declared variable,
+			1 = compiler created temporary variable
+		*/
+
+		if ((attributes[i] & 0x0c) == 0x04)
+			/* initialized scalar variable */
+			variables[i] = value;
+		else if ((attributes[i] & 0x1e) == 0x0e) {
+			/* initialized compressed
+			Boolean array */
+			uncompressed_size = jbi_get_dword(
+				&program[data_section + value]);
+
+			/* allocate a buffer for the
+			uncompressed data */
+			variables[i] = (long)kmalloc(uncompressed_size,
+								GFP_KERNEL);
+			dprintk("%s: var=%lx, (s32)var=%x\n", __func__,
+					variables[i], (s32)variables[i]);
+			if (variables[i] == 0L)
+				status = JBIC_OUT_OF_MEMORY;
+			else {
+				/* set flag so buffer
+				will be freed later */
+				attributes[i] |= 0x80;
+
+				/* uncompress the data */
+				if (jbi_uncompress(&program[data_section +
+									value],
+						variable_size[i],
+						(u8 *)variables[i],/*64 bits*/
+						uncompressed_size,
+						version) != uncompressed_size)
+					/* decompression failed */
+					status = JBIC_IO_ERROR;
+				else /*64 bits?*/
+					variable_size[i] =
+							uncompressed_size * 8L;
+
+			}
+		} else if ((attributes[i] & 0x1e) == 0x0c) {
+			/* initialized Boolean array */
+			/*64 bits*/
+			variables[i] = value + data_section + (long)program;
+		} else if ((attributes[i] & 0x1c) == 0x1c) {
+			/* initialized integer array */
+			variables[i] = value + data_section;
+		} else if ((attributes[i] & 0x0c) == 0x08) {
+			/* uninitialized array */
+
+			/* flag attributes so
+			that memory is freed */
+			attributes[i] |= 0x80;
+
+			if (variable_size[i] > 0) {
+				u32 size;
+
+				if (attributes[i] & 0x10)
+					/* integer array */
+					size = (u32)(variable_size[i] *
+								sizeof(s32));
+				else
+					/* Boolean array */
+					size = (u32)
+						((variable_size[i] + 7L) / 8L);
+				/*64 bits*/
+				variables[i] = (long)kmalloc(size, GFP_KERNEL);
+
+				if (variables[i] == 0) {
+					status = JBIC_OUT_OF_MEMORY;
+				} else {
+					/* zero out memory */
+					for (j = 0; j < size; ++j)
+						/*64 bits*/
+						((u8 *)(variables[i]))[j] = 0;
+
+				}
+			} else
+				variables[i] = 0;
+
+		} else
+			variables[i] = 0;
+
+	}
+
+exit_done:
+	if (status != JBIC_SUCCESS)
+		done = 1;
+
+	jbi_init_jtag();
+
+	pc = code_section;
+	message_buffer[0] = '\0';
+
+	/*
+	For JBC version 2, we will execute the procedures corresponding to
+	the selected ACTION */
+	if (version > 0) {
+		if (astate->action == NULL) {
+			status = JBIC_ACTION_NOT_FOUND;
+			done = 1;
+		} else {
+			int action_found = 0;
+			for (i = 0; (i < action_count) && !action_found; ++i) {
+				name_id = GET_DWORD(action_table + (12 * i));
+
+				name = (char *)&program[string_table + name_id];
+
+				if (jbi_stricmp(astate->action, name) == 0) {
+					action_found = 1;
+					current_proc = (int)
+							GET_DWORD(action_table +
+								(12 * i) + 8);
+				}
+			}
+
+			if (!action_found) {
+				status = JBIC_ACTION_NOT_FOUND;
+				done = 1;
+			}
+		}
+
+		if (status == JBIC_SUCCESS) {
+			int first_time = 1;
+			i = current_proc;
+			while ((i != 0) || first_time) {
+				first_time = 0;
+				/* check procedure attribute byte */
+				proc_attributes[i] = (u8)
+						(GET_BYTE(proc_table +
+								(13 * i) + 8) &
+									0x03);
+
+				/*
+				BIT0 - OPTIONAL
+				BIT1 - RECOMMENDED
+				BIT6 - FORCED OFF
+				BIT7 - FORCED ON
+				*/
+
+				i = (u32)GET_DWORD(proc_table + (13 * i) + 4);
+			}
+
+			/*
+			Set current_proc to the first procedure to be executed
+			*/
+			i = current_proc;
+			while ((i != 0) &&
+				((proc_attributes[i] == 1) ||
+				((proc_attributes[i] & 0xc0) == 0x40))) {

drivers/misc/stapl-altera/altera.c line 570

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+				i = (u32)GET_DWORD(proc_table + (13 * i) + 4);
+			}
+
+			if ((i != 0) || ((i == 0) && (current_proc == 0) &&
+				((proc_attributes[0] != 1) &&
+				((proc_attributes[0] & 0xc0) != 0x40)))) {
+				current_proc = i;
+				pc = code_section +
+					GET_DWORD(proc_table + (13 * i) + 9);
+				CHECK_PC;

See my comments above. The code will look cleaner if you use, instead of the macro, something like:

	if ((pc < code_section) || (pc >= debug_section))
		goto jbic_bounds_error;

(if you can simply abort the programming due to the error)

or

	if ((pc < code_section) || (pc >= debug_section))
		status = <error code>;

if you really need to program everything even knowing in advance that an error happened.

Quoted 30 lines
drivers/misc/stapl-altera/altera.c new file +30 -0
+			} else
+				/* there are no procedures to execute! */
+				done = 1;
+
+		}
+	}
+
+	message_buffer[0] = '\0';
+
+	while (!done) {
+		opcode = (u32)(GET_BYTE(pc) & 0xff);
+		opcode_address = pc;
+		++pc;
+
+		if (verbose > 1)
+			printk("opcode: %02x\n", opcode);
+
+		arg_count = (opcode >> 6) & 3;
+		for (i = 0; i < arg_count; ++i) {
+			args[i] = GET_DWORD(pc);
+			pc += 4;
+		}
+
+		switch (opcode) {
+		case 0x00: /* NOP  */
+			break;
+		case 0x01: /* DUP  */
+			if (jbi_check_stack(stack_ptr, 1, &status)) {
+				stack[stack_ptr] = stack[stack_ptr - 1];
+				++stack_ptr;

drivers/misc/stapl-altera/altera.c line 610

Quoted 10 lines
drivers/misc/stapl-altera/altera.c new file +10 -0
+			}
+			break;
+		case 0x02: /* SWP  */
+			if (jbi_check_stack(stack_ptr, 2, &status)) {
+				long_temp = stack[stack_ptr - 2];
+				stack[stack_ptr - 2] = stack[stack_ptr - 1];
+				stack[stack_ptr - 1] = long_temp;
+			}
+			break;
+		case 0x03: /* ADD  */

hmm... the better would be to do:

enum altera_fpga_opcode {
	OP_NOP = 0,
	OP_DUP = 1,
	OP_SWP = 2,
	OP_ADD = 3,
	...
};

switch (obcode) {
case OP_NOP:

Quoted 7 lines
	/* do something */

...
}

The rest of the driver have the same problems as pointed above.

Please fix, and submit a version 2.

Thank you Mauro.

I'm working on it.

Igor