diff --git a/src/arduino.c b/src/arduino.c
index f7b60246..c7aa2deb 100644
--- a/src/arduino.c
+++ b/src/arduino.c
@@ -38,8 +38,7 @@
 #include "arduino.h"
 
 /* read signature bytes - arduino version */
-static int arduino_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
-{
+static int arduino_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m) {
   unsigned char buf[32];
 
   /* Signature byte reads are always 3 bytes. */
@@ -80,8 +79,7 @@ static int arduino_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
   return 3;
 }
 
-static int arduino_open(PROGRAMMER * pgm, char * port)
-{
+static int arduino_open(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo;
   strcpy(pgm->port, port);
   pinfo.serialinfo.baud = pgm->baudrate? pgm->baudrate: 115200;
@@ -118,8 +116,7 @@ static void arduino_close(PROGRAMMER * pgm)
 
 const char arduino_desc[] = "Arduino programmer";
 
-void arduino_initpgm(PROGRAMMER * pgm)
-{
+void arduino_initpgm(PROGRAMMER *pgm) {
   /* This is mostly a STK500; just the signature is read
      differently than on real STK500v1 
      and the DTR signal is set when opening the serial port
diff --git a/src/arduino.h b/src/arduino.h
index 024d711b..ce1ff9b8 100644
--- a/src/arduino.h
+++ b/src/arduino.h
@@ -22,7 +22,7 @@
 #define arduino_h__
 
 extern const char arduino_desc[];
-void arduino_initpgm (PROGRAMMER * pgm);
+void arduino_initpgm(PROGRAMMER *pgm);
 
 #endif
 
diff --git a/src/avr.c b/src/avr.c
index 49994c47..7a1f34a6 100644
--- a/src/avr.c
+++ b/src/avr.c
@@ -38,8 +38,7 @@ FP_UpdateProgress update_progress;
 #define DEBUG 0
 
 /* TPI: returns 1 if NVM controller busy, 0 if free */
-int avr_tpi_poll_nvmbsy(PROGRAMMER *pgm)
-{
+int avr_tpi_poll_nvmbsy(const PROGRAMMER *pgm) {
   unsigned char cmd;
   unsigned char res;
 
@@ -49,8 +48,7 @@ int avr_tpi_poll_nvmbsy(PROGRAMMER *pgm)
 }
 
 /* TPI chip erase sequence */
-int avr_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+int avr_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
 	int err;
   AVRMEM *mem;
 
@@ -99,8 +97,7 @@ int avr_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
 }
 
 /* TPI program enable sequence */
-int avr_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p, unsigned char guard_time)
-{
+int avr_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p, unsigned char guard_time) {
 	int err, retry;
 	unsigned char cmd[2];
 	unsigned char response;
@@ -149,7 +146,7 @@ int avr_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p, unsigned char guard_ti
 }
 
 /* TPI: setup NVMCMD register and pointer register (PR) for read/write/erase */
-static int avr_tpi_setup_rw(PROGRAMMER * pgm, AVRMEM * mem,
+static int avr_tpi_setup_rw(const PROGRAMMER *pgm, const AVRMEM *mem,
 			    unsigned long addr, unsigned char nvmcmd)
 {
   unsigned char cmd[4];
@@ -178,7 +175,7 @@ static int avr_tpi_setup_rw(PROGRAMMER * pgm, AVRMEM * mem,
   return 0;
 }
 
-int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, 
+int avr_read_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                           unsigned long addr, unsigned char * value)
 {
   unsigned char cmd[4];
@@ -280,7 +277,7 @@ int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
  * no-op. Always return an even number since flash is word addressed.
  * Only apply this optimisation on flash-type memory.
  */
-int avr_mem_hiaddr(AVRMEM * mem)
+int avr_mem_hiaddr(const AVRMEM * mem)
 {
   int i, n;
   static int disableffopt;
@@ -322,7 +319,7 @@ int avr_mem_hiaddr(AVRMEM * mem)
  *
  * Return the number of bytes read, or < 0 if an error occurs.  
  */
-int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
+int avr_read(const PROGRAMMER *pgm, const AVRPART *p, const char *memtype,
              AVRPART * v)
 {
   unsigned long    i, lastaddr;
@@ -469,7 +466,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
 /*
  * write a page data at the specified address
  */
-int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, 
+int avr_write_page(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                    unsigned long addr)
 {
   unsigned char cmd[4];
@@ -529,7 +526,7 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 }
 
 
-int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                    unsigned long addr, unsigned char data)
 {
   unsigned char cmd[4];
@@ -790,7 +787,7 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 /*
  * write a byte of data at the specified address
  */
-int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+int avr_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                    unsigned long addr, unsigned char data)
 {
   return pgm->write_byte(pgm, p, mem, addr, data);
@@ -806,8 +803,8 @@ int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
  *
  * Return the number of bytes written, or -1 if an error occurs.
  */
-int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, 
-              int auto_erase)
+int avr_write(const PROGRAMMER *pgm, const AVRPART *p, const char *memtype,
+              int size, int auto_erase)
 {
   int              rc;
   int              newpage, page_tainted, flush_page, do_write;
@@ -1031,8 +1028,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
 /*
  * read the AVR device's signature bytes
  */
-int avr_signature(PROGRAMMER * pgm, AVRPART * p)
-{
+int avr_signature(const PROGRAMMER *pgm, const AVRPART *p) {
   int rc;
 
   report_progress (0,1,"Reading");
@@ -1084,7 +1080,7 @@ int compare_memory_masked(AVRMEM * m, uint8_t b1, uint8_t b2) {
  *
  * Return the number of bytes verified, or -1 if they don't match.
  */
-int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
+int avr_verify(const AVRPART * p, const AVRPART * v, const char * memtype, int size)
 {
   int i;
   unsigned char * buf1, * buf2;
@@ -1153,8 +1149,7 @@ int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
 }
 
 
-int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles)
-{
+int avr_get_cycle_count(const PROGRAMMER *pgm, const AVRPART *p, int *cycles) {
   AVRMEM * a;
   unsigned int cycle_count = 0;
   unsigned char v1;
@@ -1192,8 +1187,7 @@ int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles)
 }
 
 
-int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles)
-{
+int avr_put_cycle_count(const PROGRAMMER *pgm, const AVRPART *p, int cycles) {
   AVRMEM * a;
   unsigned char v1;
   int rc;
@@ -1250,7 +1244,7 @@ void avr_add_mem_order(const char *str) {
   exit(1);
 }
 
-int avr_mem_is_flash_type(AVRMEM *mem) {
+int avr_mem_is_flash_type(const AVRMEM *mem) {
   return
      strcmp(mem->desc, "flash") == 0 ||
      strcmp(mem->desc, "application") == 0 ||
@@ -1258,7 +1252,7 @@ int avr_mem_is_flash_type(AVRMEM *mem) {
      strcmp(mem->desc, "boot") == 0;
 }
 
-int avr_mem_is_eeprom_type(AVRMEM *mem) {
+int avr_mem_is_eeprom_type(const AVRMEM *mem) {
   return strcmp(mem->desc, "eeprom") == 0;
 }
 
@@ -1279,8 +1273,7 @@ int avr_mem_might_be_known(const char *str) {
 }
 
 
-int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+int avr_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
   int rc;
 
   rc = pgm->chip_erase(pgm, p);
@@ -1288,8 +1281,7 @@ int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p)
   return rc;
 }
 
-int avr_unlock(PROGRAMMER * pgm, AVRPART * p)
-{
+int avr_unlock(const PROGRAMMER *pgm, const AVRPART *p) {
   int rc = -1;
 
   if (pgm->unlock)
diff --git a/src/avr910.c b/src/avr910.c
index 3e14fdc1..6e2f1f07 100644
--- a/src/avr910.c
+++ b/src/avr910.c
@@ -71,14 +71,12 @@ static void avr910_teardown(PROGRAMMER * pgm)
 }
 
 
-static int avr910_send(PROGRAMMER * pgm, char * buf, size_t len)
-{
+static int avr910_send(const PROGRAMMER *pgm, char *buf, size_t len) {
   return serial_send(&pgm->fd, (unsigned char *)buf, len);
 }
 
 
-static int avr910_recv(PROGRAMMER * pgm, char * buf, size_t len)
-{
+static int avr910_recv(const PROGRAMMER *pgm, char *buf, size_t len) {
   int rv;
 
   rv = serial_recv(&pgm->fd, (unsigned char *)buf, len);
@@ -91,14 +89,12 @@ static int avr910_recv(PROGRAMMER * pgm, char * buf, size_t len)
 }
 
 
-static int avr910_drain(PROGRAMMER * pgm, int display)
-{
+static int avr910_drain(const PROGRAMMER *pgm, int display) {
   return serial_drain(&pgm->fd, display);
 }
 
 
-static int avr910_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
-{
+static int avr910_vfy_cmd_sent(const PROGRAMMER *pgm, char *errmsg) {
   char c;
 
   avr910_recv(pgm, &c, 1);
@@ -114,8 +110,7 @@ static int avr910_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
 /*
  * issue the 'chip erase' command to the AVR device
  */
-static int avr910_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+static int avr910_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
   avr910_send(pgm, "e", 1);
   if (avr910_vfy_cmd_sent(pgm, "chip erase") < 0)
     return -1;
@@ -129,15 +124,13 @@ static int avr910_chip_erase(PROGRAMMER * pgm, AVRPART * p)
 }
 
 
-static int avr910_enter_prog_mode(PROGRAMMER * pgm)
-{
+static int avr910_enter_prog_mode(const PROGRAMMER *pgm) {
   avr910_send(pgm, "P", 1);
   return avr910_vfy_cmd_sent(pgm, "enter prog mode");
 }
 
 
-static int avr910_leave_prog_mode(PROGRAMMER * pgm)
-{
+static int avr910_leave_prog_mode(const PROGRAMMER *pgm) {
   avr910_send(pgm, "L", 1);
   return avr910_vfy_cmd_sent(pgm, "leave prog mode");
 }
@@ -146,8 +139,7 @@ static int avr910_leave_prog_mode(PROGRAMMER * pgm)
 /*
  * issue the 'program enable' command to the AVR device
  */
-static int avr910_program_enable(PROGRAMMER * pgm, AVRPART * p)
-{
+static int avr910_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
   return -1;
 }
 
@@ -155,8 +147,7 @@ static int avr910_program_enable(PROGRAMMER * pgm, AVRPART * p)
 /*
  * initialize the AVR device and prepare it to accept commands
  */
-static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
-{
+static int avr910_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
   char id[8];
   char sw[2];
   char hw[2];
@@ -273,16 +264,14 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
 }
 
 
-static void avr910_disable(PROGRAMMER * pgm)
-{
+static void avr910_disable(const PROGRAMMER *pgm) {
   /* Do nothing. */
 
   return;
 }
 
 
-static void avr910_enable(PROGRAMMER * pgm)
-{
+static void avr910_enable(PROGRAMMER *pgm, const AVRPART *p) {
   /* Do nothing. */
 
   return;
@@ -293,7 +282,7 @@ static void avr910_enable(PROGRAMMER * pgm)
  * transmit an AVR device command and return the results; 'cmd' and
  * 'res' must point to at least a 4 byte data buffer
  */
-static int avr910_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
+static int avr910_cmd(const PROGRAMMER *pgm, const unsigned char *cmd,
                       unsigned char *res)
 {
   char buf[5];
@@ -318,8 +307,7 @@ static int avr910_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
 }
 
 
-static int avr910_parseextparms(PROGRAMMER * pgm, LISTID extparms)
-{
+static int avr910_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
   LNODEID ln;
   const char *extended_param;
   int rv = 0;
@@ -359,8 +347,7 @@ static int avr910_parseextparms(PROGRAMMER * pgm, LISTID extparms)
 }
 
 
-static int avr910_open(PROGRAMMER * pgm, char * port)
-{
+static int avr910_open(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo;
   /*
    *  If baudrate was not specified use 19.200 Baud
@@ -393,14 +380,12 @@ static void avr910_close(PROGRAMMER * pgm)
 }
 
 
-static void avr910_display(PROGRAMMER * pgm, const char * p)
-{
+static void avr910_display(const PROGRAMMER *pgm, const char *p) {
   return;
 }
 
 
-static void avr910_set_addr(PROGRAMMER * pgm, unsigned long addr)
-{
+static void avr910_set_addr(const PROGRAMMER *pgm, unsigned long addr) {
   char cmd[3];
 
   cmd[0] = 'A';
@@ -412,7 +397,7 @@ static void avr910_set_addr(PROGRAMMER * pgm, unsigned long addr)
 }
 
 
-static int avr910_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int avr910_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                              unsigned long addr, unsigned char value)
 {
   char cmd[2];
@@ -445,7 +430,7 @@ static int avr910_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 }
 
 
-static int avr910_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int avr910_read_byte_flash(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                   unsigned long addr, unsigned char * value)
 {
   char buf[2];
@@ -468,7 +453,7 @@ static int avr910_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 }
 
 
-static int avr910_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int avr910_read_byte_eeprom(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                    unsigned long addr, unsigned char * value)
 {
   avr910_set_addr(pgm, addr);
@@ -479,7 +464,7 @@ static int avr910_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 }
 
 
-static int avr910_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int avr910_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                             unsigned long addr, unsigned char * value)
 {
   if (strcmp(m->desc, "flash") == 0) {
@@ -494,7 +479,7 @@ static int avr910_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 }
 
 
-static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
+static int avr910_paged_write_flash(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                     unsigned int page_size,
                                     unsigned int addr, unsigned int n_bytes)
 {
@@ -553,8 +538,8 @@ static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 }
 
 
-static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
-                                     AVRMEM * m,
+static int avr910_paged_write_eeprom(const PROGRAMMER *pgm, const AVRPART *p,
+                                     const AVRMEM * m,
                                      unsigned int page_size,
                                      unsigned int addr, unsigned int n_bytes)
 {
@@ -582,7 +567,7 @@ static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
 }
 
 
-static int avr910_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int avr910_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                               unsigned int page_size,
                               unsigned int addr, unsigned int n_bytes)
 {
@@ -642,7 +627,7 @@ static int avr910_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 }
 
 
-static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int avr910_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                              unsigned int page_size,
                              unsigned int addr, unsigned int n_bytes)
 {
@@ -719,8 +704,7 @@ static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
 /* Signature byte reads are always 3 bytes. */
 
-static int avr910_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
-{
+static int avr910_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m) {
   unsigned char tmp;
 
   if (m->size < 3) {
@@ -740,8 +724,7 @@ static int avr910_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
 
 const char avr910_desc[] = "Serial programmers using protocol described in application note AVR910";
 
-void avr910_initpgm(PROGRAMMER * pgm)
-{
+void avr910_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "avr910");
 
   /*
diff --git a/src/avr910.h b/src/avr910.h
index 808f7e68..c18e7779 100644
--- a/src/avr910.h
+++ b/src/avr910.h
@@ -26,7 +26,7 @@ extern "C" {
 #endif
 
 extern const char avr910_desc[];
-void avr910_initpgm (PROGRAMMER * pgm);
+void avr910_initpgm(PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/avrdude.conf.in b/src/avrdude.conf.in
index c0c3e168..b4c28a12 100644
--- a/src/avrdude.conf.in
+++ b/src/avrdude.conf.in
@@ -116,7 +116,7 @@
 #       idr              = <num> ;               # IO addr of IDR (OCD) reg
 #       rampz            = <num> ;               # IO addr of RAMPZ reg
 #       spmcr            = <num> ;               # mem addr of SPMC[S]R reg
-#       eecr             = <num> ;               # mem addr of EECR reg only when != 0x3c
+#       eecr             = <num> ;               # mem addr of EECR reg only when != 0x3f
 #       mcu_base         = <num> ;
 #       nvm_base         = <num> ;
 #       ocd_base         = <num> ;
diff --git a/src/avrftdi.c b/src/avrftdi.c
index 315f23e8..fdb8e557 100644
--- a/src/avrftdi.c
+++ b/src/avrftdi.c
@@ -50,16 +50,14 @@
 
 #ifdef DO_NOT_BUILD_AVRFTDI
 
-static int avrftdi_noftdi_open (struct programmer_t *pgm, char * name)
-{
+static int avrftdi_noftdi_open(PROGRAMMER *pgm, const char *name) {
 	avrdude_message(MSG_INFO, "%s: Error: no libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.\n",
                         progname);
 
 	return -1;
 }
 
-void avrftdi_initpgm(PROGRAMMER * pgm)
-{
+void avrftdi_initpgm(PROGRAMMER *pgm) {
 	strcpy(pgm->type, "avrftdi");
 	pgm->open = avrftdi_noftdi_open;
 }
@@ -227,8 +225,7 @@ static int set_frequency(avrftdi_t* ftdi, uint32_t freq)
  * Because we configured the pin direction mask earlier, nothing bad can happen
  * here.
  */
-static int set_pin(PROGRAMMER * pgm, int pinfunc, int value)
-{
+static int set_pin(const PROGRAMMER *pgm, int pinfunc, int value) {
 	avrftdi_t* pdata = to_pdata(pgm);
 	struct pindef_t pin = pgm->pin[pinfunc];
 	
@@ -250,47 +247,43 @@ static int set_pin(PROGRAMMER * pgm, int pinfunc, int value)
 /*
  * Mandatory callbacks which boil down to GPIO.
  */
-static int set_led_pgm(struct programmer_t * pgm, int value)
-{
+static int set_led_pgm(const PROGRAMMER *pgm, int value) {
 	return set_pin(pgm, PIN_LED_PGM, value);
 }
 
-static int set_led_rdy(struct programmer_t * pgm, int value)
-{
+static int set_led_rdy(const PROGRAMMER *pgm, int value) {
 	return set_pin(pgm, PIN_LED_RDY, value);
 }
 
-static int set_led_err(struct programmer_t * pgm, int value)
-{
+static int set_led_err(const PROGRAMMER *pgm, int value) {
 	return set_pin(pgm, PIN_LED_ERR, value);
 }
 
-static int set_led_vfy(struct programmer_t * pgm, int value)
-{
+static int set_led_vfy(const PROGRAMMER *pgm, int value) {
 	return set_pin(pgm, PIN_LED_VFY, value);
 }
 
-static void avrftdi_enable(PROGRAMMER * pgm)
-{
+static void avrftdi_enable(PROGRAMMER *pgm, const AVRPART *p) {
 	set_pin(pgm, PPI_AVR_BUFF, ON);
+
+	// Switch to TPI initialisation in avrftdi_tpi.c
+	if(p->flags & AVRPART_HAS_TPI)
+          avrftdi_tpi_initpgm(pgm);
 }
 
-static void avrftdi_disable(PROGRAMMER * pgm)
-{
+static void avrftdi_disable(const PROGRAMMER *pgm) {
 	set_pin(pgm, PPI_AVR_BUFF, OFF);
 }
 
-static void avrftdi_powerup(PROGRAMMER * pgm)
-{
+static void avrftdi_powerup(const PROGRAMMER *pgm) {
 	set_pin(pgm, PPI_AVR_VCC, ON);
 }
 
-static void avrftdi_powerdown(PROGRAMMER * pgm)
-{
+static void avrftdi_powerdown(const PROGRAMMER *pgm) {
 	set_pin(pgm, PPI_AVR_VCC, OFF);
 }
 
-static inline int set_data(PROGRAMMER * pgm, unsigned char *buf, unsigned char data, bool read_data) {
+static inline int set_data(const PROGRAMMER *pgm, unsigned char *buf, unsigned char data, bool read_data) {
 	int j;
 	int buf_pos = 0;
 	unsigned char bit = 0x80;
@@ -324,7 +317,7 @@ static inline int set_data(PROGRAMMER * pgm, unsigned char *buf, unsigned char d
 	return buf_pos;
 }
 
-static inline unsigned char extract_data(PROGRAMMER * pgm, unsigned char *buf, int offset) {
+static inline unsigned char extract_data(const PROGRAMMER *pgm, unsigned char *buf, int offset) {
 	int j;
 	unsigned char bit = 0x80;
 	unsigned char r = 0;
@@ -342,7 +335,7 @@ static inline unsigned char extract_data(PROGRAMMER * pgm, unsigned char *buf, i
 }
 
 
-static int avrftdi_transmit_bb(PROGRAMMER * pgm, unsigned char mode, const unsigned char *buf,
+static int avrftdi_transmit_bb(const PROGRAMMER *pgm, unsigned char mode, const unsigned char *buf,
 			    unsigned char *data, int buf_size)
 {
 	size_t remaining = buf_size;
@@ -461,7 +454,7 @@ static int avrftdi_transmit_mpsse(avrftdi_t* pdata, unsigned char mode, const un
 	return written;
 }
 
-static inline int avrftdi_transmit(PROGRAMMER * pgm, unsigned char mode, const unsigned char *buf,
+static inline int avrftdi_transmit(const PROGRAMMER *pgm, unsigned char mode, const unsigned char *buf,
 			    unsigned char *data, int buf_size)
 {
 	avrftdi_t* pdata = to_pdata(pgm);
@@ -520,8 +513,7 @@ static int write_flush(avrftdi_t* pdata)
 
 }
 
-static int avrftdi_check_pins_bb(PROGRAMMER * pgm, bool output)
-{
+static int avrftdi_check_pins_bb(const PROGRAMMER *pgm, bool output) {
 	int pin;
 
 	/* pin checklist. */
@@ -548,8 +540,7 @@ static int avrftdi_check_pins_bb(PROGRAMMER * pgm, bool output)
 	return pins_check(pgm, pin_checklist, N_PINS, output);
 }
 
-static int avrftdi_check_pins_mpsse(PROGRAMMER * pgm, bool output)
-{
+static int avrftdi_check_pins_mpsse(const PROGRAMMER *pgm, bool output) {
 	int pin;
 
 	/* pin checklist. */
@@ -593,8 +584,7 @@ static int avrftdi_check_pins_mpsse(PROGRAMMER * pgm, bool output)
 	return pins_check(pgm, pin_checklist, N_PINS, output);
 }
 
-static int avrftdi_pin_setup(PROGRAMMER * pgm)
-{
+static int avrftdi_pin_setup(const PROGRAMMER *pgm) {
 	int pin;
 
 	/*************
@@ -648,8 +638,7 @@ static int avrftdi_pin_setup(PROGRAMMER * pgm)
 	return 0;
 }
 
-static int avrftdi_open(PROGRAMMER * pgm, char *port)
-{
+static int avrftdi_open(PROGRAMMER *pgm, const char *port) {
 	int vid, pid, interface, index, err;
 	const char *serial, *desc;
 	
@@ -817,8 +806,7 @@ static void avrftdi_close(PROGRAMMER * pgm)
 	return;
 }
 
-static int avrftdi_initialize(PROGRAMMER * pgm, AVRPART * p)
-{
+static int avrftdi_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
 	avrftdi_powerup(pgm);
 
 	if(p->flags & AVRPART_HAS_TPI)
@@ -847,21 +835,18 @@ static int avrftdi_initialize(PROGRAMMER * pgm, AVRPART * p)
 	return pgm->program_enable(pgm, p);
 }
 
-static void avrftdi_display(PROGRAMMER * pgm, const char *p)
-{
+static void avrftdi_display(const PROGRAMMER *pgm, const char *p) {
 	// print the full pin definitions as in ft245r ?
 	return;
 }
 
 
-static int avrftdi_cmd(PROGRAMMER * pgm, const unsigned char *cmd, unsigned char *res)
-{
+static int avrftdi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) {
 	return avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, res, 4);
 }
 
 
-static int avrftdi_program_enable(PROGRAMMER * pgm, AVRPART * p)
-{
+static int avrftdi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
 	int i;
 	unsigned char buf[4];
 
@@ -892,8 +877,7 @@ static int avrftdi_program_enable(PROGRAMMER * pgm, AVRPART * p)
 }
 
 
-static int avrftdi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+static int avrftdi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
 	unsigned char cmd[4];
 	unsigned char res[4];
 
@@ -915,8 +899,7 @@ static int avrftdi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
 
 /* Load extended address byte command */
 static int
-avrftdi_lext(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m, unsigned int address)
-{
+avrftdi_lext(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int address) {
 	/* nothing to do if load extended address command unavailable */
 	if(m->op[AVR_OP_LOAD_EXT_ADDR] == NULL)
 		return 0;
@@ -943,7 +926,7 @@ avrftdi_lext(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m, unsigned int address)
 	return 0;
 }
 
-static int avrftdi_eeprom_write(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
+static int avrftdi_eeprom_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
 		unsigned int page_size, unsigned int addr, unsigned int len)
 {
 	unsigned char cmd[] = { 0x00, 0x00, 0x00, 0x00 };
@@ -965,7 +948,7 @@ static int avrftdi_eeprom_write(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
 	return len;
 }
 
-static int avrftdi_eeprom_read(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
+static int avrftdi_eeprom_read(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
 		unsigned int page_size, unsigned int addr, unsigned int len)
 {
 	unsigned char cmd[4];
@@ -991,7 +974,7 @@ static int avrftdi_eeprom_read(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
 	return len;
 }
 
-static int avrftdi_flash_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int avrftdi_flash_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
 		unsigned int page_size, unsigned int addr, unsigned int len)
 {
 	unsigned int word;
@@ -1101,7 +1084,7 @@ static int avrftdi_flash_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 /*
  *Reading from flash
  */
-static int avrftdi_flash_read(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int avrftdi_flash_read(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
 		unsigned int page_size, unsigned int addr, unsigned int len)
 {
 	OPCODE * readop;
@@ -1178,7 +1161,7 @@ static int avrftdi_flash_read(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 	return len;
 }
 
-static int avrftdi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int avrftdi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
 		unsigned int page_size, unsigned int addr, unsigned int n_bytes)
 {
 	if (strcmp(m->desc, "flash") == 0)
@@ -1189,7 +1172,7 @@ static int avrftdi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 		return -2;
 }
 
-static int avrftdi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int avrftdi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
 		unsigned int page_size, unsigned int addr, unsigned int n_bytes)
 {
 	if (strcmp(m->desc, "flash") == 0)
@@ -1238,9 +1221,7 @@ avrftdi_teardown(PROGRAMMER * pgm)
 	}
 }
 
-void avrftdi_initpgm(PROGRAMMER * pgm)
-{
-
+void avrftdi_initpgm(PROGRAMMER *pgm) {
 	strcpy(pgm->type, "avrftdi");
 
 	/*
diff --git a/src/avrftdi.h b/src/avrftdi.h
index af323352..167264df 100644
--- a/src/avrftdi.h
+++ b/src/avrftdi.h
@@ -29,7 +29,7 @@ extern "C" {
 
 
 extern const char avrftdi_desc[];
-void avrftdi_initpgm        (PROGRAMMER * pgm);
+void avrftdi_initpgm(PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/avrftdi_tpi.c b/src/avrftdi_tpi.c
index efb56266..dcb3d48d 100644
--- a/src/avrftdi_tpi.c
+++ b/src/avrftdi_tpi.c
@@ -15,8 +15,8 @@
 
 #ifndef DO_NOT_BUILD_AVRFTDI
 
-static void avrftdi_tpi_disable(PROGRAMMER *);
-static int avrftdi_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p);
+static void avrftdi_tpi_disable(const PROGRAMMER *);
+static int avrftdi_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p);
 
 #ifdef notyet
 static void
@@ -63,23 +63,12 @@ avrftdi_debug_frame(uint16_t frame)
 #endif /* notyet */
 
 int
-avrftdi_tpi_initialize(PROGRAMMER * pgm, AVRPART * p)
-{
+avrftdi_tpi_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
 	int ret;
 
 	avrftdi_t* pdata = to_pdata(pgm);
 	unsigned char buf[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 0x01, 0x00, 0xff, 0xff };
 
-	log_info("Using TPI interface\n");
-
-	pgm->program_enable = avrftdi_tpi_program_enable;
-	pgm->cmd_tpi = avrftdi_cmd_tpi;
-	pgm->chip_erase = avr_tpi_chip_erase;
-	pgm->disable = avrftdi_tpi_disable;
-
-	pgm->paged_load = NULL;
-	pgm->paged_write = NULL;
-
 	log_info("Setting /Reset pin low\n");
 	pgm->setpin(pgm, PIN_AVR_RESET, OFF);
 	pgm->setpin(pgm, PIN_AVR_SCK, OFF);
@@ -101,6 +90,20 @@ avrftdi_tpi_initialize(PROGRAMMER * pgm, AVRPART * p)
 	return ret;
 }
 
+
+void avrftdi_tpi_initpgm(PROGRAMMER *pgm) {
+	  log_info("Using TPI interface\n");
+
+	  pgm->program_enable = avrftdi_tpi_program_enable;
+	  pgm->cmd_tpi = avrftdi_cmd_tpi;
+	  pgm->chip_erase = avr_tpi_chip_erase;
+	  pgm->disable = avrftdi_tpi_disable;
+
+	  pgm->paged_load = NULL;
+	  pgm->paged_write = NULL;
+}
+
+
 #define TPI_PARITY_MASK 0x2000
 
 static inline int count1s(unsigned int x)
@@ -148,8 +151,7 @@ tpi_frame2byte(uint16_t frame, uint8_t * byte)
 
 #ifdef notyet
 static int
-avrftdi_tpi_break(PROGRAMMER * pgm)
-{
+avrftdi_tpi_break(const PROGRAMMER *pgm) {
 	unsigned char buffer[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 1, 0, 0, 0 };
 	E(ftdi_write_data(to_pdata(pgm)->ftdic, buffer, sizeof(buffer)) != sizeof(buffer), to_pdata(pgm)->ftdic);
 
@@ -158,8 +160,7 @@ avrftdi_tpi_break(PROGRAMMER * pgm)
 #endif /* notyet */
 
 static int
-avrftdi_tpi_write_byte(PROGRAMMER * pgm, unsigned char byte)
-{
+avrftdi_tpi_write_byte(const PROGRAMMER *pgm, unsigned char byte) {
 	uint16_t frame;
 
 	struct ftdi_context* ftdic = to_pdata(pgm)->ftdic;
@@ -185,8 +186,7 @@ avrftdi_tpi_write_byte(PROGRAMMER * pgm, unsigned char byte)
 #define TPI_IDLE_BITS   2
 
 static int
-avrftdi_tpi_read_byte(PROGRAMMER * pgm, unsigned char * byte)
-{
+avrftdi_tpi_read_byte(const PROGRAMMER *pgm, unsigned char *byte) {
 	uint16_t frame;
 	
 	/* use 2 guard bits, 2 default idle bits + 12 frame bits = 16 bits total */
@@ -230,13 +230,12 @@ avrftdi_tpi_read_byte(PROGRAMMER * pgm, unsigned char * byte)
 }
 
 static int
-avrftdi_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p)
-{
+avrftdi_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
 	return avr_tpi_program_enable(pgm, p, TPIPCR_GT_2b);
 }
 
 int
-avrftdi_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd, int cmd_len,
+avrftdi_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, int cmd_len,
 		unsigned char *res, int res_len)
 {
 	int i, err = 0;
@@ -259,8 +258,7 @@ avrftdi_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd, int cmd_len,
 }
 
 static void
-avrftdi_tpi_disable(PROGRAMMER * pgm)
-{
+avrftdi_tpi_disable(const PROGRAMMER *pgm) {
 	unsigned char cmd[] = {TPI_OP_SSTCS(TPIPCR), 0};
 	pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0);
 
diff --git a/src/avrftdi_tpi.h b/src/avrftdi_tpi.h
index 6082a379..f9a07515 100644
--- a/src/avrftdi_tpi.h
+++ b/src/avrftdi_tpi.h
@@ -1,9 +1,10 @@
 #pragma once
 
-//int avrftdi_tpi_write_byte(PROGRAMMER * pgm, unsigned char byte);
-//int avrftdi_tpi_read_byte(PROGRAMMER * pgm, unsigned char * byte);
-int avrftdi_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd, int cmd_len,
+//int avrftdi_tpi_write_byte(PROGRAMMER *pgm, unsigned char byte);
+//int avrftdi_tpi_read_byte(PROGRAMMER *pgm, unsigned char * byte);
+int avrftdi_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, int cmd_len,
 		unsigned char *res, int res_len);
-int avrftdi_tpi_initialize(PROGRAMMER * pgm, AVRPART * p);
+int avrftdi_tpi_initialize(const PROGRAMMER *pgm, const AVRPART *p);
+void avrftdi_tpi_initpgm(PROGRAMMER *pgm);
 
 
diff --git a/src/bitbang.c b/src/bitbang.c
index 592ca124..c043d740 100644
--- a/src/bitbang.c
+++ b/src/bitbang.c
@@ -163,8 +163,7 @@ void bitbang_delay(unsigned int us)
 /*
  * transmit and receive a byte of data to/from the AVR device
  */
-static unsigned char bitbang_txrx(PROGRAMMER * pgm, unsigned char byte)
-{
+static unsigned char bitbang_txrx(const PROGRAMMER *pgm, unsigned char byte) {
   int i;
   unsigned char r, b, rbyte;
 
@@ -208,8 +207,7 @@ static unsigned char bitbang_txrx(PROGRAMMER * pgm, unsigned char byte)
   return rbyte;
 }
 
-static int bitbang_tpi_clk(PROGRAMMER * pgm) 
-{
+static int bitbang_tpi_clk(const PROGRAMMER *pgm)  {
   unsigned char r = 0;
   pgm->setpin(pgm, PIN_AVR_SCK, 1);
 
@@ -220,8 +218,7 @@ static int bitbang_tpi_clk(PROGRAMMER * pgm)
   return r;
 }
 
-void bitbang_tpi_tx(PROGRAMMER * pgm, unsigned char byte) 
-{
+void bitbang_tpi_tx(const PROGRAMMER *pgm, unsigned char byte)  {
   int i;
   unsigned char b, parity;
 
@@ -249,8 +246,7 @@ void bitbang_tpi_tx(PROGRAMMER * pgm, unsigned char byte)
   bitbang_tpi_clk(pgm);
 }
 
-int bitbang_tpi_rx(PROGRAMMER * pgm) 
-{
+int bitbang_tpi_rx(const PROGRAMMER *pgm)  {
   int i;
   unsigned char b, rbyte, parity;
 
@@ -296,26 +292,22 @@ int bitbang_tpi_rx(PROGRAMMER * pgm)
   return rbyte;
 }
 
-int bitbang_rdy_led(PROGRAMMER * pgm, int value)
-{
+int bitbang_rdy_led(const PROGRAMMER *pgm, int value) {
   pgm->setpin(pgm, PIN_LED_RDY, !value);
   return 0;
 }
 
-int bitbang_err_led(PROGRAMMER * pgm, int value)
-{
+int bitbang_err_led(const PROGRAMMER *pgm, int value) {
   pgm->setpin(pgm, PIN_LED_ERR, !value);
   return 0;
 }
 
-int bitbang_pgm_led(PROGRAMMER * pgm, int value)
-{
+int bitbang_pgm_led(const PROGRAMMER *pgm, int value) {
   pgm->setpin(pgm, PIN_LED_PGM, !value);
   return 0;
 }
 
-int bitbang_vfy_led(PROGRAMMER * pgm, int value)
-{
+int bitbang_vfy_led(const PROGRAMMER *pgm, int value) {
   pgm->setpin(pgm, PIN_LED_VFY, !value);
   return 0;
 }
@@ -325,7 +317,7 @@ int bitbang_vfy_led(PROGRAMMER * pgm, int value)
  * transmit an AVR device command and return the results; 'cmd' and
  * 'res' must point to at least a 4 byte data buffer
  */
-int bitbang_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
+int bitbang_cmd(const PROGRAMMER *pgm, const unsigned char *cmd,
                    unsigned char *res)
 {
   int i;
@@ -350,7 +342,7 @@ int bitbang_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
   return 0;
 }
 
-int bitbang_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd,
+int bitbang_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd,
                        int cmd_len, unsigned char *res, int res_len)
 {
   int i, r;
@@ -392,7 +384,7 @@ int bitbang_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd,
  * transmit bytes via SPI and return the results; 'cmd' and
  * 'res' must point to data buffers
  */
-int bitbang_spi(PROGRAMMER * pgm, const unsigned char *cmd,
+int bitbang_spi(const PROGRAMMER *pgm, const unsigned char *cmd,
                    unsigned char *res, int count)
 {
   int i;
@@ -425,8 +417,7 @@ int bitbang_spi(PROGRAMMER * pgm, const unsigned char *cmd,
 /*
  * issue the 'chip erase' command to the AVR device
  */
-int bitbang_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+int bitbang_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char cmd[4];
   unsigned char res[4];
   AVRMEM *mem;
@@ -486,8 +477,7 @@ int bitbang_chip_erase(PROGRAMMER * pgm, AVRPART * p)
 /*
  * issue the 'program enable' command to the AVR device
  */
-int bitbang_program_enable(PROGRAMMER * pgm, AVRPART * p)
-{
+int bitbang_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char cmd[4];
   unsigned char res[4];
   int i;
@@ -523,8 +513,7 @@ int bitbang_program_enable(PROGRAMMER * pgm, AVRPART * p)
 /*
  * initialize the AVR device and prepare it to accept commands
  */
-int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
-{
+int bitbang_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
   int rc;
   int tries;
   int i;
@@ -626,8 +615,7 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static int verify_pin_assigned(PROGRAMMER * pgm, int pin, char * desc)
-{
+static int verify_pin_assigned(const PROGRAMMER *pgm, int pin, char *desc) {
   if (pgm->pinno[pin] == 0) {
     avrdude_message(MSG_INFO, "%s: error: no pin has been assigned for %s\n",
             progname, desc);
@@ -640,8 +628,7 @@ static int verify_pin_assigned(PROGRAMMER * pgm, int pin, char * desc)
 /*
  * Verify all prerequisites for a bit-bang programmer are present.
  */
-int bitbang_check_prerequisites(PROGRAMMER *pgm)
-{
+int bitbang_check_prerequisites(const PROGRAMMER *pgm) {
 
   if (verify_pin_assigned(pgm, PIN_AVR_RESET, "AVR RESET") < 0)
     return -1;
diff --git a/src/bitbang.h b/src/bitbang.h
index b0131314..f837c1e5 100644
--- a/src/bitbang.h
+++ b/src/bitbang.h
@@ -31,25 +31,25 @@ int bitbang_getpin(int fd, int pin);
 int bitbang_highpulsepin(int fd, int pin);
 void bitbang_delay(unsigned int us);
 
-int bitbang_check_prerequisites(PROGRAMMER *pgm);
+int bitbang_check_prerequisites(const PROGRAMMER *pgm);
 
-int  bitbang_rdy_led        (PROGRAMMER * pgm, int value);
-int  bitbang_err_led        (PROGRAMMER * pgm, int value);
-int  bitbang_pgm_led        (PROGRAMMER * pgm, int value);
-int  bitbang_vfy_led        (PROGRAMMER * pgm, int value);
-int  bitbang_cmd            (PROGRAMMER * pgm, const unsigned char *cmd,
+int  bitbang_rdy_led        (const PROGRAMMER *pgm, int value);
+int  bitbang_err_led        (const PROGRAMMER *pgm, int value);
+int  bitbang_pgm_led        (const PROGRAMMER *pgm, int value);
+int  bitbang_vfy_led        (const PROGRAMMER *pgm, int value);
+int  bitbang_cmd            (const PROGRAMMER *pgm, const unsigned char *cmd,
                                 unsigned char *res);
-int  bitbang_cmd_tpi        (PROGRAMMER * pgm, const unsigned char *cmd,
+int  bitbang_cmd_tpi        (const PROGRAMMER *pgm, const unsigned char *cmd,
                                 int cmd_len, unsigned char *res, int res_len);
-int  bitbang_spi            (PROGRAMMER * pgm, const unsigned char *cmd,
+int  bitbang_spi            (const PROGRAMMER *pgm, const unsigned char *cmd,
                                 unsigned char *res, int count);
-int  bitbang_chip_erase     (PROGRAMMER * pgm, AVRPART * p);
-int  bitbang_program_enable (PROGRAMMER * pgm, AVRPART * p);
-void bitbang_powerup        (PROGRAMMER * pgm);
-void bitbang_powerdown      (PROGRAMMER * pgm);
-int  bitbang_initialize     (PROGRAMMER * pgm, AVRPART * p);
-void bitbang_disable        (PROGRAMMER * pgm);
-void bitbang_enable         (PROGRAMMER * pgm);
+int  bitbang_chip_erase     (const PROGRAMMER *pgm, const AVRPART *p);
+int  bitbang_program_enable (const PROGRAMMER *pgm, const AVRPART *p);
+void bitbang_powerup        (const PROGRAMMER *pgm);
+void bitbang_powerdown      (const PROGRAMMER *pgm);
+int  bitbang_initialize     (const PROGRAMMER *pgm, const AVRPART *p);
+void bitbang_disable        (const PROGRAMMER *pgm);
+void bitbang_enable         (PROGRAMMER *pgm, const AVRPART *p);
 
 #ifdef __cplusplus
 }
diff --git a/src/buspirate.c b/src/buspirate.c
index 36848179..72a8134e 100644
--- a/src/buspirate.c
+++ b/src/buspirate.c
@@ -76,14 +76,14 @@ struct pdata
 	unsigned char pin_dir;		/* Last written pin direction for bitbang mode */
 	unsigned char pin_val;		/* Last written pin values for bitbang mode */
 	int     unread_bytes;		/* How many bytes we expected, but ignored */
+        int     flag;
 };
 #define PDATA(pgm) ((struct pdata *)(pgm->cookie))
 
 /* ====== Feature checks ====== */
 static inline int
-buspirate_uses_ascii(struct programmer_t *pgm)
-{
-	return (pgm->flag & BP_FLAG_XPARM_FORCE_ASCII);
+buspirate_uses_ascii(const PROGRAMMER *pgm) {
+	return (PDATA(pgm)->flag & BP_FLAG_XPARM_FORCE_ASCII);
 }
 
 /* ====== Serial talker functions - binmode ====== */
@@ -105,8 +105,7 @@ static void dump_mem(const int msglvl, const unsigned char *buf, size_t len)
 		avrdude_message(msglvl, "\n");
 }
 
-static int buspirate_send_bin(struct programmer_t *pgm, const unsigned char *data, size_t len)
-{
+static int buspirate_send_bin(const PROGRAMMER *pgm, const unsigned char *data, size_t len) {
 	int rc;
 
 	avrdude_message(MSG_DEBUG, "%s: buspirate_send_bin():\n", progname);
@@ -117,8 +116,7 @@ static int buspirate_send_bin(struct programmer_t *pgm, const unsigned char *dat
 	return rc;
 }
 
-static int buspirate_recv_bin(struct programmer_t *pgm, unsigned char *buf, size_t len)
-{
+static int buspirate_recv_bin(const PROGRAMMER *pgm, unsigned char *buf, size_t len) {
 	int rc;
 
 	rc = serial_recv(&pgm->fd, buf, len);
@@ -131,12 +129,12 @@ static int buspirate_recv_bin(struct programmer_t *pgm, unsigned char *buf, size
 	return len;
 }
 
-static int buspirate_expect_bin(struct programmer_t *pgm,
+static int buspirate_expect_bin(const PROGRAMMER *pgm,
 				unsigned char *send_data, size_t send_len,
 				unsigned char *expect_data, size_t expect_len)
 {
 	unsigned char *recv_buf = alloca(expect_len);
-	if ((pgm->flag & BP_FLAG_IN_BINMODE) == 0) {
+	if ((PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) == 0) {
 		avrdude_message(MSG_INFO, "BusPirate: Internal error: buspirate_send_bin() called from ascii mode\n");
 		return -1;
 	}
@@ -148,7 +146,7 @@ static int buspirate_expect_bin(struct programmer_t *pgm,
 	return 1;
 }
 
-static int buspirate_expect_bin_byte(struct programmer_t *pgm,
+static int buspirate_expect_bin_byte(const PROGRAMMER *pgm,
 					unsigned char send_byte, unsigned char expect_byte)
 {
 	return buspirate_expect_bin(pgm, &send_byte, 1, &expect_byte, 1);
@@ -156,12 +154,11 @@ static int buspirate_expect_bin_byte(struct programmer_t *pgm,
 
 /* ====== Serial talker functions - ascii mode ====== */
 
-static int buspirate_getc(struct programmer_t *pgm)
-{
+static int buspirate_getc(const PROGRAMMER *pgm) {
 	int rc;
 	unsigned char ch = 0;
 
-	if (pgm->flag & BP_FLAG_IN_BINMODE) {
+	if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) {
 		avrdude_message(MSG_INFO, "BusPirate: Internal error: buspirate_getc() called from binmode\n");
 		return EOF;
 	}
@@ -172,8 +169,7 @@ static int buspirate_getc(struct programmer_t *pgm)
 	return ch;
 }
 
-static char *buspirate_readline_noexit(struct programmer_t *pgm, char *buf, size_t len)
-{
+static char *buspirate_readline_noexit(const PROGRAMMER *pgm, char *buf, size_t len) {
 	char *buf_p;
 	int c;
 	long orig_serial_recv_timeout = serial_recv_timeout;
@@ -210,8 +206,7 @@ static char *buspirate_readline_noexit(struct programmer_t *pgm, char *buf, size
 	return buf;
 }
 
-static char *buspirate_readline(struct programmer_t *pgm, char *buf, size_t len)
-{
+static char *buspirate_readline(const PROGRAMMER *pgm, char *buf, size_t len) {
 	char *ret;
 
 	ret = buspirate_readline_noexit(pgm, buf, len);
@@ -222,14 +217,13 @@ static char *buspirate_readline(struct programmer_t *pgm, char *buf, size_t len)
 	}
 	return ret;
 }
-static int buspirate_send(struct programmer_t *pgm, const char *str)
-{
+static int buspirate_send(const PROGRAMMER *pgm, const char *str) {
 	int rc;
 	const char * readline;
 
 	avrdude_message(MSG_DEBUG, "%s: buspirate_send(): %s", progname, str);
 
-	if (pgm->flag & BP_FLAG_IN_BINMODE) {
+	if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) {
 		avrdude_message(MSG_INFO, "BusPirate: Internal error: buspirate_send() called from binmode\n");
 		return -1;
 	}
@@ -256,7 +250,7 @@ static int buspirate_is_prompt(const char *str)
 	return (str[strlen_str - 1] == '>' || str[strlen_str - 2] == '>');
 }
 
-static int buspirate_expect(struct programmer_t *pgm, char *send,
+static int buspirate_expect(const PROGRAMMER *pgm, char *send,
 				char *expect, int wait_for_prompt)
 {
 	int got_it = 0;
@@ -285,14 +279,12 @@ static int buspirate_expect(struct programmer_t *pgm, char *send,
 }
 
 /* ====== Do-nothing functions ====== */
-static void buspirate_dummy_6(struct programmer_t *pgm, const char *p)
-{
+static void buspirate_dummy_6(const PROGRAMMER *pgm, const char *p) {
 }
 
 /* ====== Config / parameters handling functions ====== */
 static int
-buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
-{
+buspirate_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
 	LNODEID ln;
 	const char *extended_param;
 	char reset[10];
@@ -305,7 +297,7 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
 	for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
 		extended_param = ldata(ln);
 		if (strcmp(extended_param, "ascii") == 0) {
-			pgm->flag |= BP_FLAG_XPARM_FORCE_ASCII;
+			PDATA(pgm)->flag |= BP_FLAG_XPARM_FORCE_ASCII;
 			continue;
 		}
 
@@ -315,11 +307,11 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
 				avrdude_message(MSG_INFO, "BusPirate: see BusPirate manual for details.\n");
 				return -1;
 			}
-			if (pgm->flag & BP_FLAG_XPARM_RAWFREQ) {
+			if (PDATA(pgm)->flag & BP_FLAG_XPARM_RAWFREQ) {
 				avrdude_message(MSG_INFO, "BusPirate: set either spifreq or rawfreq\n");
 				return -1;
 			}
-			pgm->flag |=  BP_FLAG_XPARM_SPIFREQ;
+			PDATA(pgm)->flag |=  BP_FLAG_XPARM_SPIFREQ;
 			PDATA(pgm)->spifreq = spifreq;
 			continue;
 		}
@@ -330,11 +322,11 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
 				                "between 0 and 3.\n");
 				return -1;
 			}
-			if (pgm->flag & BP_FLAG_XPARM_SPIFREQ) {
+			if (PDATA(pgm)->flag & BP_FLAG_XPARM_SPIFREQ) {
 				avrdude_message(MSG_INFO, "BusPirate: set either spifreq or rawfreq\n");
 				return -1;
 			}
-			pgm->flag |=  BP_FLAG_XPARM_RAWFREQ;
+			PDATA(pgm)->flag |=  BP_FLAG_XPARM_RAWFREQ;
 			PDATA(pgm)->spifreq = rawfreq;
 			continue;
 		}
@@ -347,7 +339,7 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
 				return -1;
 			}
 			PDATA(pgm)->cpufreq = cpufreq;
-			pgm->flag |= BP_FLAG_XPARM_CPUFREQ;
+			PDATA(pgm)->flag |= BP_FLAG_XPARM_CPUFREQ;
 			continue;
 		}
 
@@ -366,17 +358,17 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
 					return -1;
 				}
 			}
-			pgm->flag |= BP_FLAG_XPARM_RESET;
+			PDATA(pgm)->flag |= BP_FLAG_XPARM_RESET;
 			continue;
 		}
 
 		if (strcmp(extended_param, "nopagedwrite") == 0) {
-			pgm->flag |= BP_FLAG_NOPAGEDWRITE;
+			PDATA(pgm)->flag |= BP_FLAG_NOPAGEDWRITE;
 			continue;
 		}
 
 		if (strcmp(extended_param, "nopagedread") == 0) {
-			pgm->flag |= BP_FLAG_NOPAGEDREAD;
+			PDATA(pgm)->flag |= BP_FLAG_NOPAGEDREAD;
 			continue;
 		}
 
@@ -397,8 +389,7 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
 }
 
 static int
-buspirate_verifyconfig(struct programmer_t *pgm)
-{
+buspirate_verifyconfig(const PROGRAMMER *pgm) {
 	/* Default reset pin is CS */
 	if (PDATA(pgm)->reset == 0x00)
 		PDATA(pgm)->reset |= BP_RESET_CS;
@@ -408,7 +399,7 @@ buspirate_verifyconfig(struct programmer_t *pgm)
 		return -1;
 	}
 
-	if (  ((pgm->flag & BP_FLAG_XPARM_SPIFREQ) || (pgm->flag & BP_FLAG_XPARM_RAWFREQ))
+	if (  ((PDATA(pgm)->flag & BP_FLAG_XPARM_SPIFREQ) || (PDATA(pgm)->flag & BP_FLAG_XPARM_RAWFREQ))
 	   && buspirate_uses_ascii(pgm)) {
 		avrdude_message(MSG_INFO, "BusPirate: SPI speed selection is not supported in ASCII mode\n");
 		return -1;
@@ -418,8 +409,7 @@ buspirate_verifyconfig(struct programmer_t *pgm)
 }
 
 /* ====== Programmer methods ======= */
-static int buspirate_open(struct programmer_t *pgm, char * port)
-{
+static int buspirate_open(PROGRAMMER *pgm, const char *port) {
 	union pinfo pinfo;
 	/* BusPirate runs at 115200 by default */
 	if(pgm->baudrate == 0)
@@ -438,21 +428,20 @@ static int buspirate_open(struct programmer_t *pgm, char * port)
 	return 0;
 }
 
-static void buspirate_close(struct programmer_t *pgm)
+static void buspirate_close(PROGRAMMER *pgm)
 {
 	serial_close(&pgm->fd);
 	pgm->fd.ifd = -1;
 }
 
-static void buspirate_reset_from_binmode(struct programmer_t *pgm)
-{
+static void buspirate_reset_from_binmode(const PROGRAMMER *pgm) {
 	unsigned char buf[10];
 
 	buf[0] = 0x00;	/* BinMode: revert to raw bitbang mode */
 	buspirate_send_bin(pgm, buf, 1);
 	buspirate_recv_bin(pgm, buf, 5);
 
-	if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
+	if (PDATA(pgm)->flag & BP_FLAG_XPARM_CPUFREQ) {
 		/* disable pwm */
 		if (buspirate_expect_bin_byte(pgm, 0x13, 0x01) != 1) {
 			avrdude_message(MSG_INFO, "%s: warning: did not get a response to stop PWM command.\n", progname);
@@ -474,7 +463,7 @@ static void buspirate_reset_from_binmode(struct programmer_t *pgm)
 		rc = buspirate_recv_bin(pgm, buf, sizeof(buf) - 1);
 
 		if (buspirate_is_prompt((const char*)buf)) {
-			pgm->flag &= ~BP_FLAG_IN_BINMODE;
+			PDATA(pgm)->flag &= ~BP_FLAG_IN_BINMODE;
 			break;
 		}
 		if (rc == EOF)
@@ -482,7 +471,7 @@ static void buspirate_reset_from_binmode(struct programmer_t *pgm)
 		memset(buf, '\0', sizeof(buf));
 	}
 
-	if (pgm->flag & BP_FLAG_IN_BINMODE) {
+	if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) {
 		avrdude_message(MSG_INFO, "BusPirate reset failed. You may need to powercycle it.\n");
 		return;
 	}
@@ -490,7 +479,7 @@ static void buspirate_reset_from_binmode(struct programmer_t *pgm)
 	avrdude_message(MSG_NOTICE, "BusPirate is back in the text mode\n");
 }
 
-static int buspirate_start_mode_bin(struct programmer_t *pgm)
+static int buspirate_start_mode_bin(PROGRAMMER *pgm)
 {
 	struct submode {
 		const char *name;  /* Name of mode for user messages */
@@ -499,13 +488,13 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
 		char config;  /* Command to setup submode parameters */
 	} submode;
 
-	if (pgm->flag & BP_FLAG_XPARM_RAWFREQ) {
+	if (PDATA(pgm)->flag & BP_FLAG_XPARM_RAWFREQ) {
 		submode.name = "Raw-wire";
 		submode.enter = 0x05;
 		submode.entered_format = "RAW%1d";
 		submode.config = 0x8C;
-		pgm->flag |= BP_FLAG_NOPAGEDWRITE;
-		pgm->flag |= BP_FLAG_NOPAGEDREAD;
+		PDATA(pgm)->flag |= BP_FLAG_NOPAGEDWRITE;
+		PDATA(pgm)->flag |= BP_FLAG_NOPAGEDREAD;
 	} else {
 		submode.name = "SPI";
 		submode.enter = 0x01;
@@ -535,9 +524,9 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
 	avrdude_message(MSG_NOTICE, "BusPirate binmode version: %d\n",
                 PDATA(pgm)->binmode_version);
 
-	pgm->flag |= BP_FLAG_IN_BINMODE;
+	PDATA(pgm)->flag |= BP_FLAG_IN_BINMODE;
 
-	if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
+	if (PDATA(pgm)->flag & BP_FLAG_XPARM_CPUFREQ) {
 		unsigned short pwm_duty;
 		unsigned short pwm_period;
 
@@ -574,7 +563,7 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
 	avrdude_message(MSG_NOTICE, "BusPirate %s version: %d\n", 
 	                submode.name, PDATA(pgm)->submode_version);
 
-	if (pgm->flag & BP_FLAG_NOPAGEDWRITE) {
+	if (PDATA(pgm)->flag & BP_FLAG_NOPAGEDWRITE) {
                 avrdude_message(MSG_NOTICE, "%s: Paged flash write disabled.\n", progname);
 		pgm->paged_write = NULL;
 	} else {
@@ -585,7 +574,7 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
 		if (buf[0] != 0x01) {
 
 			/* Disable paged write: */
-			pgm->flag |= BP_FLAG_NOPAGEDWRITE;
+			PDATA(pgm)->flag |= BP_FLAG_NOPAGEDWRITE;
 			pgm->paged_write = NULL;
 
 			/* Return to SPI mode (0x00s have landed us back in binary bitbang mode): */
@@ -617,7 +606,7 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
 		return -1;
 
 	/* AVR Extended Commands - test for existence */
-	if (pgm->flag & BP_FLAG_NOPAGEDREAD) {
+	if (PDATA(pgm)->flag & BP_FLAG_NOPAGEDREAD) {
                 avrdude_message(MSG_NOTICE, "%s: Paged flash read disabled.\n", progname);
 		pgm->paged_load = NULL;
 	} else {
@@ -633,7 +622,7 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
 			avrdude_message(MSG_NOTICE, "AVR Extended Commands version %d\n", ver);
 		} else {
 			avrdude_message(MSG_NOTICE, "AVR Extended Commands not found.\n");
-			pgm->flag |= BP_FLAG_NOPAGEDREAD;
+			PDATA(pgm)->flag |= BP_FLAG_NOPAGEDREAD;
 			pgm->paged_load = NULL;
 		}
 	}
@@ -641,8 +630,7 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
 	return 0;
 }
 
-static int buspirate_start_spi_mode_ascii(struct programmer_t *pgm)
-{
+static int buspirate_start_spi_mode_ascii(const PROGRAMMER *pgm) {
 	int spi_cmd = -1;
 	int cmd;
 	char *rcvd;
@@ -700,8 +688,7 @@ static int buspirate_start_spi_mode_ascii(struct programmer_t *pgm)
 	return 0;
 }
 
-static void buspirate_enable(struct programmer_t *pgm)
-{
+static void buspirate_enable(PROGRAMMER *pgm, const AVRPART *p) {
 	static const char *reset_str = "#\n";
 	static const char *accept_str = "y\n";
 	char *rcvd;
@@ -759,7 +746,7 @@ static void buspirate_enable(struct programmer_t *pgm)
 			avrdude_message(MSG_DEBUG, "**  %s", rcvd);
 	}
 
-	if (!(pgm->flag & BP_FLAG_IN_BINMODE)) {
+	if (!(PDATA(pgm)->flag & BP_FLAG_IN_BINMODE)) {
 		avrdude_message(MSG_INFO, "BusPirate: using ASCII mode\n");
 		if (buspirate_start_spi_mode_ascii(pgm) < 0) {
 			avrdude_message(MSG_INFO, "%s: Failed to start ascii SPI mode\n", progname);
@@ -768,9 +755,8 @@ static void buspirate_enable(struct programmer_t *pgm)
 	}
 }
 
-static void buspirate_disable(struct programmer_t *pgm)
-{
-	if (pgm->flag & BP_FLAG_IN_BINMODE) {
+static void buspirate_disable(const PROGRAMMER *pgm) {
+	if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) {
 		serial_recv_timeout = 100;
 		buspirate_reset_from_binmode(pgm);
 	} else {
@@ -778,21 +764,19 @@ static void buspirate_disable(struct programmer_t *pgm)
 	}
 }
 
-static int buspirate_initialize(struct programmer_t *pgm, AVRPART * p)
-{
+static int buspirate_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
 	pgm->powerup(pgm);
 
 	return pgm->program_enable(pgm, p);
 }
 
-static void buspirate_powerup(struct programmer_t *pgm)
-{
-	if (pgm->flag & BP_FLAG_IN_BINMODE) {
+static void buspirate_powerup(const PROGRAMMER *pgm) {
+	if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) {
 		/* Powerup in BinMode is handled in binary mode init */
 		return;
 	} else {
 		if (buspirate_expect(pgm, "W\n", "POWER SUPPLIES ON", 1)) {
-			if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
+			if (PDATA(pgm)->flag & BP_FLAG_XPARM_CPUFREQ) {
 				char buf[25];
 				int ok = 0;
 				snprintf(buf, sizeof(buf), "%d\n", PDATA(pgm)->cpufreq);
@@ -815,13 +799,12 @@ static void buspirate_powerup(struct programmer_t *pgm)
 	avrdude_message(MSG_INFO, "%s: warning: Trying to continue anyway...\n", progname);
 }
 
-static void buspirate_powerdown(struct programmer_t *pgm)
-{
-	if (pgm->flag & BP_FLAG_IN_BINMODE) {
+static void buspirate_powerdown(const PROGRAMMER *pgm) {
+	if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) {
 		/* Powerdown in BinMode is handled in binary mode init */
 		return;
 	} else {
-		if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
+		if (PDATA(pgm)->flag & BP_FLAG_XPARM_CPUFREQ) {
 			if (!buspirate_expect(pgm, "g\n", "PWM disabled", 1)) {
 				avrdude_message(MSG_INFO, "%s: warning: did not get a response to stop PWM command.\n", progname);
 			}
@@ -833,7 +816,7 @@ static void buspirate_powerdown(struct programmer_t *pgm)
 	avrdude_message(MSG_INFO, "%s: warning: did not get a response to PowerDown command.\n", progname);
 }
 
-static int buspirate_cmd_bin(struct programmer_t *pgm,
+static int buspirate_cmd_bin(const PROGRAMMER *pgm,
 				const unsigned char *cmd,
 				unsigned char *res)
 {
@@ -851,7 +834,7 @@ static int buspirate_cmd_bin(struct programmer_t *pgm,
 	return 0;
 }
 
-static int buspirate_cmd_ascii(struct programmer_t *pgm,
+static int buspirate_cmd_ascii(const PROGRAMMER *pgm,
 				const unsigned char *cmd,
 				unsigned char *res)
 {
@@ -888,25 +871,20 @@ static int buspirate_cmd_ascii(struct programmer_t *pgm,
 	return 0;
 }
 
-static int buspirate_cmd(struct programmer_t *pgm,
+static int buspirate_cmd(const PROGRAMMER *pgm,
 				const unsigned char *cmd,
 				unsigned char *res)
 {
-	if (pgm->flag & BP_FLAG_IN_BINMODE)
+	if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE)
 		return buspirate_cmd_bin(pgm, cmd, res);
 	else
 		return buspirate_cmd_ascii(pgm, cmd, res);
 }
 
 /* Paged load function which utilizes the AVR Extended Commands set */
-static int buspirate_paged_load(
-		PROGRAMMER *pgm,
-		AVRPART *p,
-		AVRMEM *m,
-		unsigned int page_size,
-		unsigned int address,
-		unsigned int n_bytes)
-{
+static int buspirate_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
+  unsigned int page_size, unsigned int address, unsigned int n_bytes) {
+
 	unsigned char commandbuf[10];
 	unsigned char buf[275];
 	unsigned int addr = 0;
@@ -914,7 +892,7 @@ static int buspirate_paged_load(
 	avrdude_message(MSG_NOTICE, "BusPirate: buspirate_paged_load(..,%s,%d,%d,%d)\n",m->desc,m->page_size,address,n_bytes);
 
 	// This should never happen, but still...
-	if (pgm->flag & BP_FLAG_NOPAGEDREAD) {
+	if (PDATA(pgm)->flag & BP_FLAG_NOPAGEDREAD) {
 		avrdude_message(MSG_INFO, "BusPirate: buspirate_paged_load() called while in nopagedread mode!\n");
 		return -1;
 	}
@@ -956,13 +934,9 @@ static int buspirate_paged_load(
 	return n_bytes;
 }
 /* Paged write function which utilizes the Bus Pirate's "Write then Read" binary SPI instruction */
-static int buspirate_paged_write(struct programmer_t *pgm,
-		AVRPART *p,
-		AVRMEM *m,
-		unsigned int page_size,
-		unsigned int base_addr,
-		unsigned int n_data_bytes)
-{
+static int buspirate_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
+  unsigned int page_size, unsigned int base_addr, unsigned int n_data_bytes) {
+
 	int page, i;
 	int addr = base_addr;
 	int n_page_writes;
@@ -970,12 +944,12 @@ static int buspirate_paged_write(struct programmer_t *pgm,
 	unsigned char cmd_buf[4096] = {'\0'};
 	unsigned char send_byte, recv_byte;
 
-	if (!(pgm->flag & BP_FLAG_IN_BINMODE)) {
+	if (!(PDATA(pgm)->flag & BP_FLAG_IN_BINMODE)) {
 		/* Return if we are not in binary mode. */
 		return -1;
 	}
 
-	if (pgm->flag & BP_FLAG_NOPAGEDWRITE) {
+	if (PDATA(pgm)->flag & BP_FLAG_NOPAGEDWRITE) {
 		/* Return if we've nominated not to use paged writes. */
 		return -1;
 	}
@@ -1074,12 +1048,11 @@ static int buspirate_paged_write(struct programmer_t *pgm,
 	return n_data_bytes;
 }
 
-static int buspirate_program_enable(struct programmer_t *pgm, AVRPART * p)
-{
+static int buspirate_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
 	unsigned char cmd[4];
 	unsigned char res[4];
 
-	if (pgm->flag & BP_FLAG_IN_BINMODE) {
+	if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) {
 		/* Clear configured reset pin(s): CS and/or AUX and/or AUX2 */
 		PDATA(pgm)->current_peripherals_config &= ~PDATA(pgm)->reset;
 		if (buspirate_expect_bin_byte(pgm, PDATA(pgm)->current_peripherals_config, 0x01) < 0)
@@ -1104,8 +1077,7 @@ static int buspirate_program_enable(struct programmer_t *pgm, AVRPART * p)
 	return 0;
 }
 
-static int buspirate_chip_erase(struct programmer_t *pgm, AVRPART * p)
-{
+static int buspirate_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
 	unsigned char cmd[4];
 	unsigned char res[4];
 
@@ -1130,7 +1102,7 @@ static int buspirate_chip_erase(struct programmer_t *pgm, AVRPART * p)
 }
 
 /* Interface - management */
-static void buspirate_setup(struct programmer_t *pgm)
+static void buspirate_setup(PROGRAMMER *pgm)
 {
 	/* Allocate private data */
 	if ((pgm->cookie = calloc(1, sizeof(struct pdata))) == 0) {
@@ -1141,14 +1113,13 @@ static void buspirate_setup(struct programmer_t *pgm)
 	PDATA(pgm)->serial_recv_timeout = 100;
 }
 
-static void buspirate_teardown(struct programmer_t *pgm)
+static void buspirate_teardown(PROGRAMMER *pgm)
 {
 	free(pgm->cookie);
 }
 const char buspirate_desc[] = "Using the Bus Pirate's SPI interface for programming";
 
-void buspirate_initpgm(struct programmer_t *pgm)
-{
+void buspirate_initpgm(PROGRAMMER *pgm) {
 	strcpy(pgm->type, "BusPirate");
 
 	pgm->display        = buspirate_dummy_6;
@@ -1181,8 +1152,7 @@ void buspirate_initpgm(struct programmer_t *pgm)
 
 /* Bitbang support */
 
-static void buspirate_bb_enable(struct programmer_t *pgm)
-{
+static void buspirate_bb_enable(PROGRAMMER *pgm, const AVRPART *p) {
 	unsigned char buf[20] = { '\0' };
 
 	if (bitbang_check_prerequisites(pgm) < 0)
@@ -1210,7 +1180,7 @@ static void buspirate_bb_enable(struct programmer_t *pgm)
 	avrdude_message(MSG_INFO, "BusPirate binmode version: %d\n",
 	                PDATA(pgm)->binmode_version);
 
-	pgm->flag |= BP_FLAG_IN_BINMODE;
+	PDATA(pgm)->flag |= BP_FLAG_IN_BINMODE;
 
 	/* Set pin directions and an initial pin status (all high) */
 	PDATA(pgm)->pin_dir = 0x12;  /* AUX, MISO input; everything else output */
@@ -1241,8 +1211,7 @@ static void buspirate_bb_enable(struct programmer_t *pgm)
    Both respond with a byte with current status:
    0|POWER|PULLUP|AUX|MOSI|CLK|MISO|CS
 */
-static int buspirate_bb_getpin(struct programmer_t *pgm, int pinfunc)
-{
+static int buspirate_bb_getpin(const PROGRAMMER *pgm, int pinfunc) {
 	unsigned char buf[10];
 	int value = 0;
 	int pin = pgm->pinno[pinfunc];
@@ -1277,8 +1246,7 @@ static int buspirate_bb_getpin(struct programmer_t *pgm, int pinfunc)
 	return value;
 }
 
-static int buspirate_bb_setpin_internal(struct programmer_t *pgm, int pin, int value)
-{
+static int buspirate_bb_setpin_internal(const PROGRAMMER *pgm, int pin, int value) {
 	unsigned char buf[10];
 
 	if (pin & PIN_INVERSE) {
@@ -1307,14 +1275,12 @@ static int buspirate_bb_setpin_internal(struct programmer_t *pgm, int pin, int v
 	return 0;
 }
 
-static int buspirate_bb_setpin(struct programmer_t *pgm, int pinfunc, int value)
-{
+static int buspirate_bb_setpin(const PROGRAMMER *pgm, int pinfunc, int value) {
 	return buspirate_bb_setpin_internal(pgm, pgm->pinno[pinfunc], value);
 }
 
 
-static int buspirate_bb_highpulsepin(struct programmer_t *pgm, int pinfunc)
-{
+static int buspirate_bb_highpulsepin(const PROGRAMMER *pgm, int pinfunc) {
 	int ret;
 	ret = buspirate_bb_setpin(pgm, pinfunc, 1);
 	if (ret < 0)
@@ -1322,20 +1288,17 @@ static int buspirate_bb_highpulsepin(struct programmer_t *pgm, int pinfunc)
 	return buspirate_bb_setpin(pgm, pinfunc, 0);
 }
 
-static void buspirate_bb_powerup(struct programmer_t *pgm)
-{
+static void buspirate_bb_powerup(const PROGRAMMER *pgm) {
 	buspirate_bb_setpin_internal(pgm, 7, 1);
 }
 
-static void buspirate_bb_powerdown(struct programmer_t *pgm)
-{
+static void buspirate_bb_powerdown(const PROGRAMMER *pgm) {
 	buspirate_bb_setpin_internal(pgm, 7, 0);
 }
 
 const char buspirate_bb_desc[] = "Using the Bus Pirate's bitbang interface for programming";
 
-void buspirate_bb_initpgm(struct programmer_t *pgm)
-{
+void buspirate_bb_initpgm(PROGRAMMER *pgm) {
 	strcpy(pgm->type, "BusPirate_BB");
 
 	pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
diff --git a/src/buspirate.h b/src/buspirate.h
index 835334a2..12a68a1a 100644
--- a/src/buspirate.h
+++ b/src/buspirate.h
@@ -26,7 +26,7 @@
 
 extern const char buspirate_desc[];
 extern const char buspirate_bb_desc[];
-void buspirate_initpgm (struct programmer_t *pgm);
-void buspirate_bb_initpgm (struct programmer_t *pgm);
+void buspirate_initpgm(PROGRAMMER *pgm);
+void buspirate_bb_initpgm(PROGRAMMER *pgm);
 
 #endif
diff --git a/src/butterfly.c b/src/butterfly.c
index 1d5fafdf..2cc6cb0b 100644
--- a/src/butterfly.c
+++ b/src/butterfly.c
@@ -75,14 +75,12 @@ static void butterfly_teardown(PROGRAMMER * pgm)
   free(pgm->cookie);
 }
 
-static int butterfly_send(PROGRAMMER * pgm, char * buf, size_t len)
-{
+static int butterfly_send(const PROGRAMMER *pgm, char *buf, size_t len) {
   return serial_send(&pgm->fd, (unsigned char *)buf, len);
 }
 
 
-static int butterfly_recv(PROGRAMMER * pgm, char * buf, size_t len)
-{
+static int butterfly_recv(const PROGRAMMER *pgm, char *buf, size_t len) {
   int rv;
 
   rv = serial_recv(&pgm->fd, (unsigned char *)buf, len);
@@ -95,14 +93,12 @@ static int butterfly_recv(PROGRAMMER * pgm, char * buf, size_t len)
 }
 
 
-static int butterfly_drain(PROGRAMMER * pgm, int display)
-{
+static int butterfly_drain(const PROGRAMMER *pgm, int display) {
   return serial_drain(&pgm->fd, display);
 }
 
 
-static int butterfly_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
-{
+static int butterfly_vfy_cmd_sent(const PROGRAMMER *pgm, char *errmsg) {
   char c;
 
   butterfly_recv(pgm, &c, 1);
@@ -115,32 +111,28 @@ static int butterfly_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
 }
 
 
-static int butterfly_rdy_led(PROGRAMMER * pgm, int value)
-{
+static int butterfly_rdy_led(const PROGRAMMER *pgm, int value) {
   /* Do nothing. */
 
   return 0;
 }
 
 
-static int butterfly_err_led(PROGRAMMER * pgm, int value)
-{
+static int butterfly_err_led(const PROGRAMMER *pgm, int value) {
   /* Do nothing. */
 
   return 0;
 }
 
 
-static int butterfly_pgm_led(PROGRAMMER * pgm, int value)
-{
+static int butterfly_pgm_led(const PROGRAMMER *pgm, int value) {
   /* Do nothing. */
 
   return 0;
 }
 
 
-static int butterfly_vfy_led(PROGRAMMER * pgm, int value)
-{
+static int butterfly_vfy_led(const PROGRAMMER *pgm, int value) {
   /* Do nothing. */
 
   return 0;
@@ -150,8 +142,7 @@ static int butterfly_vfy_led(PROGRAMMER * pgm, int value)
 /*
  * issue the 'chip erase' command to the butterfly board
  */
-static int butterfly_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+static int butterfly_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
   butterfly_send(pgm, "e", 1);
   if (butterfly_vfy_cmd_sent(pgm, "chip erase") < 0)
       return -1;
@@ -160,15 +151,13 @@ static int butterfly_chip_erase(PROGRAMMER * pgm, AVRPART * p)
 }
 
 
-static void butterfly_enter_prog_mode(PROGRAMMER * pgm)
-{
+static void butterfly_enter_prog_mode(const PROGRAMMER *pgm) {
   butterfly_send(pgm, "P", 1);
   butterfly_vfy_cmd_sent(pgm, "enter prog mode");
 }
 
 
-static void butterfly_leave_prog_mode(PROGRAMMER * pgm)
-{
+static void butterfly_leave_prog_mode(const PROGRAMMER *pgm) {
   butterfly_send(pgm, "L", 1);
   butterfly_vfy_cmd_sent(pgm, "leave prog mode");
 }
@@ -177,8 +166,7 @@ static void butterfly_leave_prog_mode(PROGRAMMER * pgm)
 /*
  * issue the 'program enable' command to the AVR device
  */
-static int butterfly_program_enable(PROGRAMMER * pgm, AVRPART * p)
-{
+static int butterfly_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
   return -1;
 }
 
@@ -186,8 +174,7 @@ static int butterfly_program_enable(PROGRAMMER * pgm, AVRPART * p)
 /*
  * apply power to the AVR processor
  */
-static void butterfly_powerup(PROGRAMMER * pgm)
-{
+static void butterfly_powerup(const PROGRAMMER *pgm) {
   /* Do nothing. */
 
   return;
@@ -197,8 +184,7 @@ static void butterfly_powerup(PROGRAMMER * pgm)
 /*
  * remove power from the AVR processor
  */
-static void butterfly_powerdown(PROGRAMMER * pgm)
-{
+static void butterfly_powerdown(const PROGRAMMER *pgm) {
   /* Do nothing. */
 
   return;
@@ -209,8 +195,7 @@ static void butterfly_powerdown(PROGRAMMER * pgm)
 /*
  * initialize the AVR device and prepare it to accept commands
  */
-static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
-{
+static int butterfly_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
   char id[8];
   char sw[2];
   char hw[2];
@@ -367,22 +352,19 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
 
 
 
-static void butterfly_disable(PROGRAMMER * pgm)
-{
+static void butterfly_disable(const PROGRAMMER *pgm) {
   butterfly_leave_prog_mode(pgm);
 
   return;
 }
 
 
-static void butterfly_enable(PROGRAMMER * pgm)
-{
+static void butterfly_enable(PROGRAMMER *pgm, const AVRPART *p) {
   return;
 }
 
 
-static int butterfly_open(PROGRAMMER * pgm, char * port)
-{
+static int butterfly_open(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo;
   strcpy(pgm->port, port);
   /*
@@ -417,14 +399,12 @@ static void butterfly_close(PROGRAMMER * pgm)
 }
 
 
-static void butterfly_display(PROGRAMMER * pgm, const char * p)
-{
+static void butterfly_display(const PROGRAMMER *pgm, const char *p) {
   return;
 }
 
 
-static void butterfly_set_addr(PROGRAMMER * pgm, unsigned long addr)
-{
+static void butterfly_set_addr(const PROGRAMMER *pgm, unsigned long addr) {
   char cmd[3];
 
   cmd[0] = 'A';
@@ -436,8 +416,7 @@ static void butterfly_set_addr(PROGRAMMER * pgm, unsigned long addr)
 }
 
 
-static void butterfly_set_extaddr(PROGRAMMER * pgm, unsigned long addr)
-{
+static void butterfly_set_extaddr(const PROGRAMMER *pgm, unsigned long addr) {
   char cmd[4];
 
   cmd[0] = 'H';
@@ -451,7 +430,7 @@ static void butterfly_set_extaddr(PROGRAMMER * pgm, unsigned long addr)
 
 
 
-static int butterfly_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int butterfly_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                              unsigned long addr, unsigned char value)
 {
   char cmd[6];
@@ -495,7 +474,7 @@ static int butterfly_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 }
 
 
-static int butterfly_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int butterfly_read_byte_flash(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                   unsigned long addr, unsigned char * value)
 {
   static int cached = 0;
@@ -536,7 +515,7 @@ static int butterfly_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 }
 
 
-static int butterfly_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int butterfly_read_byte_eeprom(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                    unsigned long addr, unsigned char * value)
 {
   butterfly_set_addr(pgm, addr);
@@ -545,8 +524,7 @@ static int butterfly_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return 0;
 }
 
-static int butterfly_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned int addr)
-{
+static int butterfly_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int addr) {
   if (strcmp(m->desc, "flash") == 0)
     return -1;            /* not supported */
   if (strcmp(m->desc, "eeprom") == 0)
@@ -556,7 +534,7 @@ static int butterfly_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsig
   return -1;
 }
 
-static int butterfly_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int butterfly_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                             unsigned long addr, unsigned char * value)
 {
   char cmd;
@@ -592,7 +570,7 @@ static int butterfly_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
 
 
-static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int butterfly_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                  unsigned int page_size,
                                  unsigned int addr, unsigned int n_bytes)
 {
@@ -647,7 +625,7 @@ static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
 
 
-static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int butterfly_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                 unsigned int page_size,
                                 unsigned int addr, unsigned int n_bytes)
 {
@@ -693,8 +671,7 @@ static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
 
 /* Signature byte reads are always 3 bytes. */
-static int butterfly_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
-{
+static int butterfly_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m) {
   unsigned char tmp;
 
   if (m->size < 3) {
@@ -714,8 +691,7 @@ static int butterfly_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
 
 const char butterfly_desc[] = "Atmel Butterfly evaluation board; Atmel AppNotes AVR109, AVR911";
 
-void butterfly_initpgm(PROGRAMMER * pgm)
-{
+void butterfly_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "butterfly");
 
   /*
@@ -755,8 +731,7 @@ void butterfly_initpgm(PROGRAMMER * pgm)
 
 const char butterfly_mk_desc[] = "Mikrokopter.de Butterfly";
 
-void butterfly_mk_initpgm(PROGRAMMER * pgm)
-{
+void butterfly_mk_initpgm(PROGRAMMER *pgm) {
   butterfly_initpgm(pgm);
   strcpy(pgm->type, "butterfly_mk");
   pgm->flag = IS_BUTTERFLY_MK;
diff --git a/src/butterfly.h b/src/butterfly.h
index 6f6a54c8..2d4bfa64 100644
--- a/src/butterfly.h
+++ b/src/butterfly.h
@@ -27,8 +27,8 @@ extern "C" {
 
 extern const char butterfly_desc[];
 extern const char butterfly_mk_desc[];
-void butterfly_initpgm (PROGRAMMER * pgm);
-void butterfly_mk_initpgm (PROGRAMMER * pgm);
+void butterfly_initpgm(PROGRAMMER *pgm);
+void butterfly_mk_initpgm(PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/config_gram.y b/src/config_gram.y
index c4c144a7..bd32de16 100644
--- a/src/config_gram.y
+++ b/src/config_gram.y
@@ -315,7 +315,7 @@ prog_decl :
     |
   K_PROGRAMMER K_PARENT TKN_STRING
     {
-      struct programmer_t * pgm = locate_programmer(programmers, $3->value.string);
+      PROGRAMMER * pgm = locate_programmer(programmers, $3->value.string);
       if (pgm == NULL) {
         yyerror("parent programmer %s not found", $3->value.string);
         free_token($3);
diff --git a/src/dfu.c b/src/dfu.c
index 8e014e3c..efa58c8a 100644
--- a/src/dfu.c
+++ b/src/dfu.c
@@ -38,7 +38,7 @@
 
 #ifndef HAVE_LIBUSB
 
-struct dfu_dev *dfu_open(char *port_name) {
+struct dfu_dev *dfu_open(const char *port_name) {
   avrdude_message(MSG_INFO, "%s: Error: No USB support in this compile of avrdude\n",
     progname);
   return NULL;
@@ -99,8 +99,7 @@ static char * get_usb_string(usb_dev_handle * dev_handle, int index);
 /* EXPORTED FUNCTION DEFINITIONS
  */
 
-struct dfu_dev * dfu_open(char *port_spec)
-{
+struct dfu_dev *dfu_open(const char *port_spec) {
   struct dfu_dev *dfu;
   char *bus_name = NULL;
   char *dev_name = NULL;
diff --git a/src/dfu.h b/src/dfu.h
index fa5da416..6be53a18 100644
--- a/src/dfu.h
+++ b/src/dfu.h
@@ -114,7 +114,7 @@ struct dfu_status {
 
 // FUNCTIONS
 
-extern struct dfu_dev * dfu_open(char *port_spec);
+extern struct dfu_dev *dfu_open(const char *port_spec);
 extern int dfu_init(struct dfu_dev *dfu,
   unsigned short vid, unsigned short pid);
 extern void dfu_close(struct dfu_dev *dfu);
diff --git a/src/doc/avrdude.texi b/src/doc/avrdude.texi
index a9242b4d..cdc7602b 100644
--- a/src/doc/avrdude.texi
+++ b/src/doc/avrdude.texi
@@ -1809,7 +1809,7 @@ part
     rampz            = <num> ;                # IO addr of RAMPZ reg.
     spmcr            = <num> ;                # mem addr of SPMC[S]R reg.
     eecr             = <num> ;                # mem addr of EECR reg.
-                                              # (only when != 0x3c)
+                                              # (only when != 0x3F)
     is_at90s1200     = <yes/no> ;             # AT90S1200 part
     is_avr32         = <yes/no> ;             # AVR32 part
 
diff --git a/src/flip1.c b/src/flip1.c
index 4db54aad..dbddfaf0 100644
--- a/src/flip1.c
+++ b/src/flip1.c
@@ -136,23 +136,23 @@ enum flip1_mem_unit {
 
 /* EXPORTED PROGRAMMER FUNCTION PROTOTYPES */
 
-static int flip1_open(PROGRAMMER *pgm, char *port_spec);
-static int flip1_initialize(PROGRAMMER* pgm, AVRPART *part);
+static int flip1_open(PROGRAMMER *pgm, const char *port_spec);
+static int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part);
 static void flip1_close(PROGRAMMER* pgm);
-static void flip1_enable(PROGRAMMER* pgm);
-static void flip1_disable(PROGRAMMER* pgm);
-static void flip1_display(PROGRAMMER* pgm, const char *prefix);
-static int flip1_program_enable(PROGRAMMER* pgm, AVRPART *part);
-static int flip1_chip_erase(PROGRAMMER* pgm, AVRPART *part);
-static int flip1_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+static void flip1_enable(PROGRAMMER *pgm, const AVRPART *p);
+static void flip1_disable(const PROGRAMMER *pgm);
+static void flip1_display(const PROGRAMMER *pgm, const char *prefix);
+static int flip1_program_enable(const PROGRAMMER *pgm, const AVRPART *part);
+static int flip1_chip_erase(const PROGRAMMER *pgm, const AVRPART *part);
+static int flip1_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned long addr, unsigned char *value);
-static int flip1_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+static int flip1_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned long addr, unsigned char value);
-static int flip1_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+static int flip1_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned int page_size, unsigned int addr, unsigned int n_bytes);
-static int flip1_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+static int flip1_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned int page_size, unsigned int addr, unsigned int n_bytes);
-static int flip1_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem);
+static int flip1_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem);
 static void flip1_setup(PROGRAMMER * pgm);
 static void flip1_teardown(PROGRAMMER * pgm);
 
@@ -162,7 +162,7 @@ static void flip1_teardown(PROGRAMMER * pgm);
 
 static void flip1_show_info(struct flip1 *flip1);
 
-static int flip1_read_memory(PROGRAMMER * pgm,
+static int flip1_read_memory(const PROGRAMMER *pgm,
   enum flip1_mem_unit mem_unit, uint32_t addr, void *ptr, int size);
 static int flip1_write_memory(struct dfu_dev *dfu,
   enum flip1_mem_unit mem_unit, uint32_t addr, const void *ptr, int size);
@@ -176,8 +176,7 @@ static enum flip1_mem_unit flip1_mem_unit(const char *name);
 
 /* THE INITPGM FUNCTION DEFINITIONS */
 
-void flip1_initpgm(PROGRAMMER *pgm)
-{
+void flip1_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "flip1");
 
   /* Mandatory Functions */
@@ -201,14 +200,12 @@ void flip1_initpgm(PROGRAMMER *pgm)
 #ifdef HAVE_LIBUSB
 /* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */
 
-int flip1_open(PROGRAMMER *pgm, char *port_spec)
-{
+int flip1_open(PROGRAMMER *pgm, const char *port_spec) {
   FLIP1(pgm)->dfu = dfu_open(port_spec);
   return (FLIP1(pgm)->dfu != NULL) ? 0 : -1;
 }
 
-int flip1_initialize(PROGRAMMER* pgm, AVRPART *part)
-{
+int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part) {
   unsigned short vid, pid;
   int result;
   struct dfu_dev *dfu = FLIP1(pgm)->dfu;
@@ -322,31 +319,26 @@ flip1_initialize_fail:
   return 0;
 }
 
-void flip1_close(PROGRAMMER* pgm)
-{
+void flip1_close(PROGRAMMER *pgm) {
   if (FLIP1(pgm)->dfu != NULL) {
     dfu_close(FLIP1(pgm)->dfu);
     FLIP1(pgm)->dfu = NULL;
   }
 }
 
-void flip1_enable(PROGRAMMER* pgm)
-{
+void flip1_enable(PROGRAMMER *pgm, const AVRPART *p) {
   /* Nothing to do. */
 }
 
-void flip1_disable(PROGRAMMER* pgm)
-{
+void flip1_disable(const PROGRAMMER *pgm) {
   /* Nothing to do. */
 }
 
-void flip1_display(PROGRAMMER* pgm, const char *prefix)
-{
+void flip1_display(const PROGRAMMER *pgm, const char *prefix) {
   /* Nothing to do. */
 }
 
-int flip1_program_enable(PROGRAMMER* pgm, AVRPART *part)
-{
+int flip1_program_enable(const PROGRAMMER *pgm, const AVRPART *part) {
   /* I couldn't find anything that uses this function, although it is marked
    * as "mandatory" in pgm.c. In case anyone does use it, we'll report an
    * error if we failed to initialize.
@@ -355,8 +347,7 @@ int flip1_program_enable(PROGRAMMER* pgm, AVRPART *part)
   return (FLIP1(pgm)->dfu != NULL) ? 0 : -1;
 }
 
-int flip1_chip_erase(PROGRAMMER* pgm, AVRPART *part)
-{
+int flip1_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) {
   struct dfu_status status;
   int cmd_result = 0;
   int aux_result;
@@ -387,7 +378,7 @@ int flip1_chip_erase(PROGRAMMER* pgm, AVRPART *part)
   return 0;
 }
 
-int flip1_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+int flip1_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned long addr, unsigned char *value)
 {
   enum flip1_mem_unit mem_unit;
@@ -424,7 +415,7 @@ int flip1_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
   return flip1_read_memory(pgm, mem_unit, addr, value, 1);
 }
 
-int flip1_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+int flip1_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned long addr, unsigned char value)
 {
   enum flip1_mem_unit mem_unit;
@@ -445,7 +436,7 @@ int flip1_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
   return flip1_write_memory(FLIP1(pgm)->dfu, mem_unit, addr, &value, 1);
 }
 
-int flip1_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+int flip1_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned int page_size, unsigned int addr, unsigned int n_bytes)
 {
   enum flip1_mem_unit mem_unit;
@@ -470,7 +461,7 @@ int flip1_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
   return flip1_read_memory(pgm, mem_unit, addr, mem->buf + addr, n_bytes);
 }
 
-int flip1_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+int flip1_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned int page_size, unsigned int addr, unsigned int n_bytes)
 {
   enum flip1_mem_unit mem_unit;
@@ -502,8 +493,7 @@ int flip1_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
   return (result == 0) ? n_bytes : -1;
 }
 
-int flip1_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
-{
+int flip1_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) {
   avrdude_message(MSG_NOTICE2, "%s: flip1_read_sig_bytes(): ", progname);
 
   if (FLIP1(pgm)->dfu == NULL)
@@ -605,7 +595,7 @@ void flip1_show_info(struct flip1 *flip1)
     (unsigned short) flip1->dfu->dev_desc.bMaxPacketSize0);
 }
 
-int flip1_read_memory(PROGRAMMER * pgm,
+int flip1_read_memory(const PROGRAMMER *pgm,
   enum flip1_mem_unit mem_unit, uint32_t addr, void *ptr, int size)
 {
   struct dfu_dev *dfu = FLIP1(pgm)->dfu;
@@ -864,15 +854,13 @@ enum flip1_mem_unit flip1_mem_unit(const char *name) {
 }
 #else /* HAVE_LIBUSB */
 // Dummy functions
-int flip1_open(PROGRAMMER *pgm, char *port_spec)
-{
+int flip1_open(PROGRAMMER *pgm, const char *port_spec) {
   fprintf(stderr, "%s: Error: No USB support in this compile of avrdude\n",
     progname);
   return -1;
 }
 
-int flip1_initialize(PROGRAMMER* pgm, AVRPART *part)
-{
+int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part) {
   return -1;
 }
 
@@ -880,54 +868,48 @@ void flip1_close(PROGRAMMER* pgm)
 {
 }
 
-void flip1_enable(PROGRAMMER* pgm)
-{
+void flip1_enable(PROGRAMMER *pgm, const AVRPART *p) {
 }
 
-void flip1_disable(PROGRAMMER* pgm)
-{
+void flip1_disable(const PROGRAMMER *pgm) {
 }
 
-void flip1_display(PROGRAMMER* pgm, const char *prefix)
-{
+void flip1_display(const PROGRAMMER *pgm, const char *prefix) {
 }
 
-int flip1_program_enable(PROGRAMMER* pgm, AVRPART *part)
-{
+int flip1_program_enable(const PROGRAMMER *pgm, const AVRPART *part) {
   return -1;
 }
 
-int flip1_chip_erase(PROGRAMMER* pgm, AVRPART *part)
-{
+int flip1_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) {
   return -1;
 }
 
-int flip1_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+int flip1_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned long addr, unsigned char *value)
 {
   return -1;
 }
 
-int flip1_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+int flip1_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned long addr, unsigned char value)
 {
   return -1;
 }
 
-int flip1_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+int flip1_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned int page_size, unsigned int addr, unsigned int n_bytes)
 {
   return -1;
 }
 
-int flip1_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+int flip1_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned int page_size, unsigned int addr, unsigned int n_bytes)
 {
   return -1;
 }
 
-int flip1_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
-{
+int flip1_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) {
   return -1;
 }
 
diff --git a/src/flip1.h b/src/flip1.h
index c5f4986b..276229e3 100644
--- a/src/flip1.h
+++ b/src/flip1.h
@@ -26,7 +26,7 @@ extern "C" {
 #endif
 
 extern const char flip1_desc[];
-extern void flip1_initpgm(PROGRAMMER * pgm);
+extern void flip1_initpgm(PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/flip2.c b/src/flip2.c
index a1bebc1c..a26da242 100644
--- a/src/flip2.c
+++ b/src/flip2.c
@@ -123,23 +123,23 @@ enum flip2_mem_unit {
 
 /* EXPORTED PROGRAMMER FUNCTION PROTOTYPES */
 
-static int flip2_open(PROGRAMMER *pgm, char *port_spec);
-static int flip2_initialize(PROGRAMMER* pgm, AVRPART *part);
+static int flip2_open(PROGRAMMER *pgm, const char *port_spec);
+static int flip2_initialize(const PROGRAMMER *pgm, const AVRPART *part);
 static void flip2_close(PROGRAMMER* pgm);
-static void flip2_enable(PROGRAMMER* pgm);
-static void flip2_disable(PROGRAMMER* pgm);
-static void flip2_display(PROGRAMMER* pgm, const char *prefix);
-static int flip2_program_enable(PROGRAMMER* pgm, AVRPART *part);
-static int flip2_chip_erase(PROGRAMMER* pgm, AVRPART *part);
-static int flip2_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+static void flip2_enable(PROGRAMMER *pgm, const AVRPART *p);
+static void flip2_disable(const PROGRAMMER *pgm);
+static void flip2_display(const PROGRAMMER *pgm, const char *prefix);
+static int flip2_program_enable(const PROGRAMMER *pgm, const AVRPART *part);
+static int flip2_chip_erase(const PROGRAMMER *pgm, const AVRPART *part);
+static int flip2_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned long addr, unsigned char *value);
-static int flip2_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+static int flip2_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned long addr, unsigned char value);
-static int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+static int flip2_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned int page_size, unsigned int addr, unsigned int n_bytes);
-static int flip2_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+static int flip2_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned int page_size, unsigned int addr, unsigned int n_bytes);
-static int flip2_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem);
+static int flip2_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem);
 static void flip2_setup(PROGRAMMER * pgm);
 static void flip2_teardown(PROGRAMMER * pgm);
 
@@ -170,8 +170,7 @@ static enum flip2_mem_unit flip2_mem_unit(const char *name);
 
 /* THE INITPGM FUNCTION DEFINITIONS */
 
-void flip2_initpgm(PROGRAMMER *pgm)
-{
+void flip2_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "flip2");
 
   /* Mandatory Functions */
@@ -195,14 +194,12 @@ void flip2_initpgm(PROGRAMMER *pgm)
 #ifdef HAVE_LIBUSB
 /* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */
 
-int flip2_open(PROGRAMMER *pgm, char *port_spec)
-{
+int flip2_open(PROGRAMMER *pgm, const char *port_spec) {
   FLIP2(pgm)->dfu = dfu_open(port_spec);
   return (FLIP2(pgm)->dfu != NULL) ? 0 : -1;
 }
 
-int flip2_initialize(PROGRAMMER* pgm, AVRPART *part)
-{
+int flip2_initialize(const PROGRAMMER *pgm, const AVRPART *part) {
   unsigned short vid, pid;
   int result;
   struct dfu_dev *dfu = FLIP2(pgm)->dfu;
@@ -323,23 +320,19 @@ void flip2_close(PROGRAMMER* pgm)
   }
 }
 
-void flip2_enable(PROGRAMMER* pgm)
-{
+void flip2_enable(PROGRAMMER *pgm, const AVRPART *p) {
   /* Nothing to do. */
 }
 
-void flip2_disable(PROGRAMMER* pgm)
-{
+void flip2_disable(const PROGRAMMER *pgm) {
   /* Nothing to do. */
 }
 
-void flip2_display(PROGRAMMER* pgm, const char *prefix)
-{
+void flip2_display(const PROGRAMMER *pgm, const char *prefix) {
   /* Nothing to do. */
 }
 
-int flip2_program_enable(PROGRAMMER* pgm, AVRPART *part)
-{
+int flip2_program_enable(const PROGRAMMER *pgm, const AVRPART *part) {
   /* I couldn't find anything that uses this function, although it is marked
    * as "mandatory" in pgm.c. In case anyone does use it, we'll report an
    * error if we failed to initialize.
@@ -348,8 +341,7 @@ int flip2_program_enable(PROGRAMMER* pgm, AVRPART *part)
   return (FLIP2(pgm)->dfu != NULL) ? 0 : -1;
 }
 
-int flip2_chip_erase(PROGRAMMER* pgm, AVRPART *part)
-{
+int flip2_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) {
   struct dfu_status status;
   int cmd_result = 0;
   int aux_result;
@@ -383,7 +375,7 @@ int flip2_chip_erase(PROGRAMMER* pgm, AVRPART *part)
   return cmd_result;
 }
 
-int flip2_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+int flip2_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned long addr, unsigned char *value)
 {
   enum flip2_mem_unit mem_unit;
@@ -406,7 +398,7 @@ int flip2_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
   return flip2_read_memory(FLIP2(pgm)->dfu, mem_unit, addr, value, 1);
 }
 
-int flip2_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+int flip2_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned long addr, unsigned char value)
 {
   enum flip2_mem_unit mem_unit;
@@ -429,7 +421,7 @@ int flip2_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
   return flip2_write_memory(FLIP2(pgm)->dfu, mem_unit, addr, &value, 1);
 }
 
-int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+int flip2_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned int page_size, unsigned int addr, unsigned int n_bytes)
 {
   enum flip2_mem_unit mem_unit;
@@ -463,7 +455,7 @@ int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
   return (result == 0) ? n_bytes : -1;
 }
 
-int flip2_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+int flip2_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned int page_size, unsigned int addr, unsigned int n_bytes)
 {
   enum flip2_mem_unit mem_unit;
@@ -497,8 +489,7 @@ int flip2_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
   return (result == 0) ? n_bytes : -1;
 }
 
-int flip2_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
-{
+int flip2_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) {
   if (FLIP2(pgm)->dfu == NULL)
     return -1;
 
@@ -918,15 +909,13 @@ enum flip2_mem_unit flip2_mem_unit(const char *name) {
 
 /* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */
 
-int flip2_open(PROGRAMMER *pgm, char *port_spec)
-{
+int flip2_open(PROGRAMMER *pgm, const char *port_spec) {
   fprintf(stderr, "%s: Error: No USB support in this compile of avrdude\n",
     progname);
   return -1;
 }
 
-int flip2_initialize(PROGRAMMER* pgm, AVRPART *part)
-{
+int flip2_initialize(const PROGRAMMER *pgm, const AVRPART *part) {
   return -1;
 }
 
@@ -934,54 +923,48 @@ void flip2_close(PROGRAMMER* pgm)
 {
 }
 
-void flip2_enable(PROGRAMMER* pgm)
-{
+void flip2_enable(PROGRAMMER *pgm, const AVRPART *p) {
 }
 
-void flip2_disable(PROGRAMMER* pgm)
-{
+void flip2_disable(const PROGRAMMER *pgm) {
 }
 
-void flip2_display(PROGRAMMER* pgm, const char *prefix)
-{
+void flip2_display(const PROGRAMMER *pgm, const char *prefix) {
 }
 
-int flip2_program_enable(PROGRAMMER* pgm, AVRPART *part)
-{
+int flip2_program_enable(const PROGRAMMER *pgm, const AVRPART *part) {
   return -1;
 }
 
-int flip2_chip_erase(PROGRAMMER* pgm, AVRPART *part)
-{
+int flip2_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) {
   return -1;
 }
 
-int flip2_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+int flip2_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned long addr, unsigned char *value)
 {
   return -1;
 }
 
-int flip2_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+int flip2_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned long addr, unsigned char value)
 {
   return -1;
 }
 
-int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+int flip2_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned int page_size, unsigned int addr, unsigned int n_bytes)
 {
   return -1;
 }
 
-int flip2_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+int flip2_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned int page_size, unsigned int addr, unsigned int n_bytes)
 {
   return -1;
 }
 
-int flip2_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
-{
+int flip2_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) {
   return -1;
 }
 
diff --git a/src/flip2.h b/src/flip2.h
index 4b1e576d..002d3b3c 100644
--- a/src/flip2.h
+++ b/src/flip2.h
@@ -26,7 +26,7 @@ extern "C" {
 #endif
 
 extern const char flip2_desc[];
-extern void flip2_initpgm(PROGRAMMER * pgm);
+extern void flip2_initpgm(PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/ft245r.c b/src/ft245r.c
index 04790143..9048cc2f 100644
--- a/src/ft245r.c
+++ b/src/ft245r.c
@@ -93,14 +93,14 @@
 
 #if defined(DO_NOT_BUILD_FT245R)
 
-static int ft245r_noftdi_open (struct programmer_t *pgm, char * name) {
+static int ft245r_noftdi_open(PROGRAMMER *pgm, const char *name) {
     avrdude_message(MSG_INFO, "%s: error: no libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.\n",
                     progname);
 
     return -1;
 }
 
-void ft245r_initpgm(PROGRAMMER * pgm) {
+void ft245r_initpgm(PROGRAMMER *pgm) {
     strcpy(pgm->type, "ftdi_syncbb");
     pgm->open = ft245r_noftdi_open;
 }
@@ -153,25 +153,25 @@ static struct {
     uint8_t buf[FT245R_BUFSIZE];	// receive ring buffer
 } rx;
 
-static int ft245r_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
+static int ft245r_cmd(const PROGRAMMER *pgm, const unsigned char *cmd,
                       unsigned char *res);
-static int ft245r_tpi_tx(PROGRAMMER * pgm, uint8_t byte);
-static int ft245r_tpi_rx(PROGRAMMER * pgm, uint8_t *bytep);
+static int ft245r_tpi_tx(const PROGRAMMER *pgm, uint8_t byte);
+static int ft245r_tpi_rx(const PROGRAMMER *pgm, uint8_t *bytep);
 
 // Discard all data from the receive buffer.
-static void ft245r_rx_buf_purge(PROGRAMMER * pgm) {
+static void ft245r_rx_buf_purge(const PROGRAMMER *pgm) {
     rx.len = 0;
     rx.rd = rx.wr = 0;
 }
 
-static void ft245r_rx_buf_put(PROGRAMMER * pgm, uint8_t byte) {
+static void ft245r_rx_buf_put(const PROGRAMMER *pgm, uint8_t byte) {
     rx.len++;
     rx.buf[rx.wr++] = byte;
     if (rx.wr >= sizeof(rx.buf))
 	rx.wr = 0;
 }
 
-static uint8_t ft245r_rx_buf_get(PROGRAMMER * pgm) {
+static uint8_t ft245r_rx_buf_get(const PROGRAMMER *pgm) {
     rx.len--;
     uint8_t byte = rx.buf[rx.rd++];
     if (rx.rd >= sizeof(rx.buf))
@@ -180,7 +180,7 @@ static uint8_t ft245r_rx_buf_get(PROGRAMMER * pgm) {
 }
 
 /* Fill receive buffer with data from the FTDI receive FIFO.  */
-static int ft245r_fill(PROGRAMMER * pgm) {
+static int ft245r_fill(const PROGRAMMER *pgm) {
     uint8_t raw[FT245R_MIN_FIFO_SIZE];
     int i, nread;
 
@@ -197,8 +197,7 @@ static int ft245r_fill(PROGRAMMER * pgm) {
     return nread;
 }
 
-static int ft245r_rx_buf_fill_and_get(PROGRAMMER* pgm)
-{
+static int ft245r_rx_buf_fill_and_get(const PROGRAMMER *pgm) {
     while (rx.len == 0)
     {
         int result = ft245r_fill(pgm);
@@ -212,7 +211,7 @@ static int ft245r_rx_buf_fill_and_get(PROGRAMMER* pgm)
 }
 
 /* Flush pending TX data to the FTDI send FIFO.  */
-static int ft245r_flush(PROGRAMMER * pgm) {
+static int ft245r_flush(const PROGRAMMER *pgm) {
     int rv, len = tx.len, avail;
     uint8_t *src = tx.buf;
 
@@ -251,7 +250,7 @@ static int ft245r_flush(PROGRAMMER * pgm) {
     return 0;
 }
 
-static int ft245r_send2(PROGRAMMER * pgm, unsigned char * buf, size_t len,
+static int ft245r_send2(const PROGRAMMER *pgm, unsigned char *buf, size_t len,
 			bool discard_rx_data) {
     int i, j;
 
@@ -267,16 +266,16 @@ static int ft245r_send2(PROGRAMMER * pgm, unsigned char * buf, size_t len,
     return 0;
 }
 
-static int ft245r_send(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
+static int ft245r_send(const PROGRAMMER *pgm, unsigned char *buf, size_t len) {
     return ft245r_send2(pgm, buf, len, false);
 }
 
-static int ft245r_send_and_discard(PROGRAMMER * pgm, unsigned char * buf,
+static int ft245r_send_and_discard(const PROGRAMMER *pgm, unsigned char *buf,
 				   size_t len) {
     return ft245r_send2(pgm, buf, len, true);
 }
 
-static int ft245r_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
+static int ft245r_recv(const PROGRAMMER *pgm, unsigned char *buf, size_t len) {
     int i, j;
 
     ft245r_flush(pgm);
@@ -318,7 +317,7 @@ static int ft245r_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
 }
 
 
-static int ft245r_drain(PROGRAMMER * pgm, int display) {
+static int ft245r_drain(const PROGRAMMER *pgm, int display) {
     int r;
 
     // flush the buffer in the chip by changing the mode.....
@@ -334,13 +333,13 @@ static int ft245r_drain(PROGRAMMER * pgm, int display) {
 
 
 /* Ensure any pending writes are sent to the FTDI chip before sleeping.  */
-static void ft245r_usleep(PROGRAMMER * pgm, useconds_t usec) {
+static void ft245r_usleep(const PROGRAMMER *pgm, useconds_t usec) {
     ft245r_flush(pgm);
     usleep(usec);
 }
 
 
-static int ft245r_chip_erase(PROGRAMMER * pgm, AVRPART * p) {
+static int ft245r_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
     unsigned char cmd[4] = {0,0,0,0};
     unsigned char res[4];
 
@@ -360,7 +359,7 @@ static int ft245r_chip_erase(PROGRAMMER * pgm, AVRPART * p) {
 }
 
 
-static int ft245r_set_bitclock(PROGRAMMER * pgm) {
+static int ft245r_set_bitclock(const PROGRAMMER *pgm) {
     // libftdi1 multiplies bitbang baudrate by 4:
     int r, rate = 0, ftdi_rate = 3000000 / 4;
 
@@ -395,7 +394,7 @@ static int ft245r_set_bitclock(PROGRAMMER * pgm) {
     return 0;
 }
 
-static int get_pin(PROGRAMMER *pgm, int pinname) {
+static int get_pin(const PROGRAMMER *pgm, int pinname) {
   uint8_t byte;
 
   ft245r_flush(pgm);
@@ -407,7 +406,7 @@ static int get_pin(PROGRAMMER *pgm, int pinname) {
   return GET_BITS_0(byte, pgm, pinname) != 0;
 }
 
-static int set_pin(PROGRAMMER * pgm, int pinname, int val) {
+static int set_pin(const PROGRAMMER *pgm, int pinname, int val) {
     unsigned char buf[1];
 
     if (pgm->pin[pinname].mask[0] == 0) {
@@ -422,46 +421,45 @@ static int set_pin(PROGRAMMER * pgm, int pinname, int val) {
     return 0;
 }
 
-static int set_sck(PROGRAMMER * pgm, int value) {
+static int set_sck(const PROGRAMMER *pgm, int value) {
     return set_pin(pgm, PIN_AVR_SCK, value);
 }
 
-static int set_reset(PROGRAMMER * pgm, int value) {
+static int set_reset(const PROGRAMMER *pgm, int value) {
     return set_pin(pgm, PIN_AVR_RESET, value);
 }
 
-static int set_buff(PROGRAMMER * pgm, int value) {
+static int set_buff(const PROGRAMMER *pgm, int value) {
     return set_pin(pgm, PPI_AVR_BUFF, value);
 }
 
-static int set_vcc(PROGRAMMER * pgm, int value) {
+static int set_vcc(const PROGRAMMER *pgm, int value) {
     return set_pin(pgm, PPI_AVR_VCC, value);
 }
 
 /* these functions are callbacks, which go into the
  * PROGRAMMER data structure ("optional functions")
  */
-static int set_led_pgm(struct programmer_t * pgm, int value) {
+static int set_led_pgm(const PROGRAMMER *pgm, int value) {
     return set_pin(pgm, PIN_LED_PGM, value);
 }
 
-static int set_led_rdy(struct programmer_t * pgm, int value) {
+static int set_led_rdy(const PROGRAMMER *pgm, int value) {
     return set_pin(pgm, PIN_LED_RDY, value);
 }
 
-static int set_led_err(struct programmer_t * pgm, int value) {
+static int set_led_err(const PROGRAMMER *pgm, int value) {
     return set_pin(pgm, PIN_LED_ERR, value);
 }
 
-static int set_led_vfy(struct programmer_t * pgm, int value) {
+static int set_led_vfy(const PROGRAMMER *pgm, int value) {
     return set_pin(pgm, PIN_LED_VFY, value);
 }
 
 /*
  * apply power to the AVR processor
  */
-static void ft245r_powerup(PROGRAMMER * pgm)
-{
+static void ft245r_powerup(const PROGRAMMER *pgm) {
     set_vcc(pgm, ON); /* power up */
     ft245r_usleep(pgm, 100);
 }
@@ -470,18 +468,17 @@ static void ft245r_powerup(PROGRAMMER * pgm)
 /*
  * remove power from the AVR processor
  */
-static void ft245r_powerdown(PROGRAMMER * pgm)
-{
+static void ft245r_powerdown(const PROGRAMMER *pgm) {
     set_vcc(pgm, OFF); /* power down */
 }
 
 
-static void ft245r_disable(PROGRAMMER * pgm) {
+static void ft245r_disable(const PROGRAMMER *pgm) {
     set_buff(pgm, OFF);
 }
 
 
-static void ft245r_enable(PROGRAMMER * pgm) {
+static void ft245r_enable(PROGRAMMER *pgm, const AVRPART *p) {
   /*
    * Prepare to start talking to the connected device - pull reset low
    * first, delay a few milliseconds, then enable the buffer.  This
@@ -500,7 +497,7 @@ static void ft245r_enable(PROGRAMMER * pgm) {
 /*
  * issue the 'program enable' command to the AVR device
  */
-static int ft245r_program_enable(PROGRAMMER * pgm, AVRPART * p) {
+static int ft245r_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
     unsigned char cmd[4] = {0,0,0,0};
     unsigned char res[4];
     int i;
@@ -547,7 +544,7 @@ static int ft245r_program_enable(PROGRAMMER * pgm, AVRPART * p) {
 /*
  * initialize the AVR device and prepare it to accept commands
  */
-static int ft245r_initialize(PROGRAMMER * pgm, AVRPART * p) {
+static int ft245r_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
 
     /* Apply power between VCC and GND while RESET and SCK are set to “0”. In some systems,
      * the programmer can not guarantee that SCK is held low during power-up. In this
@@ -616,7 +613,7 @@ static int ft245r_initialize(PROGRAMMER * pgm, AVRPART * p) {
     return ft245r_program_enable(pgm, p);
 }
 
-static inline void add_bit(PROGRAMMER * pgm, unsigned char *buf, int *buf_pos,
+static inline void add_bit(const PROGRAMMER *pgm, unsigned char *buf, int *buf_pos,
 			   uint8_t bit) {
     ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_MOSI, bit);
     ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0);
@@ -628,7 +625,7 @@ static inline void add_bit(PROGRAMMER * pgm, unsigned char *buf, int *buf_pos,
     (*buf_pos)++;
 }
 
-static inline int set_data(PROGRAMMER * pgm, unsigned char *buf, unsigned char data) {
+static inline int set_data(const PROGRAMMER *pgm, unsigned char *buf, unsigned char data) {
     int j;
     int buf_pos = 0;
     unsigned char bit = 0x80;
@@ -640,7 +637,7 @@ static inline int set_data(PROGRAMMER * pgm, unsigned char *buf, unsigned char d
     return buf_pos;
 }
 
-static inline unsigned char extract_data(PROGRAMMER * pgm, unsigned char *buf, int offset) {
+static inline unsigned char extract_data(const PROGRAMMER *pgm, unsigned char *buf, int offset) {
     int j;
     int buf_pos = FT245R_CYCLES; /* MISO data is valid AFTER rising SCK edge,
                                             i.e. in next clock cycle */
@@ -660,7 +657,7 @@ static inline unsigned char extract_data(PROGRAMMER * pgm, unsigned char *buf, i
 
 /* to check data */
 #if 0
-static inline unsigned char extract_data_out(PROGRAMMER * pgm, unsigned char *buf, int offset) {
+static inline unsigned char extract_data_out(const PROGRAMMER *pgm, unsigned char *buf, int offset) {
     int j;
     int buf_pos = 1;
     unsigned char bit = 0x80;
@@ -683,7 +680,7 @@ static inline unsigned char extract_data_out(PROGRAMMER * pgm, unsigned char *bu
  * transmit an AVR device command and return the results; 'cmd' and
  * 'res' must point to at least a 4 byte data buffer
  */
-static int ft245r_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
+static int ft245r_cmd(const PROGRAMMER *pgm, const unsigned char *cmd,
                       unsigned char *res) {
     int i,buf_pos;
     unsigned char buf[128];
@@ -705,7 +702,7 @@ static int ft245r_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
     return 0;
 }
 
-static inline uint8_t extract_tpi_data(PROGRAMMER * pgm, unsigned char *buf,
+static inline uint8_t extract_tpi_data(const PROGRAMMER *pgm, unsigned char *buf,
 				       int *buf_pos) {
     uint8_t bit = 0x1, byte = 0;
     int j;
@@ -719,7 +716,7 @@ static inline uint8_t extract_tpi_data(PROGRAMMER * pgm, unsigned char *buf,
     return byte;
 }
 
-static inline int set_tpi_data(PROGRAMMER * pgm, unsigned char *buf,
+static inline int set_tpi_data(const PROGRAMMER *pgm, unsigned char *buf,
 			       uint8_t byte) {
     uint8_t bit = 0x1, parity = 0;
     int j, buf_pos = 0;
@@ -742,7 +739,7 @@ static inline int set_tpi_data(PROGRAMMER * pgm, unsigned char *buf,
     return buf_pos;
 }
 
-static int ft245r_tpi_tx(PROGRAMMER * pgm, uint8_t byte) {
+static int ft245r_tpi_tx(const PROGRAMMER *pgm, uint8_t byte) {
     uint8_t buf[128];
     int len;
 
@@ -751,7 +748,7 @@ static int ft245r_tpi_tx(PROGRAMMER * pgm, uint8_t byte) {
     return 0;
 }
 
-static int ft245r_tpi_rx(PROGRAMMER * pgm, uint8_t *bytep) {
+static int ft245r_tpi_rx(const PROGRAMMER *pgm, uint8_t *bytep) {
     uint8_t buf[128], bit, parity;
     int i, buf_pos = 0, len = 0;
     uint32_t res, m, byte;
@@ -796,7 +793,7 @@ static int ft245r_tpi_rx(PROGRAMMER * pgm, uint8_t *bytep) {
     return 0;
 }
 
-static int ft245r_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd,
+static int ft245r_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd,
 			  int cmd_len, unsigned char *res, int res_len) {
     int i, ret = 0;
 
@@ -832,7 +829,7 @@ static const struct pin_checklist_t pin_checklist[] = {
     { PPI_AVR_BUFF, 0, &valid_pins},
 };
 
-static int ft245r_open(PROGRAMMER * pgm, char * port) {
+static int ft245r_open(PROGRAMMER *pgm, const char *port) {
     int rv;
     int devnum = -1;
     char device[9] = "";
@@ -987,13 +984,13 @@ static void ft245r_close(PROGRAMMER * pgm) {
     }
 }
 
-static void ft245r_display(PROGRAMMER * pgm, const char * p) {
+static void ft245r_display(const PROGRAMMER *pgm, const char *p) {
     avrdude_message(MSG_INFO, "%sPin assignment  : 0..7 = DBUS0..7\n",p);/* , 8..11 = GPIO0..3\n",p);*/
     pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS);
 }
 
 
-static int ft245r_paged_write_gen(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
+static int ft245r_paged_write_gen(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
              unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
 
     for(int i=0; i < (int) n_bytes; i++, addr++)
@@ -1035,7 +1032,7 @@ static void put_request(int addr, int bytes, int n) {
     }
 }
 
-static int do_request(PROGRAMMER * pgm, AVRMEM *m) {
+static int do_request(const PROGRAMMER *pgm, const AVRMEM *m) {
     struct ft245r_request *p;
     int addr, bytes, j, n;
     unsigned char buf[FT245R_FRAGMENT_SIZE+1+128];
@@ -1060,7 +1057,7 @@ static int do_request(PROGRAMMER * pgm, AVRMEM *m) {
 }
 
 
-static int ft245r_paged_write_flash(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
+static int ft245r_paged_write_flash(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
              unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
 
     int i, j, addr_save, buf_pos, req_count, do_page_write;
@@ -1127,7 +1124,7 @@ static int ft245r_paged_write_flash(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
 }
 
 
-static int ft245r_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int ft245r_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
             unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
 
     if(!n_bytes)
@@ -1142,7 +1139,7 @@ static int ft245r_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     return -2;
 }
 
-static int ft245r_paged_load_gen(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
+static int ft245r_paged_load_gen(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
              unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
 
     for(int i=0; i < (int) n_bytes; i++) {
@@ -1158,7 +1155,7 @@ static int ft245r_paged_load_gen(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
 }
 
 
-static int ft245r_paged_load_flash(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
+static int ft245r_paged_load_flash(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
             unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
 
     int i, j, addr_save, buf_pos, req_count;
@@ -1225,7 +1222,7 @@ static int ft245r_paged_load_flash(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
     return 0;
 }
 
-static int ft245r_paged_load(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
+static int ft245r_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
              unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
 
     if(!n_bytes)
@@ -1240,7 +1237,7 @@ static int ft245r_paged_load(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
    return -2;
 }
 
-void ft245r_initpgm(PROGRAMMER * pgm) {
+void ft245r_initpgm(PROGRAMMER *pgm) {
     strcpy(pgm->type, "ftdi_syncbb");
 
     /*
diff --git a/src/ft245r.h b/src/ft245r.h
index 40602e22..2495dc87 100644
--- a/src/ft245r.h
+++ b/src/ft245r.h
@@ -2,7 +2,7 @@
 #define ft245r_h
 
 extern const char ft245r_desc[];
-void ft245r_initpgm (PROGRAMMER * pgm);
+void ft245r_initpgm(PROGRAMMER *pgm);
 
 
 #endif /* ft245r_h */
diff --git a/src/jtag3.c b/src/jtag3.c
index a13c5c39..94b2b695 100644
--- a/src/jtag3.c
+++ b/src/jtag3.c
@@ -75,7 +75,7 @@ struct pdata
   bool use_hvupdi;
 
   /* Function to set the appropriate clock parameter */
-  int (*set_sck)(PROGRAMMER *, unsigned char *);
+  int (*set_sck)(const PROGRAMMER *, unsigned char *);
 };
 
 #define PDATA(pgm) ((struct pdata *)(pgm->cookie))
@@ -90,25 +90,25 @@ struct pdata
 #define PGM_FL_IS_EDBG          (0x0008)
 #define PGM_FL_IS_UPDI          (0x0010)
 
-static int jtag3_open(PROGRAMMER * pgm, char * port);
-static int jtag3_edbg_prepare(PROGRAMMER * pgm);
-static int jtag3_edbg_signoff(PROGRAMMER * pgm);
-static int jtag3_edbg_send(PROGRAMMER * pgm, unsigned char * data, size_t len);
-static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg);
+static int jtag3_open(PROGRAMMER *pgm, const char *port);
+static int jtag3_edbg_prepare(const PROGRAMMER *pgm);
+static int jtag3_edbg_signoff(const PROGRAMMER *pgm);
+static int jtag3_edbg_send(const PROGRAMMER *pgm, unsigned char *data, size_t len);
+static int jtag3_edbg_recv_frame(const PROGRAMMER *pgm, unsigned char **msg);
 
-static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p);
-static int jtag3_chip_erase(PROGRAMMER * pgm, AVRPART * p);
-static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p);
+static int jtag3_chip_erase(const PROGRAMMER *pgm, const AVRPART *p);
+static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                                 unsigned long addr, unsigned char * value);
-static int jtag3_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                                 unsigned long addr, unsigned char data);
-static int jtag3_set_sck_period(PROGRAMMER * pgm, double v);
-static void jtag3_print_parms1(PROGRAMMER * pgm, const char * p);
-static int jtag3_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int jtag3_set_sck_period(const PROGRAMMER *pgm, double v);
+static void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p);
+static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                 unsigned int page_size,
                                 unsigned int addr, unsigned int n_bytes);
-static unsigned char jtag3_memtype(PROGRAMMER * pgm, AVRPART * p, unsigned long addr);
-static unsigned int jtag3_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr);
+static unsigned char jtag3_memtype(const PROGRAMMER *pgm, const AVRPART *p, unsigned long addr);
+static unsigned int jtag3_memaddr(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr);
 
 
 void jtag3_setup(PROGRAMMER * pgm)
@@ -188,8 +188,7 @@ static void jtag3_print_data(unsigned char *b, size_t s)
     putc('\n', stderr);
 }
 
-static void jtag3_prmsg(PROGRAMMER * pgm, unsigned char * data, size_t len)
-{
+static void jtag3_prmsg(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
   int i;
 
   if (verbose >= 4) {
@@ -324,8 +323,7 @@ static int jtag3_errcode(int reason)
   return LIBAVRDUDE_GENERAL_FAILURE;
 }
 
-static void jtag3_prevent(PROGRAMMER * pgm, unsigned char * data, size_t len)
-{
+static void jtag3_prevent(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
   int i;
 
   if (verbose >= 4) {
@@ -416,8 +414,7 @@ static void jtag3_prevent(PROGRAMMER * pgm, unsigned char * data, size_t len)
 
 
 
-int jtag3_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
-{
+int jtag3_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
   unsigned char *buf;
 
   if (pgm->flag & PGM_FL_IS_EDBG)
@@ -450,8 +447,7 @@ int jtag3_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
   return 0;
 }
 
-static int jtag3_edbg_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
-{
+static int jtag3_edbg_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
   unsigned char buf[USBDEV_MAX_XFER_3];
   unsigned char status[USBDEV_MAX_XFER_3];
   int rv;
@@ -533,8 +529,7 @@ static int jtag3_edbg_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
 /*
  * Send out all the CMSIS-DAP stuff needed to prepare the ICE.
  */
-static int jtag3_edbg_prepare(PROGRAMMER * pgm)
-{
+static int jtag3_edbg_prepare(const PROGRAMMER *pgm) {
   unsigned char buf[USBDEV_MAX_XFER_3];
   unsigned char status[USBDEV_MAX_XFER_3];
   int rv;
@@ -591,8 +586,7 @@ static int jtag3_edbg_prepare(PROGRAMMER * pgm)
 /*
  * Send out all the CMSIS-DAP stuff when signing off.
  */
-static int jtag3_edbg_signoff(PROGRAMMER * pgm)
-{
+static int jtag3_edbg_signoff(const PROGRAMMER *pgm) {
   unsigned char buf[USBDEV_MAX_XFER_3];
   unsigned char status[USBDEV_MAX_XFER_3];
   int rv;
@@ -643,8 +637,7 @@ static int jtag3_edbg_signoff(PROGRAMMER * pgm)
 }
 
 
-static int jtag3_drain(PROGRAMMER * pgm, int display)
-{
+static int jtag3_drain(const PROGRAMMER *pgm, int display) {
   return serial_drain(&pgm->fd, display);
 }
 
@@ -657,7 +650,7 @@ static int jtag3_drain(PROGRAMMER * pgm, int display)
  *
  * Caller must eventually free the buffer.
  */
-static int jtag3_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
+static int jtag3_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) {
   int rv;
   unsigned char *buf = NULL;
 
@@ -689,7 +682,7 @@ static int jtag3_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
   return rv;
 }
 
-static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
+static int jtag3_edbg_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) {
   int rv, len = 0;
   unsigned char *buf = NULL;
   unsigned char *request;
@@ -803,7 +796,7 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
   return len;
 }
 
-int jtag3_recv(PROGRAMMER * pgm, unsigned char **msg) {
+int jtag3_recv(const PROGRAMMER *pgm, unsigned char **msg) {
   unsigned short r_seqno;
   int rv;
 
@@ -845,7 +838,7 @@ int jtag3_recv(PROGRAMMER * pgm, unsigned char **msg) {
   }
 }
 
-int jtag3_command(PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
+int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
 		   unsigned char **resp, const char *descr)
 {
   int status;
@@ -890,7 +883,7 @@ int jtag3_command(PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
 }
 
 
-int jtag3_getsync(PROGRAMMER * pgm, int mode) {
+int jtag3_getsync(const PROGRAMMER *pgm, int mode) {
 
   unsigned char buf[3], *resp;
 
@@ -921,8 +914,7 @@ int jtag3_getsync(PROGRAMMER * pgm, int mode) {
 /*
  * issue the 'chip erase' command to the AVR device
  */
-static int jtag3_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+static int jtag3_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char buf[8], *resp;
 
   buf[0] = SCOPE_AVR;
@@ -941,8 +933,7 @@ static int jtag3_chip_erase(PROGRAMMER * pgm, AVRPART * p)
 /*
  * UPDI 'unlock' -> 'enter progmode' with chip erase key
  */
-static int jtag3_unlock_erase_key(PROGRAMMER * pgm, AVRPART * p)
-{
+static int jtag3_unlock_erase_key(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char buf[8], *resp;
 
   buf[0] = 1; /* Enable */
@@ -969,8 +960,7 @@ static int jtag3_unlock_erase_key(PROGRAMMER * pgm, AVRPART * p)
 /*
  * There is no chip erase functionality in debugWire mode.
  */
-static int jtag3_chip_erase_dw(PROGRAMMER * pgm, AVRPART * p)
-{
+static int jtag3_chip_erase_dw(const PROGRAMMER *pgm, const AVRPART *p) {
 
   avrdude_message(MSG_INFO, "%s: Chip erase not supported in debugWire mode\n",
 	  progname);
@@ -978,13 +968,11 @@ static int jtag3_chip_erase_dw(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static int jtag3_program_enable_dummy(PROGRAMMER * pgm, AVRPART * p)
-{
+static int jtag3_program_enable_dummy(const PROGRAMMER *pgm, const AVRPART *p) {
   return 0;
 }
 
-static int jtag3_program_enable(PROGRAMMER * pgm)
-{
+static int jtag3_program_enable(const PROGRAMMER *pgm) {
   unsigned char buf[3], *resp;
   int status;
 
@@ -1005,8 +993,7 @@ static int jtag3_program_enable(PROGRAMMER * pgm)
   return status;
 }
 
-static int jtag3_program_disable(PROGRAMMER * pgm)
-{
+static int jtag3_program_disable(const PROGRAMMER *pgm) {
   unsigned char buf[3], *resp;
 
   if (!PDATA(pgm)->prog_enabled)
@@ -1026,18 +1013,15 @@ static int jtag3_program_disable(PROGRAMMER * pgm)
   return 0;
 }
 
-static int jtag3_set_sck_xmega_pdi(PROGRAMMER *pgm, unsigned char *clk)
-{
+static int jtag3_set_sck_xmega_pdi(const PROGRAMMER *pgm, unsigned char *clk) {
     return jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_PDI, clk, 2);
 }
 
-static int jtag3_set_sck_xmega_jtag(PROGRAMMER *pgm, unsigned char *clk)
-{
+static int jtag3_set_sck_xmega_jtag(const PROGRAMMER *pgm, unsigned char *clk) {
     return jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_JTAG, clk, 2);
 }
 
-static int jtag3_set_sck_mega_jtag(PROGRAMMER *pgm, unsigned char *clk)
-{
+static int jtag3_set_sck_mega_jtag(const PROGRAMMER *pgm, unsigned char *clk) {
     return jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_PROG, clk, 2);
 }
 
@@ -1045,8 +1029,7 @@ static int jtag3_set_sck_mega_jtag(PROGRAMMER *pgm, unsigned char *clk)
 /*
  * initialize the AVR device and prepare it to accept commands
  */
-static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
-{
+static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char conn = 0, parm[4];
   const char *ifname;
   unsigned char cmd[4], *resp;
@@ -1365,12 +1348,11 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
     md.allow_full_page_bitstream = (p->flags & AVRPART_ALLOWFULLPAGEBITSTREAM) != 0;
     md.idr_address = p->idr;
 
-    if (p->eecr == 0)
-      p->eecr = 0x3f;		/* matches most "modern" mega/tiny AVRs */
-    md.eearh_address = p->eecr - 0x20 + 3;
-    md.eearl_address = p->eecr - 0x20 + 2;
-    md.eecr_address = p->eecr - 0x20;
-    md.eedr_address = p->eecr - 0x20 + 1;
+    unsigned char eecr = p->eecr? p->eecr: 0x3f; // Use default 0x3f if not set
+    md.eearh_address = eecr - 0x20 + 3;
+    md.eearl_address = eecr - 0x20 + 2;
+    md.eecr_address = eecr - 0x20;
+    md.eedr_address = eecr - 0x20 + 1;
     md.spmcr_address = p->spmcr;
     //md.osccal_address = p->osccal;  // do we need it at all?
 
@@ -1459,8 +1441,7 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static void jtag3_disable(PROGRAMMER * pgm)
-{
+static void jtag3_disable(const PROGRAMMER *pgm) {
 
   free(PDATA(pgm)->flash_pagecache);
   PDATA(pgm)->flash_pagecache = NULL;
@@ -1475,13 +1456,11 @@ static void jtag3_disable(PROGRAMMER * pgm)
   (void)jtag3_program_disable(pgm);
 }
 
-static void jtag3_enable(PROGRAMMER * pgm)
-{
+static void jtag3_enable(PROGRAMMER *pgm, const AVRPART *p) {
   return;
 }
 
-static int jtag3_parseextparms(PROGRAMMER * pgm, LISTID extparms)
-{
+static int jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
   LNODEID ln;
   const char *extended_param;
   int rv = 0;
@@ -1524,8 +1503,7 @@ static int jtag3_parseextparms(PROGRAMMER * pgm, LISTID extparms)
   return rv;
 }
 
-int jtag3_open_common(PROGRAMMER * pgm, char * port)
-{
+int jtag3_open_common(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo;
   LNODEID usbpid;
   int rv = -1;
@@ -1620,8 +1598,7 @@ int jtag3_open_common(PROGRAMMER * pgm, char * port)
 
 
 
-static int jtag3_open(PROGRAMMER * pgm, char * port)
-{
+static int jtag3_open(PROGRAMMER *pgm, const char *port) {
   avrdude_message(MSG_NOTICE2, "%s: jtag3_open()\n", progname);
 
   if (jtag3_open_common(pgm, port) < 0)
@@ -1633,8 +1610,7 @@ static int jtag3_open(PROGRAMMER * pgm, char * port)
   return 0;
 }
 
-static int jtag3_open_dw(PROGRAMMER * pgm, char * port)
-{
+static int jtag3_open_dw(PROGRAMMER *pgm, const char *port) {
   avrdude_message(MSG_NOTICE2, "%s: jtag3_open_dw()\n", progname);
 
   if (jtag3_open_common(pgm, port) < 0)
@@ -1646,8 +1622,7 @@ static int jtag3_open_dw(PROGRAMMER * pgm, char * port)
   return 0;
 }
 
-static int jtag3_open_pdi(PROGRAMMER * pgm, char * port)
-{
+static int jtag3_open_pdi(PROGRAMMER *pgm, const char *port) {
   avrdude_message(MSG_NOTICE2, "%s: jtag3_open_pdi()\n", progname);
 
   if (jtag3_open_common(pgm, port) < 0)
@@ -1659,8 +1634,7 @@ static int jtag3_open_pdi(PROGRAMMER * pgm, char * port)
   return 0;
 }
 
-static int jtag3_open_updi(PROGRAMMER * pgm, char * port)
-{
+static int jtag3_open_updi(PROGRAMMER *pgm, const char *port) {
   avrdude_message(MSG_NOTICE2, "%s: jtag3_open_updi()\n", progname);
 
   LNODEID ln;
@@ -1708,7 +1682,7 @@ void jtag3_close(PROGRAMMER * pgm)
   pgm->fd.ifd = -1;
 }
 
-static int jtag3_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int jtag3_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                unsigned int addr)
 {
   unsigned char cmd[8], *resp;
@@ -1754,7 +1728,7 @@ static int jtag3_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return 0;
 }
 
-static int jtag3_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                 unsigned int page_size,
                                 unsigned int addr, unsigned int n_bytes)
 {
@@ -1864,7 +1838,7 @@ static int jtag3_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return n_bytes;
 }
 
-static int jtag3_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int jtag3_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                unsigned int page_size,
                                unsigned int addr, unsigned int n_bytes)
 {
@@ -1950,7 +1924,7 @@ static int jtag3_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return n_bytes;
 }
 
-static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 			      unsigned long addr, unsigned char * value)
 {
   unsigned char cmd[12];
@@ -2123,7 +2097,7 @@ static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
   return 0;
 }
 
-static int jtag3_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 			       unsigned long addr, unsigned char data)
 {
   unsigned char cmd[14];
@@ -2247,8 +2221,7 @@ static int jtag3_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
  * As the STK500 expresses it as a period length (and we actualy do
  * program a period length as well), we rather call it by that name.
  */
-static int jtag3_set_sck_period(PROGRAMMER * pgm, double v)
-{
+static int jtag3_set_sck_period(const PROGRAMMER *pgm, double v) {
   unsigned char parm[2];
   unsigned int clock = 1E-3 / v; /* kHz */
 
@@ -2268,7 +2241,7 @@ static int jtag3_set_sck_period(PROGRAMMER * pgm, double v)
 /*
  * Read (an) emulator parameter(s).
  */
-int jtag3_getparm(PROGRAMMER * pgm, unsigned char scope,
+int jtag3_getparm(const PROGRAMMER *pgm, unsigned char scope,
 		  unsigned char section, unsigned char parm,
 		  unsigned char *value, unsigned char length)
 {
@@ -2310,7 +2283,7 @@ int jtag3_getparm(PROGRAMMER * pgm, unsigned char scope,
 /*
  * Write an emulator parameter.
  */
-int jtag3_setparm(PROGRAMMER * pgm, unsigned char scope,
+int jtag3_setparm(const PROGRAMMER *pgm, unsigned char scope,
 		  unsigned char section, unsigned char parm,
 		  unsigned char *value, unsigned char length)
 {
@@ -2347,8 +2320,7 @@ int jtag3_setparm(PROGRAMMER * pgm, unsigned char scope,
   return status;
 }
 
-int jtag3_read_sib(PROGRAMMER * pgm, AVRPART * p, char * sib)
-{
+int jtag3_read_sib(const PROGRAMMER *pgm, const AVRPART *p, char *sib) {
   int status;
   unsigned char cmd[12];
   unsigned char *resp = NULL;
@@ -2370,8 +2342,7 @@ int jtag3_read_sib(PROGRAMMER * pgm, AVRPART * p, char * sib)
   return 0;
 }
 
-static int jtag3_set_vtarget(PROGRAMMER * pgm, double v)
-{
+static int jtag3_set_vtarget(const PROGRAMMER *pgm, double v) {
   unsigned uaref, utarg;
   unsigned char buf[2];
 
@@ -2397,8 +2368,7 @@ static int jtag3_set_vtarget(PROGRAMMER * pgm, double v)
   return 0;
 }
 
-static void jtag3_display(PROGRAMMER * pgm, const char * p)
-{
+static void jtag3_display(const PROGRAMMER *pgm, const char *p) {
   unsigned char parms[5];
   unsigned char cmd[4], *resp, c;
   int status;
@@ -2440,8 +2410,7 @@ static void jtag3_display(PROGRAMMER * pgm, const char * p)
 }
 
 
-static void jtag3_print_parms1(PROGRAMMER * pgm, const char * p)
-{
+static void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) {
   unsigned char buf[2];
 
   if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0)
@@ -2483,13 +2452,11 @@ static void jtag3_print_parms1(PROGRAMMER * pgm, const char * p)
   }
 }
 
-static void jtag3_print_parms(PROGRAMMER * pgm)
-{
+static void jtag3_print_parms(const PROGRAMMER *pgm) {
   jtag3_print_parms1(pgm, "");
 }
 
-static unsigned char jtag3_memtype(PROGRAMMER * pgm, AVRPART * p, unsigned long addr)
-{
+static unsigned char jtag3_memtype(const PROGRAMMER *pgm, const AVRPART *p, unsigned long addr) {
   if ( p->flags & AVRPART_HAS_PDI ) {
     if (addr >= PDATA(pgm)->boot_start)
       return MTYPE_BOOT_FLASH;
@@ -2500,8 +2467,7 @@ static unsigned char jtag3_memtype(PROGRAMMER * pgm, AVRPART * p, unsigned long
   }
 }
 
-static unsigned int jtag3_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr)
-{
+static unsigned int jtag3_memaddr(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr) {
   if ((p->flags & AVRPART_HAS_PDI) != 0) {
     if (addr >= PDATA(pgm)->boot_start)
       /*
@@ -2533,8 +2499,7 @@ static unsigned int jtag3_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, uns
 
 const char jtag3_desc[] = "Atmel JTAGICE3";
 
-void jtag3_initpgm(PROGRAMMER * pgm)
-{
+void jtag3_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "JTAGICE3");
 
   /*
@@ -2568,8 +2533,7 @@ void jtag3_initpgm(PROGRAMMER * pgm)
 
 const char jtag3_dw_desc[] = "Atmel JTAGICE3 in debugWire mode";
 
-void jtag3_dw_initpgm(PROGRAMMER * pgm)
-{
+void jtag3_dw_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "JTAGICE3_DW");
 
   /*
@@ -2600,8 +2564,7 @@ void jtag3_dw_initpgm(PROGRAMMER * pgm)
 
 const char jtag3_pdi_desc[] = "Atmel JTAGICE3 in PDI mode";
 
-void jtag3_pdi_initpgm(PROGRAMMER * pgm)
-{
+void jtag3_pdi_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "JTAGICE3_PDI");
 
   /*
@@ -2634,8 +2597,7 @@ void jtag3_pdi_initpgm(PROGRAMMER * pgm)
 
 const char jtag3_updi_desc[] = "Atmel JTAGICE3 in UPDI mode";
 
-void jtag3_updi_initpgm(PROGRAMMER * pgm)
-{
+void jtag3_updi_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "JTAGICE3_UPDI");
 
   /*
diff --git a/src/jtag3.h b/src/jtag3.h
index 4e49c586..c871c019 100644
--- a/src/jtag3.h
+++ b/src/jtag3.h
@@ -25,27 +25,27 @@
 extern "C" {
 #endif
 
-int  jtag3_open_common(PROGRAMMER * pgm, char * port);
-int  jtag3_send(PROGRAMMER * pgm, unsigned char * data, size_t len);
-int  jtag3_recv(PROGRAMMER * pgm, unsigned char **msg);
+int  jtag3_open_common(PROGRAMMER *pgm, const char *port);
+int  jtag3_send(const PROGRAMMER *pgm, unsigned char *data, size_t len);
+int  jtag3_recv(const PROGRAMMER *pgm, unsigned char **msg);
 void jtag3_close(PROGRAMMER * pgm);
-int  jtag3_getsync(PROGRAMMER * pgm, int mode);
-int  jtag3_getparm(PROGRAMMER * pgm, unsigned char scope,
+int  jtag3_getsync(const PROGRAMMER *pgm, int mode);
+int  jtag3_getparm(const PROGRAMMER *pgm, unsigned char scope,
 		   unsigned char section, unsigned char parm,
 		   unsigned char *value, unsigned char length);
-int jtag3_setparm(PROGRAMMER * pgm, unsigned char scope,
+int jtag3_setparm(const PROGRAMMER *pgm, unsigned char scope,
 		  unsigned char section, unsigned char parm,
 		  unsigned char *value, unsigned char length);
-int jtag3_command(PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
+int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
 		  unsigned char **resp, const char *descr);
 extern const char jtag3_desc[];
 extern const char jtag3_dw_desc[];
 extern const char jtag3_pdi_desc[];
 extern const char jtag3_updi_desc[];
-void jtag3_initpgm (PROGRAMMER * pgm);
-void jtag3_dw_initpgm (PROGRAMMER * pgm);
-void jtag3_pdi_initpgm (PROGRAMMER * pgm);
-void jtag3_updi_initpgm (PROGRAMMER * pgm);
+void jtag3_initpgm(PROGRAMMER *pgm);
+void jtag3_dw_initpgm(PROGRAMMER *pgm);
+void jtag3_pdi_initpgm(PROGRAMMER *pgm);
+void jtag3_updi_initpgm(PROGRAMMER *pgm);
 
 /*
  * These functions are referenced from stk500v2.c for JTAGICE3 in
diff --git a/src/jtagmkI.c b/src/jtagmkI.c
index 2e84eb5c..a9b2dda8 100644
--- a/src/jtagmkI.c
+++ b/src/jtagmkI.c
@@ -95,18 +95,18 @@ const static struct {
 /*  {  14400L, 0xf8 }, */ /* not supported by serial driver */
 };
 
-static int jtagmkI_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int jtagmkI_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 			      unsigned long addr, unsigned char * value);
-static int jtagmkI_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int jtagmkI_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 			       unsigned long addr, unsigned char data);
-static int jtagmkI_set_sck_period(PROGRAMMER * pgm, double v);
-static int jtagmkI_getparm(PROGRAMMER * pgm, unsigned char parm,
+static int jtagmkI_set_sck_period(const PROGRAMMER *pgm, double v);
+static int jtagmkI_getparm(const PROGRAMMER *pgm, unsigned char parm,
 			    unsigned char * value);
-static int jtagmkI_setparm(PROGRAMMER * pgm, unsigned char parm,
+static int jtagmkI_setparm(const PROGRAMMER *pgm, unsigned char parm,
 			    unsigned char value);
-static void jtagmkI_print_parms1(PROGRAMMER * pgm, const char * p);
+static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p);
 
-static int jtagmkI_resync(PROGRAMMER *pgm, int maxtries, int signon);
+static int jtagmkI_resync(const PROGRAMMER *pgm, int maxtries, int signon);
 
 static void jtagmkI_setup(PROGRAMMER * pgm)
 {
@@ -139,8 +139,7 @@ u16_to_b2(unsigned char *b, unsigned short l)
   b[1] = (l >> 8) & 0xff;
 }
 
-static void jtagmkI_prmsg(PROGRAMMER * pgm, unsigned char * data, size_t len)
-{
+static void jtagmkI_prmsg(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
   int i;
 
   if (verbose >= 4) {
@@ -193,8 +192,7 @@ static void jtagmkI_prmsg(PROGRAMMER * pgm, unsigned char * data, size_t len)
 }
 
 
-static int jtagmkI_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
-{
+static int jtagmkI_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
   unsigned char *buf;
 
   avrdude_message(MSG_DEBUG, "\n%s: jtagmkI_send(): sending %u bytes\n",
@@ -223,8 +221,7 @@ static int jtagmkI_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
   return 0;
 }
 
-static int jtagmkI_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
-{
+static int jtagmkI_recv(const PROGRAMMER *pgm, unsigned char *buf, size_t len) {
   if (serial_recv(&pgm->fd, buf, len) != 0) {
     avrdude_message(MSG_INFO, "\n%s: jtagmkI_recv(): failed to send command to serial port\n",
                     progname);
@@ -238,14 +235,12 @@ static int jtagmkI_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
 }
 
 
-static int jtagmkI_drain(PROGRAMMER * pgm, int display)
-{
+static int jtagmkI_drain(const PROGRAMMER *pgm, int display) {
   return serial_drain(&pgm->fd, display);
 }
 
 
-static int jtagmkI_resync(PROGRAMMER * pgm, int maxtries, int signon)
-{
+static int jtagmkI_resync(const PROGRAMMER *pgm, int maxtries, int signon) {
   int tries;
   unsigned char buf[4], resp[9];
   long otimeout = serial_recv_timeout;
@@ -316,8 +311,7 @@ static int jtagmkI_resync(PROGRAMMER * pgm, int maxtries, int signon)
   return 0;
 }
 
-static int jtagmkI_getsync(PROGRAMMER * pgm)
-{
+static int jtagmkI_getsync(const PROGRAMMER *pgm) {
   unsigned char buf[1], resp[9];
 
   if (jtagmkI_resync(pgm, 5, 1) < 0) {
@@ -345,8 +339,7 @@ static int jtagmkI_getsync(PROGRAMMER * pgm)
 /*
  * issue the 'chip erase' command to the AVR device
  */
-static int jtagmkI_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+static int jtagmkI_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char buf[1], resp[2];
 
   buf[0] = CMD_CHIP_ERASE;
@@ -372,8 +365,7 @@ static int jtagmkI_chip_erase(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static void jtagmkI_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
-{
+static void jtagmkI_set_devdescr(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char resp[2];
   LNODEID ln;
   AVRMEM * m;
@@ -419,8 +411,7 @@ static void jtagmkI_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
 /*
  * Reset the target.
  */
-static int jtagmkI_reset(PROGRAMMER * pgm)
-{
+static int jtagmkI_reset(const PROGRAMMER *pgm) {
   unsigned char buf[1], resp[2];
 
   buf[0] = CMD_RESET;
@@ -445,14 +436,12 @@ static int jtagmkI_reset(PROGRAMMER * pgm)
   return 0;
 }
 
-static int jtagmkI_program_enable_dummy(PROGRAMMER * pgm, AVRPART * p)
-{
+static int jtagmkI_program_enable_dummy(const PROGRAMMER *pgm, const AVRPART *p) {
 
   return 0;
 }
 
-static int jtagmkI_program_enable(PROGRAMMER * pgm)
-{
+static int jtagmkI_program_enable(const PROGRAMMER *pgm) {
   unsigned char buf[1], resp[2];
 
   if (PDATA(pgm)->prog_enabled)
@@ -483,8 +472,7 @@ static int jtagmkI_program_enable(PROGRAMMER * pgm)
   return 0;
 }
 
-static int jtagmkI_program_disable(PROGRAMMER * pgm)
-{
+static int jtagmkI_program_disable(const PROGRAMMER *pgm) {
   unsigned char buf[1], resp[2];
 
   if (!PDATA(pgm)->prog_enabled)
@@ -530,8 +518,7 @@ static unsigned char jtagmkI_get_baud(long baud)
 /*
  * initialize the AVR device and prepare it to accept commands
  */
-static int jtagmkI_initialize(PROGRAMMER * pgm, AVRPART * p)
-{
+static int jtagmkI_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
   AVRMEM hfuse;
   unsigned char cmd[1], resp[5];
   unsigned char b;
@@ -621,8 +608,7 @@ static int jtagmkI_initialize(PROGRAMMER * pgm, AVRPART * p)
 }
 
 
-static void jtagmkI_disable(PROGRAMMER * pgm)
-{
+static void jtagmkI_disable(const PROGRAMMER *pgm) {
 
   free(PDATA(pgm)->flash_pagecache);
   PDATA(pgm)->flash_pagecache = NULL;
@@ -632,13 +618,12 @@ static void jtagmkI_disable(PROGRAMMER * pgm)
   (void)jtagmkI_program_disable(pgm);
 }
 
-static void jtagmkI_enable(PROGRAMMER * pgm)
-{
+static void jtagmkI_enable(PROGRAMMER *pgm, const AVRPART *p) {
   return;
 }
 
 
-static int jtagmkI_open(PROGRAMMER * pgm, char * port)
+static int jtagmkI_open(PROGRAMMER *pgm, const char *port)
 {
   size_t i;
 
@@ -712,7 +697,7 @@ static void jtagmkI_close(PROGRAMMER * pgm)
 }
 
 
-static int jtagmkI_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int jtagmkI_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                unsigned int page_size,
                                unsigned int addr, unsigned int n_bytes)
 {
@@ -846,7 +831,7 @@ static int jtagmkI_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return n_bytes;
 }
 
-static int jtagmkI_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int jtagmkI_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
 			      unsigned int page_size,
                               unsigned int addr, unsigned int n_bytes)
 {
@@ -937,7 +922,7 @@ static int jtagmkI_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return n_bytes;
 }
 
-static int jtagmkI_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int jtagmkI_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 			      unsigned long addr, unsigned char * value)
 {
   unsigned char cmd[6];
@@ -1053,7 +1038,7 @@ static int jtagmkI_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
   return 0;
 }
 
-static int jtagmkI_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int jtagmkI_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 			       unsigned long addr, unsigned char data)
 {
   unsigned char cmd[6], datacmd[1 * 2 + 1];
@@ -1175,8 +1160,7 @@ static int jtagmkI_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
  * As the STK500 expresses it as a period length (and we actualy do
  * program a period length as well), we rather call it by that name.
  */
-static int jtagmkI_set_sck_period(PROGRAMMER * pgm, double v)
-{
+static int jtagmkI_set_sck_period(const PROGRAMMER *pgm, double v) {
   unsigned char dur;
 
   v = 1 / v;			/* convert to frequency */
@@ -1198,7 +1182,7 @@ static int jtagmkI_set_sck_period(PROGRAMMER * pgm, double v)
  * multi-byte parameters get two different parameter names for
  * their components.
  */
-static int jtagmkI_getparm(PROGRAMMER * pgm, unsigned char parm,
+static int jtagmkI_getparm(const PROGRAMMER *pgm, const unsigned char parm,
 			    unsigned char * value)
 {
   unsigned char buf[2], resp[3];
@@ -1242,7 +1226,7 @@ static int jtagmkI_getparm(PROGRAMMER * pgm, unsigned char parm,
 /*
  * Write an emulator parameter.
  */
-static int jtagmkI_setparm(PROGRAMMER * pgm, unsigned char parm,
+static int jtagmkI_setparm(const PROGRAMMER *pgm, unsigned char parm,
 			    unsigned char value)
 {
   unsigned char buf[3], resp[2];
@@ -1274,9 +1258,7 @@ static int jtagmkI_setparm(PROGRAMMER * pgm, unsigned char parm,
 }
 
 
-static void jtagmkI_display(PROGRAMMER * pgm, const char * p)
-{
-
+static void jtagmkI_display(const PROGRAMMER *pgm, const char *p) {
   unsigned char hw, fw;
 
   if (jtagmkI_getparm(pgm, PARM_HW_VERSION, &hw) < 0 ||
@@ -1292,8 +1274,7 @@ static void jtagmkI_display(PROGRAMMER * pgm, const char * p)
 }
 
 
-static void jtagmkI_print_parms1(PROGRAMMER * pgm, const char * p)
-{
+static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p) {
   unsigned char vtarget, jtag_clock;
   const char *clkstr;
   double clk;
@@ -1337,15 +1318,13 @@ static void jtagmkI_print_parms1(PROGRAMMER * pgm, const char * p)
 }
 
 
-static void jtagmkI_print_parms(PROGRAMMER * pgm)
-{
+static void jtagmkI_print_parms(const PROGRAMMER *pgm) {
   jtagmkI_print_parms1(pgm, "");
 }
 
 const char jtagmkI_desc[] = "Atmel JTAG ICE mkI";
 
-void jtagmkI_initpgm(PROGRAMMER * pgm)
-{
+void jtagmkI_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "JTAGMKI");
 
   /*
diff --git a/src/jtagmkI.h b/src/jtagmkI.h
index fbc0d161..2a250c04 100644
--- a/src/jtagmkI.h
+++ b/src/jtagmkI.h
@@ -26,7 +26,7 @@ extern "C" {
 #endif
 
 extern const char jtagmkI_desc[];
-void jtagmkI_initpgm (PROGRAMMER * pgm);
+void jtagmkI_initpgm(PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/jtagmkII.c b/src/jtagmkII.c
index 98ee87b1..f4323799 100644
--- a/src/jtagmkII.c
+++ b/src/jtagmkII.c
@@ -83,6 +83,11 @@ struct pdata
 
   /* Major firmware version (needed for Xmega programming) */
   unsigned int fwver;
+
+#define FLAGS32_INIT_SMC      1 // Part will undergo chip erase
+#define FLAGS32_WRITE         2 // At least one write operation specified
+  // Couple of flag bits for AVR32 programming
+  int flags32;
 };
 
 #define PDATA(pgm) ((struct pdata *)(pgm->cookie))
@@ -127,64 +132,57 @@ static struct {
 #define PGM_FL_IS_PDI           (0x0002)
 #define PGM_FL_IS_JTAG          (0x0004)
 
-static int jtagmkII_open(PROGRAMMER * pgm, char * port);
+static int jtagmkII_open(PROGRAMMER *pgm, const char *port);
 
-static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p);
-static int jtagmkII_chip_erase(PROGRAMMER * pgm, AVRPART * p);
-static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p);
+static int jtagmkII_chip_erase(const PROGRAMMER *pgm, const AVRPART *p);
+static int jtagmkII_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                                 unsigned long addr, unsigned char * value);
-static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int jtagmkII_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                                 unsigned long addr, unsigned char data);
-static int jtagmkII_reset(PROGRAMMER * pgm, unsigned char flags);
-static int jtagmkII_set_sck_period(PROGRAMMER * pgm, double v);
-static int jtagmkII_setparm(PROGRAMMER * pgm, unsigned char parm,
+static int jtagmkII_reset(const PROGRAMMER *pgm, unsigned char flags);
+static int jtagmkII_set_sck_period(const PROGRAMMER *pgm, double v);
+static int jtagmkII_setparm(const PROGRAMMER *pgm, unsigned char parm,
                             unsigned char * value);
-static void jtagmkII_print_parms1(PROGRAMMER * pgm, const char * p);
-static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p);
+static int jtagmkII_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                 unsigned int page_size,
                                 unsigned int addr, unsigned int n_bytes);
-static unsigned char jtagmkII_memtype(PROGRAMMER * pgm, AVRPART * p, unsigned long addr);
-static unsigned int jtagmkII_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr);
+static unsigned char jtagmkII_memtype(const PROGRAMMER *pgm, const AVRPART *p, unsigned long addr);
+static unsigned int jtagmkII_memaddr(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr);
 
 // AVR32
 #define ERROR_SAB 0xFFFFFFFF
 
-static int jtagmkII_open32(PROGRAMMER * pgm, char * port);
+static int jtagmkII_open32(PROGRAMMER *pgm, const char *port);
 static void jtagmkII_close32(PROGRAMMER * pgm);
-static int jtagmkII_reset32(PROGRAMMER * pgm, unsigned short flags);
-static int jtagmkII_initialize32(PROGRAMMER * pgm, AVRPART * p);
-static int jtagmkII_chip_erase32(PROGRAMMER * pgm, AVRPART * p);
-static unsigned long jtagmkII_read_SABaddr(PROGRAMMER * pgm, unsigned long addr,
+static int jtagmkII_reset32(const PROGRAMMER *pgm, unsigned short flags);
+static int jtagmkII_initialize32(const PROGRAMMER *pgm, const AVRPART *p);
+static int jtagmkII_chip_erase32(const PROGRAMMER *pgm, const AVRPART *p);
+static unsigned long jtagmkII_read_SABaddr(const PROGRAMMER *pgm, unsigned long addr,
                       unsigned int prefix); // ERROR_SAB illegal
-static int jtagmkII_write_SABaddr(PROGRAMMER * pgm, unsigned long addr,
+static int jtagmkII_write_SABaddr(const PROGRAMMER *pgm, unsigned long addr,
                                   unsigned int prefix, unsigned long val);
-static int jtagmkII_avr32_reset(PROGRAMMER * pgm, unsigned char val,
+static int jtagmkII_avr32_reset(const PROGRAMMER *pgm, unsigned char val,
                                   unsigned char ret1, unsigned char ret2);
-static int jtagmkII_smc_init32(PROGRAMMER * pgm);
-static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int jtagmkII_smc_init32(const PROGRAMMER *pgm);
+static int jtagmkII_paged_write32(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                   unsigned int page_size,
                                   unsigned int addr, unsigned int n_bytes);
-static int jtagmkII_flash_lock32(PROGRAMMER * pgm, unsigned char lock,
+static int jtagmkII_flash_lock32(const PROGRAMMER *pgm, unsigned char lock,
                                   unsigned int page);
-static int jtagmkII_flash_erase32(PROGRAMMER * pgm, unsigned int page);
-static int jtagmkII_flash_write_page32(PROGRAMMER * pgm, unsigned int page);
-static int jtagmkII_flash_clear_pagebuffer32(PROGRAMMER * pgm);
-static int jtagmkII_paged_load32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int jtagmkII_flash_erase32(const PROGRAMMER *pgm, unsigned int page);
+static int jtagmkII_flash_write_page32(const PROGRAMMER *pgm, unsigned int page);
+static int jtagmkII_flash_clear_pagebuffer32(const PROGRAMMER *pgm);
+static int jtagmkII_paged_load32(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                  unsigned int page_size,
                                  unsigned int addr, unsigned int n_bytes);
 
-void jtagmkII_setup(PROGRAMMER * pgm)
-{
-  if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
-    avrdude_message(MSG_INFO, "%s: jtagmkII_setup(): Out of memory allocating private data\n",
-                    progname);
-    exit(1);
-  }
-  memset(pgm->cookie, 0, sizeof(struct pdata));
+void jtagmkII_setup(PROGRAMMER *pgm) {
+  pgm->cookie = cfg_malloc("jtagmkII_setup()", sizeof(struct pdata));
 }
 
-void jtagmkII_teardown(PROGRAMMER * pgm)
-{
+void jtagmkII_teardown(PROGRAMMER *pgm) {
   free(pgm->cookie);
 }
 
@@ -279,8 +277,7 @@ static void jtagmkII_print_memory(unsigned char *b, size_t s)
     putc('\n', stderr);
 }
 
-static void jtagmkII_prmsg(PROGRAMMER * pgm, unsigned char * data, size_t len)
-{
+static void jtagmkII_prmsg(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
   int i;
 
   if (verbose >= 4) {
@@ -420,8 +417,7 @@ static void jtagmkII_prmsg(PROGRAMMER * pgm, unsigned char * data, size_t len)
 }
 
 
-int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
-{
+int jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
   unsigned char *buf;
 
   avrdude_message(MSG_DEBUG, "\n%s: jtagmkII_send(): sending %lu bytes\n",
@@ -455,8 +451,7 @@ int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
 }
 
 
-static int jtagmkII_drain(PROGRAMMER * pgm, int display)
-{
+static int jtagmkII_drain(const PROGRAMMER *pgm, int display) {
   return serial_drain(&pgm->fd, display);
 }
 
@@ -469,7 +464,7 @@ static int jtagmkII_drain(PROGRAMMER * pgm, int display)
  *
  * Caller must eventually free the buffer.
  */
-static int jtagmkII_recv_frame(PROGRAMMER * pgm, unsigned char **msg,
+static int jtagmkII_recv_frame(const PROGRAMMER *pgm, unsigned char **msg,
 			       unsigned short * seqno) {
   enum states { sSTART,
 		/* NB: do NOT change the sequence of the following: */
@@ -615,7 +610,7 @@ static int jtagmkII_recv_frame(PROGRAMMER * pgm, unsigned char **msg,
   return msglen;
 }
 
-int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg) {
+int jtagmkII_recv(const PROGRAMMER *pgm, unsigned char **msg) {
   unsigned short r_seqno;
   int rv;
 
@@ -671,7 +666,7 @@ int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg) {
 }
 
 
-int jtagmkII_getsync(PROGRAMMER * pgm, int mode) {
+int jtagmkII_getsync(const PROGRAMMER *pgm, int mode) {
   int tries;
 #define MAXTRIES 10
   unsigned char buf[3], *resp, c = 0xff;
@@ -883,8 +878,7 @@ retry:
 /*
  * issue the 'chip erase' command to the AVR device
  */
-static int jtagmkII_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+static int jtagmkII_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
   int status, len;
   unsigned char buf[6], *resp, c;
 
@@ -934,8 +928,7 @@ static int jtagmkII_chip_erase(PROGRAMMER * pgm, AVRPART * p)
 /*
  * There is no chip erase functionality in debugWire mode.
  */
-static int jtagmkII_chip_erase_dw(PROGRAMMER * pgm, AVRPART * p)
-{
+static int jtagmkII_chip_erase_dw(const PROGRAMMER *pgm, const AVRPART *p) {
 
   avrdude_message(MSG_INFO, "%s: Chip erase not supported in debugWire mode\n",
 	  progname);
@@ -943,8 +936,7 @@ static int jtagmkII_chip_erase_dw(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static void jtagmkII_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
-{
+static void jtagmkII_set_devdescr(const PROGRAMMER *pgm, const AVRPART *p) {
   int status;
   unsigned char *resp, c;
   LNODEID ln;
@@ -959,7 +951,7 @@ static void jtagmkII_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
   sendbuf.dd.ucSPMCRAddress = p->spmcr;
   sendbuf.dd.ucRAMPZAddress = p->rampz;
   sendbuf.dd.ucIDRAddress = p->idr;
-  u16_to_b2(sendbuf.dd.EECRAddress, p->eecr);
+  u16_to_b2(sendbuf.dd.EECRAddress, p->eecr? p->eecr: 0x3f); // Unset eecr means 0x3f
   sendbuf.dd.ucAllowFullPageBitstream =
     (p->flags & AVRPART_ALLOWFULLPAGEBITSTREAM) != 0;
   sendbuf.dd.EnablePageProgramming =
@@ -1014,8 +1006,7 @@ static void jtagmkII_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
   }
 }
 
-static void jtagmkII_set_xmega_params(PROGRAMMER * pgm, AVRPART * p)
-{
+static void jtagmkII_set_xmega_params(const PROGRAMMER *pgm, const AVRPART *p) {
   int status;
   unsigned char *resp, c;
   LNODEID ln;
@@ -1095,8 +1086,7 @@ static void jtagmkII_set_xmega_params(PROGRAMMER * pgm, AVRPART * p)
 /*
  * Reset the target.
  */
-static int jtagmkII_reset(PROGRAMMER * pgm, unsigned char flags)
-{
+static int jtagmkII_reset(const PROGRAMMER *pgm, unsigned char flags) {
   int status;
   unsigned char buf[2], *resp, c;
 
@@ -1142,13 +1132,11 @@ static int jtagmkII_reset(PROGRAMMER * pgm, unsigned char flags)
   return 0;
 }
 
-static int jtagmkII_program_enable_INFO(PROGRAMMER * pgm, AVRPART * p)
-{
+static int jtagmkII_program_enable_INFO(const PROGRAMMER *pgm, const AVRPART *p) {
   return 0;
 }
 
-static int jtagmkII_program_enable(PROGRAMMER * pgm)
-{
+static int jtagmkII_program_enable(const PROGRAMMER *pgm) {
   int status;
   unsigned char buf[1], *resp, c;
   int use_ext_reset;
@@ -1203,8 +1191,7 @@ static int jtagmkII_program_enable(PROGRAMMER * pgm)
   return 0;
 }
 
-static int jtagmkII_program_disable(PROGRAMMER * pgm)
-{
+static int jtagmkII_program_disable(const PROGRAMMER *pgm) {
   int status;
   unsigned char buf[1], *resp, c;
 
@@ -1296,8 +1283,7 @@ static unsigned char jtagmkII_get_baud(long baud)
 /*
  * initialize the AVR device and prepare it to accept commands
  */
-static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
-{
+static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
   AVRMEM hfuse;
   unsigned char b;
   int ok;
@@ -1449,8 +1435,7 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static void jtagmkII_disable(PROGRAMMER * pgm)
-{
+static void jtagmkII_disable(const PROGRAMMER *pgm) {
 
   free(PDATA(pgm)->flash_pagecache);
   PDATA(pgm)->flash_pagecache = NULL;
@@ -1465,13 +1450,11 @@ static void jtagmkII_disable(PROGRAMMER * pgm)
   (void)jtagmkII_program_disable(pgm);
 }
 
-static void jtagmkII_enable(PROGRAMMER * pgm)
-{
+static void jtagmkII_enable(PROGRAMMER * pgm, const AVRPART *p) {
   return;
 }
 
-static int jtagmkII_parseextparms(PROGRAMMER * pgm, LISTID extparms)
-{
+static int jtagmkII_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
   LNODEID ln;
   const char *extended_param;
   int rv = 0;
@@ -1509,8 +1492,7 @@ static int jtagmkII_parseextparms(PROGRAMMER * pgm, LISTID extparms)
 }
 
 
-static int jtagmkII_open(PROGRAMMER * pgm, char * port)
-{
+static int jtagmkII_open(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo;
 
   avrdude_message(MSG_NOTICE2, "%s: jtagmkII_open()\n", progname);
@@ -1562,8 +1544,7 @@ static int jtagmkII_open(PROGRAMMER * pgm, char * port)
   return 0;
 }
 
-static int jtagmkII_open_dw(PROGRAMMER * pgm, char * port)
-{
+static int jtagmkII_open_dw(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo;
 
   avrdude_message(MSG_NOTICE2, "%s: jtagmkII_open_dw()\n", progname);
@@ -1615,8 +1596,7 @@ static int jtagmkII_open_dw(PROGRAMMER * pgm, char * port)
   return 0;
 }
 
-static int jtagmkII_open_pdi(PROGRAMMER * pgm, char * port)
-{
+static int jtagmkII_open_pdi(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo;
 
   avrdude_message(MSG_NOTICE2, "%s: jtagmkII_open_pdi()\n", progname);
@@ -1669,8 +1649,7 @@ static int jtagmkII_open_pdi(PROGRAMMER * pgm, char * port)
 }
 
 
-static int jtagmkII_dragon_open(PROGRAMMER * pgm, char * port)
-{
+static int jtagmkII_dragon_open(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo;
 
   avrdude_message(MSG_NOTICE2, "%s: jtagmkII_dragon_open()\n", progname);
@@ -1723,8 +1702,7 @@ static int jtagmkII_dragon_open(PROGRAMMER * pgm, char * port)
 }
 
 
-static int jtagmkII_dragon_open_dw(PROGRAMMER * pgm, char * port)
-{
+static int jtagmkII_dragon_open_dw(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo;
 
   avrdude_message(MSG_NOTICE2, "%s: jtagmkII_dragon_open_dw()\n", progname);
@@ -1777,8 +1755,7 @@ static int jtagmkII_dragon_open_dw(PROGRAMMER * pgm, char * port)
 }
 
 
-static int jtagmkII_dragon_open_pdi(PROGRAMMER * pgm, char * port)
-{
+static int jtagmkII_dragon_open_pdi(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo;
 
   avrdude_message(MSG_NOTICE2, "%s: jtagmkII_dragon_open_pdi()\n", progname);
@@ -1899,7 +1876,7 @@ void jtagmkII_close(PROGRAMMER * pgm)
   pgm->fd.ifd = -1;
 }
 
-static int jtagmkII_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int jtagmkII_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                unsigned int addr)
 {
   unsigned char cmd[6];
@@ -1995,7 +1972,7 @@ static int jtagmkII_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return 0;
 }
 
-static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int jtagmkII_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                 unsigned int page_size,
                                 unsigned int addr, unsigned int n_bytes)
 {
@@ -2131,7 +2108,7 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return n_bytes;
 }
 
-static int jtagmkII_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int jtagmkII_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                unsigned int page_size,
                                unsigned int addr, unsigned int n_bytes)
 {
@@ -2233,7 +2210,8 @@ static int jtagmkII_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return n_bytes;
 }
 
-static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+
+static int jtagmkII_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 			      unsigned long addr, unsigned char * value)
 {
   unsigned char cmd[10];
@@ -2412,7 +2390,7 @@ fail:
   return -1;
 }
 
-static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int jtagmkII_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 			       unsigned long addr, unsigned char data)
 {
   unsigned char cmd[12];
@@ -2545,8 +2523,7 @@ fail:
  * As the STK500 expresses it as a period length (and we actualy do
  * program a period length as well), we rather call it by that name.
  */
-static int jtagmkII_set_sck_period(PROGRAMMER * pgm, double v)
-{
+static int jtagmkII_set_sck_period(const PROGRAMMER *pgm, double v) {
   unsigned char dur;
 
   v = 1 / v;			/* convert to frequency */
@@ -2568,7 +2545,7 @@ static int jtagmkII_set_sck_period(PROGRAMMER * pgm, double v)
  * bytes by now, we always copy out 4 bytes to *value, so the caller
  * must have allocated sufficient space.
  */
-int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
+int jtagmkII_getparm(const PROGRAMMER *pgm, unsigned char parm,
 		     unsigned char * value)
 {
   int status;
@@ -2615,7 +2592,7 @@ int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
 /*
  * Write an emulator parameter.
  */
-static int jtagmkII_setparm(PROGRAMMER * pgm, unsigned char parm,
+static int jtagmkII_setparm(const PROGRAMMER *pgm, unsigned char parm,
 			    unsigned char * value)
 {
   int status;
@@ -2681,8 +2658,7 @@ static int jtagmkII_setparm(PROGRAMMER * pgm, unsigned char parm,
 }
 
 
-static void jtagmkII_display(PROGRAMMER * pgm, const char * p)
-{
+static void jtagmkII_display(const PROGRAMMER *pgm, const char *p) {
   unsigned char hw[4], fw[4];
 
   if (jtagmkII_getparm(pgm, PAR_HW_VERSION, hw) < 0 ||
@@ -2702,8 +2678,7 @@ static void jtagmkII_display(PROGRAMMER * pgm, const char * p)
 }
 
 
-static void jtagmkII_print_parms1(PROGRAMMER * pgm, const char * p)
-{
+static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p) {
   unsigned char vtarget[4], jtag_clock[4];
   char clkbuf[20];
   double clk;
@@ -2739,13 +2714,11 @@ static void jtagmkII_print_parms1(PROGRAMMER * pgm, const char * p)
   return;
 }
 
-static void jtagmkII_print_parms(PROGRAMMER * pgm)
-{
+static void jtagmkII_print_parms(const PROGRAMMER *pgm) {
   jtagmkII_print_parms1(pgm, "");
 }
 
-static unsigned char jtagmkII_memtype(PROGRAMMER * pgm, AVRPART * p, unsigned long addr)
-{
+static unsigned char jtagmkII_memtype(const PROGRAMMER *pgm, const AVRPART *p, unsigned long addr) {
   if ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) {
     if (addr >= PDATA(pgm)->boot_start)
       return MTYPE_BOOT_FLASH;
@@ -2756,8 +2729,7 @@ static unsigned char jtagmkII_memtype(PROGRAMMER * pgm, AVRPART * p, unsigned lo
   }
 }
 
-static unsigned int jtagmkII_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr)
-{
+static unsigned int jtagmkII_memaddr(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr) {
   /*
    * Xmega devices handled by V7+ firmware don't want to be told their
    * m->offset within the write memory command.
@@ -2786,7 +2758,7 @@ static unsigned int jtagmkII_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 #pragma mark -
 #endif
 
-static int jtagmkII_avr32_reset(PROGRAMMER * pgm, unsigned char val,
+static int jtagmkII_avr32_reset(const PROGRAMMER *pgm, unsigned char val,
                                 unsigned char ret1, unsigned char ret2)
 {
   int status;
@@ -2827,8 +2799,7 @@ static int jtagmkII_avr32_reset(PROGRAMMER * pgm, unsigned char val,
 }
 
 // At init: AVR32_RESET_READ_IR | AVR32_RESET_READ_READ_CHIPINFO
-static int jtagmkII_reset32(PROGRAMMER * pgm, unsigned short flags)
-{
+static int jtagmkII_reset32(const PROGRAMMER *pgm, unsigned short flags) {
   int status, j, lineno;
   unsigned char *resp, buf[3];
   unsigned long val=0;
@@ -3017,8 +2988,7 @@ static int jtagmkII_reset32(PROGRAMMER * pgm, unsigned short flags)
     return -1;
 }
 
-static int jtagmkII_smc_init32(PROGRAMMER * pgm)
-{
+static int jtagmkII_smc_init32(const PROGRAMMER *pgm) {
   int status, lineno;
   unsigned long val;
 
@@ -3120,8 +3090,7 @@ static int jtagmkII_smc_init32(PROGRAMMER * pgm)
 /*
  * initialize the AVR device and prepare it to accept commands
  */
-static int jtagmkII_initialize32(PROGRAMMER * pgm, AVRPART * p)
-{
+static int jtagmkII_initialize32(const PROGRAMMER *pgm, const AVRPART *p) {
   int status, j;
   unsigned char buf[6], *resp;
 
@@ -3197,8 +3166,7 @@ static int jtagmkII_initialize32(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static int jtagmkII_chip_erase32(PROGRAMMER * pgm, AVRPART * p)
-{
+static int jtagmkII_chip_erase32(const PROGRAMMER *pgm, const AVRPART *p) {
   int status=0, loops;
   unsigned char *resp, buf[3], x, ret[4], *retP;
   unsigned long val=0;
@@ -3258,7 +3226,7 @@ static int jtagmkII_chip_erase32(PROGRAMMER * pgm, AVRPART * p)
     return -1;
 }
 
-static unsigned long jtagmkII_read_SABaddr(PROGRAMMER * pgm, unsigned long addr,
+static unsigned long jtagmkII_read_SABaddr(const PROGRAMMER *pgm, unsigned long addr,
                                            unsigned int prefix)
 {
   unsigned char buf[6], *resp;
@@ -3320,7 +3288,7 @@ static unsigned long jtagmkII_read_SABaddr(PROGRAMMER * pgm, unsigned long addr,
   return val;
 }
 
-static int jtagmkII_write_SABaddr(PROGRAMMER * pgm, unsigned long addr,
+static int jtagmkII_write_SABaddr(const PROGRAMMER *pgm, unsigned long addr,
                                   unsigned int prefix, unsigned long val)
 {
   unsigned char buf[10], *resp;
@@ -3355,8 +3323,7 @@ static int jtagmkII_write_SABaddr(PROGRAMMER * pgm, unsigned long addr,
   return 0;
 }
 
-static int jtagmkII_open32(PROGRAMMER * pgm, char * port)
-{
+static int jtagmkII_open32(PROGRAMMER *pgm, const char *port) {
   int status;
   unsigned char buf[6], *resp;
   union pinfo pinfo;
@@ -3492,7 +3459,7 @@ static void jtagmkII_close32(PROGRAMMER * pgm)
     goto ret;
 }
 
-static int jtagmkII_paged_load32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int jtagmkII_paged_load32(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                  unsigned int page_size,
                                  unsigned int addr, unsigned int n_bytes)
 {
@@ -3509,23 +3476,16 @@ static int jtagmkII_paged_load32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
   serial_recv_timeout = 256;
 
-  if(!(p->flags & AVRPART_WRITE)) {
+  if(!(PDATA(pgm)->flags32 & FLAGS32_WRITE)) {
     status = jtagmkII_reset32(pgm, AVR32_RESET_READ);
     if(status != 0) {lineno = __LINE__; goto eRR;}
   }
 
   // Init SMC and set clocks
-  if(!(p->flags & AVRPART_INIT_SMC)) {
+  if(!(PDATA(pgm)->flags32 & FLAGS32_INIT_SMC)) {
     status = jtagmkII_smc_init32(pgm);
     if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
-    p->flags |= AVRPART_INIT_SMC;
-  }
-
-  // Init SMC and set clocks
-  if(!(p->flags & AVRPART_INIT_SMC)) {
-    status = jtagmkII_smc_init32(pgm);
-    if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
-    p->flags |= AVRPART_INIT_SMC;
+    PDATA(pgm)->flags32 |= FLAGS32_INIT_SMC;
   }
 
   //avrdude_message(MSG_INFO, "\n pageSize=%d bytes=%d pages=%d m->offset=0x%x pgm->page_size %d\n",
@@ -3580,7 +3540,7 @@ static int jtagmkII_paged_load32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     return -1;
 }
 
-static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int jtagmkII_paged_write32(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                   unsigned int page_size,
                                   unsigned int addr, unsigned int n_bytes)
 {
@@ -3598,7 +3558,7 @@ static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
   status = jtagmkII_reset32(pgm, AVR32_RESET_WRITE);
   if(status != 0) {lineno = __LINE__; goto eRR;}
-  p->flags |= AVRPART_WRITE;
+  PDATA(pgm)->flags32 |= FLAGS32_WRITE;
 
   pages = (n_bytes - addr - 1)/page_size + 1;
   sPageNum = addr/page_size;
@@ -3612,10 +3572,10 @@ static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   }
 
   // Init SMC and set clocks
-  if(!(p->flags & AVRPART_INIT_SMC)) {
+  if(!(p->flags & FLAGS32_INIT_SMC)) {
     status = jtagmkII_smc_init32(pgm);
     if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
-    p->flags |= AVRPART_INIT_SMC;
+    PDATA(pgm)->flags32 |= FLAGS32_INIT_SMC;
   }
 
   // First unlock the pages
@@ -3694,8 +3654,7 @@ static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 }
 
 
-static int jtagmkII_flash_lock32(PROGRAMMER * pgm, unsigned char lock, unsigned int page)
-{
+static int jtagmkII_flash_lock32(const PROGRAMMER *pgm, unsigned char lock, unsigned int page) {
   int status, lineno, i;
   unsigned long val, cmd=0;
 
@@ -3721,8 +3680,7 @@ static int jtagmkII_flash_lock32(PROGRAMMER * pgm, unsigned char lock, unsigned
     return -1;
 }
 
-static int jtagmkII_flash_erase32(PROGRAMMER * pgm, unsigned int page)
-{
+static int jtagmkII_flash_erase32(const PROGRAMMER *pgm, unsigned int page) {
   int status, lineno, i;
   unsigned long val=0, cmd=0, err=0;
 
@@ -3761,8 +3719,7 @@ static int jtagmkII_flash_erase32(PROGRAMMER * pgm, unsigned int page)
     return -1;
 }
 
-static int jtagmkII_flash_write_page32(PROGRAMMER * pgm, unsigned int page)
-{
+static int jtagmkII_flash_write_page32(const PROGRAMMER *pgm, unsigned int page) {
   int status, lineno, i;
   unsigned long val=0, cmd, err;
 
@@ -3791,8 +3748,7 @@ static int jtagmkII_flash_write_page32(PROGRAMMER * pgm, unsigned int page)
     return -1;
 }
 
-static int jtagmkII_flash_clear_pagebuffer32(PROGRAMMER * pgm)
-{
+static int jtagmkII_flash_clear_pagebuffer32(const PROGRAMMER *pgm) {
   int status, lineno, i;
   unsigned long val=0, cmd, err;
 
@@ -3826,8 +3782,7 @@ static int jtagmkII_flash_clear_pagebuffer32(PROGRAMMER * pgm)
 
 const char jtagmkII_desc[] = "Atmel JTAG ICE mkII";
 
-void jtagmkII_initpgm(PROGRAMMER * pgm)
-{
+void jtagmkII_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "JTAGMKII");
 
   /*
@@ -3861,8 +3816,7 @@ void jtagmkII_initpgm(PROGRAMMER * pgm)
 
 const char jtagmkII_dw_desc[] = "Atmel JTAG ICE mkII in debugWire mode";
 
-void jtagmkII_dw_initpgm(PROGRAMMER * pgm)
-{
+void jtagmkII_dw_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "JTAGMKII_DW");
 
   /*
@@ -3893,8 +3847,7 @@ void jtagmkII_dw_initpgm(PROGRAMMER * pgm)
 
 const char jtagmkII_pdi_desc[] = "Atmel JTAG ICE mkII in PDI mode";
 
-void jtagmkII_pdi_initpgm(PROGRAMMER * pgm)
-{
+void jtagmkII_pdi_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "JTAGMKII_PDI");
 
   /*
@@ -3926,8 +3879,7 @@ void jtagmkII_pdi_initpgm(PROGRAMMER * pgm)
 
 const char jtagmkII_updi_desc[] = "Atmel JTAG ICE mkII in UPDI mode";
 
-void jtagmkII_updi_initpgm(PROGRAMMER * pgm)
-{
+void jtagmkII_updi_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "JTAGMKII_UPDI");
 
   /*
@@ -3959,8 +3911,7 @@ void jtagmkII_updi_initpgm(PROGRAMMER * pgm)
 
 const char jtagmkII_dragon_desc[] = "Atmel AVR Dragon in JTAG mode";
 
-void jtagmkII_dragon_initpgm(PROGRAMMER * pgm)
-{
+void jtagmkII_dragon_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "DRAGON_JTAG");
 
   /*
@@ -3994,8 +3945,7 @@ void jtagmkII_dragon_initpgm(PROGRAMMER * pgm)
 
 const char jtagmkII_dragon_dw_desc[] = "Atmel AVR Dragon in debugWire mode";
 
-void jtagmkII_dragon_dw_initpgm(PROGRAMMER * pgm)
-{
+void jtagmkII_dragon_dw_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "DRAGON_DW");
 
   /*
@@ -4026,8 +3976,7 @@ void jtagmkII_dragon_dw_initpgm(PROGRAMMER * pgm)
 
 const char jtagmkII_avr32_desc[] = "Atmel JTAG ICE mkII in AVR32 mode";
 
-void jtagmkII_avr32_initpgm(PROGRAMMER * pgm)
-{
+void jtagmkII_avr32_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "JTAGMKII_AVR32");
 
   /*
@@ -4060,8 +4009,7 @@ void jtagmkII_avr32_initpgm(PROGRAMMER * pgm)
 
 const char jtagmkII_dragon_pdi_desc[] = "Atmel AVR Dragon in PDI mode";
 
-void jtagmkII_dragon_pdi_initpgm(PROGRAMMER * pgm)
-{
+void jtagmkII_dragon_pdi_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "DRAGON_PDI");
 
   /*
diff --git a/src/jtagmkII.h b/src/jtagmkII.h
index 34004d6d..f420edf9 100644
--- a/src/jtagmkII.h
+++ b/src/jtagmkII.h
@@ -25,11 +25,11 @@
 extern "C" {
 #endif
 
-int  jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len);
-int  jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg);
+int  jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, size_t len);
+int  jtagmkII_recv(const PROGRAMMER *pgm, unsigned char **msg);
 void jtagmkII_close(PROGRAMMER * pgm);
-int  jtagmkII_getsync(PROGRAMMER * pgm, int mode);
-int  jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
+int  jtagmkII_getsync(const PROGRAMMER *pgm, int mode);
+int  jtagmkII_getparm(const PROGRAMMER *pgm, unsigned char parm,
 		      unsigned char * value);
 
 extern const char jtagmkII_desc[];
@@ -40,14 +40,14 @@ extern const char jtagmkII_updi_desc[];
 extern const char jtagmkII_dragon_desc[];
 extern const char jtagmkII_dragon_dw_desc[];
 extern const char jtagmkII_dragon_pdi_desc[];
-void jtagmkII_initpgm (PROGRAMMER * pgm);
-void jtagmkII_avr32_initpgm (PROGRAMMER * pgm);
-void jtagmkII_dw_initpgm (PROGRAMMER * pgm);
-void jtagmkII_pdi_initpgm (PROGRAMMER * pgm);
-void jtagmkII_updi_initpgm (PROGRAMMER * pgm);
-void jtagmkII_dragon_initpgm (PROGRAMMER * pgm);
-void jtagmkII_dragon_dw_initpgm (PROGRAMMER * pgm);
-void jtagmkII_dragon_pdi_initpgm (PROGRAMMER * pgm);
+void jtagmkII_initpgm(PROGRAMMER *pgm);
+void jtagmkII_avr32_initpgm(PROGRAMMER *pgm);
+void jtagmkII_dw_initpgm(PROGRAMMER *pgm);
+void jtagmkII_pdi_initpgm(PROGRAMMER *pgm);
+void jtagmkII_updi_initpgm(PROGRAMMER *pgm);
+void jtagmkII_dragon_initpgm(PROGRAMMER *pgm);
+void jtagmkII_dragon_dw_initpgm(PROGRAMMER *pgm);
+void jtagmkII_dragon_pdi_initpgm(PROGRAMMER *pgm);
 
 /*
  * These functions are referenced from stk500v2.c for JTAG ICE mkII
diff --git a/src/libavrdude.h b/src/libavrdude.h
index eef7a67c..627bb89b 100644
--- a/src/libavrdude.h
+++ b/src/libavrdude.h
@@ -193,8 +193,6 @@ typedef struct opcode {
 #define AVRPART_HAS_DW         0x0040  /* part has a debugWire i/f */
 #define AVRPART_HAS_PDI        0x0080  /* part has PDI i/f rather than ISP (ATxmega) */
 #define AVRPART_AVR32          0x0100  /* part is in AVR32 family */
-#define AVRPART_INIT_SMC       0x0200  /* part will undergo chip erase */
-#define AVRPART_WRITE          0x0400  /* at least one write operation specified */
 #define AVRPART_HAS_TPI        0x0800  /* part has TPI i/f rather than ISP (ATtiny4/5/9/10) */
 #define AVRPART_IS_AT90S1200   0x1000  /* part is an AT90S1200 (needs special treatment) */
 #define AVRPART_HAS_UPDI       0x2000  /* part has UPDI i/f (AVR8X) */
@@ -614,18 +612,17 @@ union pinfo
 };
 
 
-struct serial_device
-{
+struct serial_device {
   // open should return -1 on error, other values on success
-  int (*open)(char * port, union pinfo pinfo, union filedescriptor *fd); 
-  int (*setparams)(union filedescriptor *fd, long baud, unsigned long cflags);
+  int (*open)(const char *port, union pinfo pinfo, union filedescriptor *fd);
+  int (*setparams)(const union filedescriptor *fd, long baud, unsigned long cflags);
   void (*close)(union filedescriptor *fd);
 
-  int (*send)(union filedescriptor *fd, const unsigned char * buf, size_t buflen);
-  int (*recv)(union filedescriptor *fd, unsigned char * buf, size_t buflen);
-  int (*drain)(union filedescriptor *fd, int display);
+  int (*send)(const union filedescriptor *fd, const unsigned char * buf, size_t buflen);
+  int (*recv)(const union filedescriptor *fd, unsigned char * buf, size_t buflen);
+  int (*drain)(const union filedescriptor *fd, int display);
 
-  int (*set_dtr_rts)(union filedescriptor *fd, int is_on);
+  int (*set_dtr_rts)(const union filedescriptor *fd, int is_on);
 
   int flags;
 #define SERDEV_FL_NONE         0x0000 /* no flags */
@@ -684,8 +681,8 @@ typedef enum {
 typedef struct programmer_t {
   LISTID id;
   const char *desc;
-  void (*initpgm)(struct programmer_t *pgm);
-  LISTID        comments;       // Used by developer options -c*/[ASsr...]
+  void (*initpgm)(struct programmer_t *pgm); // Sets up the AVRDUDE programmer
+  LISTID comments;              // Used by developer options -c*/[ASsr...]
   const char *parent_id;        // Used by developer options
   struct pindef_t pin[N_PINS];
   conntype_t conntype;
@@ -712,60 +709,60 @@ typedef struct programmer_t {
   int page_size;                // Page size if the programmer supports paged write/load
   double bitclock;              // JTAG ICE clock period in microseconds
 
-  int  (*rdy_led)        (struct programmer_t * pgm, int value);
-  int  (*err_led)        (struct programmer_t * pgm, int value);
-  int  (*pgm_led)        (struct programmer_t * pgm, int value);
-  int  (*vfy_led)        (struct programmer_t * pgm, int value);
-  int  (*initialize)     (struct programmer_t * pgm, AVRPART * p);
-  void (*display)        (struct programmer_t * pgm, const char * p);
-  void (*enable)         (struct programmer_t * pgm);
-  void (*disable)        (struct programmer_t * pgm);
-  void (*powerup)        (struct programmer_t * pgm);
-  void (*powerdown)      (struct programmer_t * pgm);
-  int  (*program_enable) (struct programmer_t * pgm, AVRPART * p);
-  int  (*chip_erase)     (struct programmer_t * pgm, AVRPART * p);
-  int  (*unlock)         (struct programmer_t * pgm, AVRPART * p);
-  int  (*cmd)            (struct programmer_t * pgm, const unsigned char *cmd,
+  int  (*rdy_led)        (const struct programmer_t *pgm, int value);
+  int  (*err_led)        (const struct programmer_t *pgm, int value);
+  int  (*pgm_led)        (const struct programmer_t *pgm, int value);
+  int  (*vfy_led)        (const struct programmer_t *pgm, int value);
+  int  (*initialize)     (const struct programmer_t *pgm, const AVRPART *p); // Sets up the physical programmer
+  void (*display)        (const struct programmer_t *pgm, const char *p);
+  void (*enable)         (struct programmer_t *pgm, const AVRPART *p);
+  void (*disable)        (const struct programmer_t *pgm);
+  void (*powerup)        (const struct programmer_t *pgm);
+  void (*powerdown)      (const struct programmer_t *pgm);
+  int  (*program_enable) (const struct programmer_t *pgm, const AVRPART *p);
+  int  (*chip_erase)     (const struct programmer_t *pgm, const AVRPART *p);
+  int  (*unlock)         (const struct programmer_t *pgm, const AVRPART *p);
+  int  (*cmd)            (const struct programmer_t *pgm, const unsigned char *cmd,
                           unsigned char *res);
-  int  (*cmd_tpi)        (struct programmer_t * pgm, const unsigned char *cmd,
+  int  (*cmd_tpi)        (const struct programmer_t *pgm, const unsigned char *cmd,
                           int cmd_len, unsigned char res[], int res_len);
-  int  (*spi)            (struct programmer_t * pgm, const unsigned char *cmd,
+  int  (*spi)            (const struct programmer_t *pgm, const unsigned char *cmd,
                           unsigned char *res, int count);
-  int  (*open)           (struct programmer_t * pgm, char * port);
-  void (*close)          (struct programmer_t * pgm);
-  int  (*paged_write)    (struct programmer_t * pgm, AVRPART * p, AVRMEM * m, 
+  int  (*open)           (struct programmer_t *pgm, const char *port);
+  void (*close)          (struct programmer_t *pgm);
+  int  (*paged_write)    (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m,
                           unsigned int page_size, unsigned int baseaddr,
                           unsigned int n_bytes);
-  int  (*paged_load)     (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
+  int  (*paged_load)     (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m,
                           unsigned int page_size, unsigned int baseaddr,
                           unsigned int n_bytes);
-  int  (*page_erase)     (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
+  int  (*page_erase)     (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m,
                           unsigned int baseaddr);
-  void (*write_setup)    (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
-  int  (*write_byte)     (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
+  void (*write_setup)    (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m);
+  int  (*write_byte)     (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m,
                           unsigned long addr, unsigned char value);
-  int  (*read_byte)      (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
-                          unsigned long addr, unsigned char * value);
-  int  (*read_sig_bytes) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
-  int  (*read_sib)       (struct programmer_t * pgm, AVRPART * p, char *sib);
-  void (*print_parms)    (struct programmer_t * pgm);
-  int  (*set_vtarget)    (struct programmer_t * pgm, double v);
-  int  (*set_varef)      (struct programmer_t * pgm, unsigned int chan, double v);
-  int  (*set_fosc)       (struct programmer_t * pgm, double v);
-  int  (*set_sck_period) (struct programmer_t * pgm, double v);
-  int  (*setpin)         (struct programmer_t * pgm, int pinfunc, int value);
-  int  (*getpin)         (struct programmer_t * pgm, int pinfunc);
-  int  (*highpulsepin)   (struct programmer_t * pgm, int pinfunc);
-  int  (*parseexitspecs) (struct programmer_t * pgm, char *s);
-  int  (*perform_osccal) (struct programmer_t * pgm);
-  int  (*parseextparams) (struct programmer_t * pgm, LISTID xparams);
-  void (*setup)          (struct programmer_t * pgm);
-  void (*teardown)       (struct programmer_t * pgm);
+  int  (*read_byte)      (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m,
+                          unsigned long addr, unsigned char *value);
+  int  (*read_sig_bytes) (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m);
+  int  (*read_sib)       (const struct programmer_t *pgm, const AVRPART *p, char *sib);
+  void (*print_parms)    (const struct programmer_t *pgm);
+  int  (*set_vtarget)    (const struct programmer_t *pgm, double v);
+  int  (*set_varef)      (const struct programmer_t *pgm, unsigned int chan, double v);
+  int  (*set_fosc)       (const struct programmer_t *pgm, double v);
+  int  (*set_sck_period) (const struct programmer_t *pgm, double v);
+  int  (*setpin)         (const struct programmer_t *pgm, int pinfunc, int value);
+  int  (*getpin)         (const struct programmer_t *pgm, int pinfunc);
+  int  (*highpulsepin)   (const struct programmer_t *pgm, int pinfunc);
+  int  (*parseexitspecs) (struct programmer_t *pgm, const char *s);
+  int  (*perform_osccal) (const struct programmer_t *pgm);
+  int  (*parseextparams) (const struct programmer_t *pgm, const LISTID xparams);
+  void (*setup)          (struct programmer_t *pgm);
+  void (*teardown)       (struct programmer_t *pgm);
 
   const char *config_file;      // Config file where defined
   int  lineno;                  // Config file line number
   void *cookie;                 // For private use by the programmer
-  char flag;                    // For private use of the programmer
+  char flag;                    // For use by pgm->initpgm()
 } PROGRAMMER;
 
 #ifdef __cplusplus
@@ -812,50 +809,50 @@ extern FP_UpdateProgress update_progress;
 extern "C" {
 #endif
 
-int avr_tpi_poll_nvmbsy(PROGRAMMER *pgm);
-int avr_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p);
-int avr_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p, unsigned char guard_time);
-int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+int avr_tpi_poll_nvmbsy(const PROGRAMMER *pgm);
+int avr_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p);
+int avr_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p, unsigned char guard_time);
+int avr_read_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 			  unsigned long addr, unsigned char * value);
 
-int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, AVRPART * v);
+int avr_read(const PROGRAMMER * pgm, const AVRPART *p, const char *memtype, AVRPART *v);
 
-int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+int avr_write_page(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                    unsigned long addr);
 
-int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+int avr_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                    unsigned long addr, unsigned char data);
 
-int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 			   unsigned long addr, unsigned char data);
 
-int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
+int avr_write(const PROGRAMMER *pgm, const AVRPART *p, const char *memtype, int size,
               int auto_erase);
 
-int avr_signature(PROGRAMMER * pgm, AVRPART * p);
+int avr_signature(const PROGRAMMER *pgm, const AVRPART *p);
 
-int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size);
+int avr_verify(const AVRPART * p, const AVRPART * v, const char * memtype, int size);
 
-int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles);
+int avr_get_cycle_count(const PROGRAMMER *pgm, const AVRPART *p, int *cycles);
 
-int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);
+int avr_put_cycle_count(const PROGRAMMER *pgm, const AVRPART *p, int cycles);
 
 void avr_add_mem_order(const char *str);
 
-int avr_mem_is_flash_type(AVRMEM *mem);
+int avr_mem_is_flash_type(const AVRMEM *mem);
 
-int avr_mem_is_eeprom_type(AVRMEM *mem);
+int avr_mem_is_eeprom_type(const AVRMEM *mem);
 
 int avr_mem_is_known(const char *str);
 
 int avr_mem_might_be_known(const char *str);
 
 #define disable_trailing_ff_removal() avr_mem_hiaddr(NULL)
-int avr_mem_hiaddr(AVRMEM * mem);
+int avr_mem_hiaddr(const AVRMEM * mem);
 
-int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p);
+int avr_chip_erase(const PROGRAMMER *pgm, const AVRPART *p);
 
-int avr_unlock(PROGRAMMER * pgm, AVRPART * p);
+int avr_unlock(const PROGRAMMER *pgm, const AVRPART *p);
 
 void report_progress (int completed, int total, char *hdr);
 
@@ -983,7 +980,7 @@ int update_dryrun(struct avrpart *p, UPDATE *upd);
 
 typedef struct programmer_type_t {
   const char * const id;
-  void (*initpgm)(struct programmer_t * pgm);
+  void (*initpgm)(struct programmer_t *pgm);
   const char * const desc;
 } PROGRAMMER_TYPE;
 
diff --git a/src/linuxgpio.c b/src/linuxgpio.c
index 86fefd76..639597c3 100644
--- a/src/linuxgpio.c
+++ b/src/linuxgpio.c
@@ -144,8 +144,7 @@ static int linuxgpio_dir_in(unsigned int gpio)
 static int linuxgpio_fds[N_GPIO] ;
 
 
-static int linuxgpio_setpin(PROGRAMMER * pgm, int pinfunc, int value)
-{
+static int linuxgpio_setpin(const PROGRAMMER *pgm, int pinfunc, int value) {
   int r;
   int pin = pgm->pinno[pinfunc]; // TODO
 
@@ -171,8 +170,7 @@ static int linuxgpio_setpin(PROGRAMMER * pgm, int pinfunc, int value)
   return 0;
 }
 
-static int linuxgpio_getpin(PROGRAMMER * pgm, int pinfunc)
-{
+static int linuxgpio_getpin(const PROGRAMMER *pgm, int pinfunc) {
   unsigned char invert=0;
   char c;
   int pin = pgm->pinno[pinfunc]; // TODO
@@ -198,11 +196,9 @@ static int linuxgpio_getpin(PROGRAMMER * pgm, int pinfunc)
     return 1-invert;
   else
     return -1;
-
 }
 
-static int linuxgpio_highpulsepin(PROGRAMMER * pgm, int pinfunc)
-{
+static int linuxgpio_highpulsepin(const PROGRAMMER *pgm, int pinfunc) {
   int pin = pgm->pinno[pinfunc]; // TODO
   
   if ( linuxgpio_fds[pin & PIN_MASK] < 0 )
@@ -216,34 +212,28 @@ static int linuxgpio_highpulsepin(PROGRAMMER * pgm, int pinfunc)
 
 
 
-static void linuxgpio_display(PROGRAMMER *pgm, const char *p)
-{
+static void linuxgpio_display(const PROGRAMMER *pgm, const char *p) {
     avrdude_message(MSG_INFO, "%sPin assignment  : /sys/class/gpio/gpio{n}\n",p);
     pgm_display_generic_mask(pgm, p, SHOW_AVR_PINS);
 }
 
-static void linuxgpio_enable(PROGRAMMER *pgm)
-{
+static void linuxgpio_enable(PROGRAMMER *pgm, const AVRPART *p) {
   /* nothing */
 }
 
-static void linuxgpio_disable(PROGRAMMER *pgm)
-{
+static void linuxgpio_disable(const PROGRAMMER *pgm) {
   /* nothing */
 }
 
-static void linuxgpio_powerup(PROGRAMMER *pgm)
-{
+static void linuxgpio_powerup(const PROGRAMMER *pgm) {
   /* nothing */
 }
 
-static void linuxgpio_powerdown(PROGRAMMER *pgm)
-{
+static void linuxgpio_powerdown(const PROGRAMMER *pgm) {
   /* nothing */
 }
 
-static int linuxgpio_open(PROGRAMMER *pgm, char *port)
-{
+static int linuxgpio_open(PROGRAMMER *pgm, const char *port) {
   int r, i, pin;
 
   if (bitbang_check_prerequisites(pgm) < 0)
@@ -311,8 +301,7 @@ static void linuxgpio_close(PROGRAMMER *pgm)
   }
 }
 
-void linuxgpio_initpgm(PROGRAMMER *pgm)
-{
+void linuxgpio_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "linuxgpio");
 
   pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
@@ -344,8 +333,7 @@ const char linuxgpio_desc[] = "GPIO bitbanging using the Linux sysfs interface";
 
 #else  /* !HAVE_LINUXGPIO */
 
-void linuxgpio_initpgm(PROGRAMMER * pgm)
-{
+void linuxgpio_initpgm(PROGRAMMER *pgm) {
   avrdude_message(MSG_INFO, "%s: Linux sysfs GPIO support not available in this configuration\n",
                   progname);
 }
diff --git a/src/linuxgpio.h b/src/linuxgpio.h
index dc477982..5c07d7c4 100644
--- a/src/linuxgpio.h
+++ b/src/linuxgpio.h
@@ -27,7 +27,7 @@ extern "C" {
 #endif
 
 extern const char linuxgpio_desc[];
-void linuxgpio_initpgm        (PROGRAMMER * pgm);
+void linuxgpio_initpgm(PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/linuxspi.c b/src/linuxspi.c
index df497057..df57c7e6 100644
--- a/src/linuxspi.c
+++ b/src/linuxspi.c
@@ -68,8 +68,7 @@ static int fd_spidev, fd_gpiochip, fd_linehandle;
  * @brief Sends/receives a message in full duplex mode
  * @return -1 on failure, otherwise number of bytes sent/received
  */
-static int linuxspi_spi_duplex(PROGRAMMER *pgm, const unsigned char *tx, unsigned char *rx, int len)
-{
+static int linuxspi_spi_duplex(const PROGRAMMER *pgm, const unsigned char *tx, unsigned char *rx, int len) {
     struct spi_ioc_transfer tr;
     int ret;
 
@@ -89,16 +88,13 @@ static int linuxspi_spi_duplex(PROGRAMMER *pgm, const unsigned char *tx, unsigne
     return (ret == -1) ? -1 : 0;
 }
 
-static void linuxspi_setup(PROGRAMMER *pgm)
-{
+static void linuxspi_setup(PROGRAMMER *pgm) {
 }
 
-static void linuxspi_teardown(PROGRAMMER* pgm)
-{
+static void linuxspi_teardown(PROGRAMMER* pgm) {
 }
 
-static int linuxspi_reset_mcu(PROGRAMMER *pgm, bool active)
-{
+static int linuxspi_reset_mcu(const PROGRAMMER *pgm, bool active) {
     struct gpiohandle_data data;
     int ret;
 
@@ -128,13 +124,13 @@ static int linuxspi_reset_mcu(PROGRAMMER *pgm, bool active)
     return 0;
 }
 
-static int linuxspi_open(PROGRAMMER *pgm, char *port)
-{
+static int linuxspi_open(PROGRAMMER *pgm, const char *pt) {
     const char *port_error =
       "%s: error: Unknown port specification. "
       "Please use the format /dev/spidev:/dev/gpiochip[:resetno]\n";
     char port_default[] = "/dev/spidev0.0:/dev/gpiochip0";
     char *spidev, *gpiochip, *reset_pin;
+    char *port = cfg_strdup("linuxspi_open()", pt);
     struct gpiohandle_request req;
     int ret;
 
@@ -243,8 +239,7 @@ close_spidev:
     return ret;
 }
 
-static void linuxspi_close(PROGRAMMER *pgm)
-{
+static void linuxspi_close(PROGRAMMER *pgm) {
     switch (pgm->exit_reset) {
     case EXIT_RESET_ENABLED:
         linuxspi_reset_mcu(pgm, true);
@@ -263,20 +258,16 @@ static void linuxspi_close(PROGRAMMER *pgm)
     close(fd_gpiochip);
 }
 
-static void linuxspi_disable(PROGRAMMER* pgm)
-{
+static void linuxspi_disable(const PROGRAMMER* pgm) {
 }
 
-static void linuxspi_enable(PROGRAMMER* pgm)
-{
+static void linuxspi_enable(PROGRAMMER *pgm, const AVRPART *p) {
 }
 
-static void linuxspi_display(PROGRAMMER* pgm, const char* p)
-{
+static void linuxspi_display(const PROGRAMMER* pgm, const char* p) {
 }
 
-static int linuxspi_initialize(PROGRAMMER *pgm, AVRPART *p)
-{
+static int linuxspi_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
     int tries, ret;
 
     if (p->flags & AVRPART_HAS_TPI) {
@@ -300,13 +291,12 @@ static int linuxspi_initialize(PROGRAMMER *pgm, AVRPART *p)
     return ret;
 }
 
-static int linuxspi_cmd(PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res)
+static int linuxspi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res)
 {
     return linuxspi_spi_duplex(pgm, cmd, res, 4);
 }
 
-static int linuxspi_program_enable(PROGRAMMER *pgm, AVRPART *p)
-{
+static int linuxspi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
     unsigned char cmd[4], res[4];
 
     if (!p->op[AVR_OP_PGM_ENABLE]) {
@@ -349,8 +339,7 @@ static int linuxspi_program_enable(PROGRAMMER *pgm, AVRPART *p)
     return 0;
 }
 
-static int linuxspi_chip_erase(PROGRAMMER *pgm, AVRPART *p)
-{
+static int linuxspi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
     unsigned char cmd[4], res[4];
 
     if (!p->op[AVR_OP_CHIP_ERASE]) {
@@ -367,12 +356,12 @@ static int linuxspi_chip_erase(PROGRAMMER *pgm, AVRPART *p)
     return 0;
 }
 
-static int linuxspi_parseexitspecs(PROGRAMMER *pgm, char *s)
-{
-    char *cp;
+static int linuxspi_parseexitspecs(PROGRAMMER *pgm, const char *sp) {
+    char *cp, *s, *str = cfg_strdup("linuxspi_parseextitspecs()", sp);
 
+    s = str;
     while ((cp = strtok(s, ","))) {
-        s = 0;
+        s = NULL;
         if (!strcmp(cp, "reset")) {
             pgm->exit_reset = EXIT_RESET_ENABLED;
             continue;
@@ -381,14 +370,15 @@ static int linuxspi_parseexitspecs(PROGRAMMER *pgm, char *s)
             pgm->exit_reset = EXIT_RESET_DISABLED;
             continue;
         }
+        free(str);
         return -1;
     }
 
+    free(str);
     return 0;
 }
 
-void linuxspi_initpgm(PROGRAMMER *pgm)
-{
+void linuxspi_initpgm(PROGRAMMER *pgm) {
     strcpy(pgm->type, LINUXSPI);
 
     pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
@@ -416,10 +406,8 @@ const char linuxspi_desc[] = "SPI using Linux spidev driver";
 
 #else /* !HAVE_LINUXSPI */
 
-void linuxspi_initpgm(PROGRAMMER * pgm)
-{
-    avrdude_message(MSG_INFO, "%s: Linux SPI driver not available in this configuration\n",
-                    progname);
+void linuxspi_initpgm(PROGRAMMER *pgm) {
+  avrdude_message(MSG_INFO, "%s: Linux SPI driver not available in this configuration\n", progname);
 }
 
 const char linuxspi_desc[] = "SPI using Linux spidev driver (not available)";
diff --git a/src/linuxspi.h b/src/linuxspi.h
index 06c6dd20..21c65d46 100644
--- a/src/linuxspi.h
+++ b/src/linuxspi.h
@@ -25,7 +25,7 @@ extern "C" {
 #endif
 
 extern const char linuxspi_desc[];
-void linuxspi_initpgm        (PROGRAMMER * pgm);
+void linuxspi_initpgm(PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/main.c b/src/main.c
index 54f6e633..51dbc879 100644
--- a/src/main.c
+++ b/src/main.c
@@ -279,7 +279,7 @@ int main(int argc, char * argv [])
   int     calibrate;   /* 1=calibrate RC oscillator, 0=don't */
   char  * port;        /* device port (/dev/xxx) */
   int     terminal;    /* 1=enter terminal mode, 0=don't */
-  char  * exitspecs;   /* exit specs string from command line */
+  const char *exitspecs; /* exit specs string from command line */
   char  * programmer;  /* programmer id */
   char  * partdesc;    /* part id */
   char    sys_config[PATH_MAX]; /* system wide config file */
@@ -869,12 +869,13 @@ int main(int argc, char * argv [])
 
       case CONNTYPE_SPI:
 #ifdef HAVE_LINUXSPI
-        port = *default_spi? default_spi: "unknown";
+        port = cfg_strdup("main()", *default_spi? default_spi: "unknown");
 #endif
         break;
     }
   }
 
+
   if (partdesc == NULL) {
     avrdude_message(MSG_INFO, "%s: No AVR part has been specified, use \"-p Part\"\n\n",
                     progname);
@@ -884,7 +885,6 @@ int main(int argc, char * argv [])
     exit(1);
   }
 
-
   p = locate_part(part_list, partdesc);
   if (p == NULL) {
     avrdude_message(MSG_INFO, "%s: AVR Part \"%s\" not found.\n\n",
@@ -895,7 +895,6 @@ int main(int argc, char * argv [])
     exit(1);
   }
 
-
   if (exitspecs != NULL) {
     if (pgm->parseexitspecs == NULL) {
       avrdude_message(MSG_INFO, "%s: WARNING: -E option not supported by this programmer type\n",
@@ -908,10 +907,9 @@ int main(int argc, char * argv [])
     }
   }
 
-  if (avr_initmem(p) != 0)
-  {
+  if (avr_initmem(p) != 0) {
     avrdude_message(MSG_INFO, "\n%s: failed to initialize memories\n",
-            progname);
+      progname);
     exit(1);
   }
 
@@ -1024,7 +1022,7 @@ int main(int argc, char * argv [])
   /*
    * enable the programmer
    */
-  pgm->enable(pgm);
+  pgm->enable(pgm, p);
 
   /*
    * turn off all the status leds
diff --git a/src/micronucleus.c b/src/micronucleus.c
index c3dd007d..029edab9 100644
--- a/src/micronucleus.c
+++ b/src/micronucleus.c
@@ -567,8 +567,7 @@ static void micronucleus_teardown(PROGRAMMER* pgm)
     free(pgm->cookie);
 }
 
-static int micronucleus_initialize(PROGRAMMER* pgm, AVRPART* p)
-{
+static int micronucleus_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
     avrdude_message(MSG_DEBUG, "%s: micronucleus_initialize()\n", progname);
 
     pdata_t* pdata = PDATA(pgm);
@@ -582,18 +581,15 @@ static int micronucleus_initialize(PROGRAMMER* pgm, AVRPART* p)
     return 0;
 }
 
-static void micronucleus_display(PROGRAMMER* pgm, const char* prefix)
-{
+static void micronucleus_display(const PROGRAMMER *pgm, const char *prefix) {
     avrdude_message(MSG_DEBUG, "%s: micronucleus_display()\n", progname);
 }
 
-static void micronucleus_powerup(PROGRAMMER* pgm)
-{
+static void micronucleus_powerup(const PROGRAMMER *pgm) {
     avrdude_message(MSG_DEBUG, "%s: micronucleus_powerup()\n", progname);
 }
 
-static void micronucleus_powerdown(PROGRAMMER* pgm)
-{
+static void micronucleus_powerdown(const PROGRAMMER *pgm) {
     avrdude_message(MSG_DEBUG, "%s: micronucleus_powerdown()\n", progname);
 
     pdata_t* pdata = PDATA(pgm);
@@ -618,24 +614,20 @@ static void micronucleus_powerdown(PROGRAMMER* pgm)
     }
 }
 
-static void micronucleus_enable(PROGRAMMER* pgm)
-{
+static void micronucleus_enable(PROGRAMMER *pgm, const AVRPART *p) {
     avrdude_message(MSG_DEBUG, "%s: micronucleus_enable()\n", progname);
 }
 
-static void micronucleus_disable(PROGRAMMER* pgm)
-{
+static void micronucleus_disable(const PROGRAMMER *pgm) {
     avrdude_message(MSG_DEBUG, "%s: micronucleus_disable()\n", progname);
 }
 
-static int micronucleus_program_enable(PROGRAMMER* pgm, AVRPART* p)
-{
+static int micronucleus_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
     avrdude_message(MSG_DEBUG, "%s: micronucleus_program_enable()\n", progname);
     return 0;
 }
 
-static int micronucleus_read_sig_bytes(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem)
-{
+static int micronucleus_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem) {
     avrdude_message(MSG_DEBUG, "%s: micronucleus_read_sig_bytes()\n", progname);
 
     if (mem->size < 3)
@@ -651,20 +643,18 @@ static int micronucleus_read_sig_bytes(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem)
     return 0;
 }
 
-static int micronucleus_chip_erase(PROGRAMMER* pgm, AVRPART* p)
-{
+static int micronucleus_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
     avrdude_message(MSG_DEBUG, "%s: micronucleus_chip_erase()\n", progname);
 
     pdata_t* pdata = PDATA(pgm);
     return micronucleus_erase_device(pdata);
 }
 
-static int micronucleus_open(PROGRAMMER* pgm, char* port)
-{
+static int micronucleus_open(PROGRAMMER* pgm, const char *port) {
     avrdude_message(MSG_DEBUG, "%s: micronucleus_open(\"%s\")\n", progname, port);
 
     pdata_t* pdata = PDATA(pgm);
-    char* bus_name = NULL;
+    const char *bus_name = NULL;
     char* dev_name = NULL;
 
     // if no -P was given or '-P usb' was given
@@ -829,7 +819,7 @@ static void micronucleus_close(PROGRAMMER* pgm)
     }
 }
 
-static int micronucleus_read_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
+static int micronucleus_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
     unsigned long addr, unsigned char* value)
 {
     avrdude_message(MSG_DEBUG, "%s: micronucleus_read_byte(desc=%s, addr=0x%0X)\n",
@@ -850,7 +840,7 @@ static int micronucleus_read_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
     }
 }
 
-static int micronucleus_write_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
+static int micronucleus_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
     unsigned long addr, unsigned char value)
 {
     avrdude_message(MSG_DEBUG, "%s: micronucleus_write_byte(desc=%s, addr=0x%0X)\n",
@@ -858,7 +848,7 @@ static int micronucleus_write_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
     return -1;
 }
 
-static int micronucleus_paged_load(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
+static int micronucleus_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
     unsigned int page_size,
     unsigned int addr, unsigned int n_bytes)
 {
@@ -867,7 +857,7 @@ static int micronucleus_paged_load(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
     return -1;
 }
 
-static int micronucleus_paged_write(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
+static int micronucleus_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
     unsigned int page_size,
     unsigned int addr, unsigned int n_bytes)
 {
@@ -926,8 +916,7 @@ static int micronucleus_paged_write(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
     }
 }
 
-static int micronucleus_parseextparams(PROGRAMMER* pgm, LISTID xparams)
-{
+static int micronucleus_parseextparams(const PROGRAMMER *pgm, const LISTID xparams) {
     avrdude_message(MSG_DEBUG, "%s: micronucleus_parseextparams()\n", progname);
 
     pdata_t* pdata = PDATA(pgm);
@@ -955,8 +944,7 @@ static int micronucleus_parseextparams(PROGRAMMER* pgm, LISTID xparams)
     return 0;
 }
 
-void micronucleus_initpgm(PROGRAMMER* pgm)
-{
+void micronucleus_initpgm(PROGRAMMER *pgm) {
     strcpy(pgm->type, "Micronucleus V2.0");
 
     pgm->setup = micronucleus_setup;
@@ -983,14 +971,12 @@ void micronucleus_initpgm(PROGRAMMER* pgm)
 #else /* !HAVE_LIBUSB */
 
  // Give a proper error if we were not compiled with libusb
-static int micronucleus_nousb_open(struct programmer_t* pgm, char* name)
-{
+static int micronucleus_nousb_open(PROGRAMMER* pgm, const char* name) {
     avrdude_message(MSG_INFO, "%s: error: No usb support. Please compile again with libusb installed.\n", progname);
     return -1;
 }
 
-void micronucleus_initpgm(PROGRAMMER* pgm)
-{
+void micronucleus_initpgm(PROGRAMMER *pgm) {
     strcpy(pgm->type, "micronucleus");
     pgm->open = micronucleus_nousb_open;
 }
diff --git a/src/micronucleus.h b/src/micronucleus.h
index 46c67182..729fa126 100644
--- a/src/micronucleus.h
+++ b/src/micronucleus.h
@@ -26,7 +26,7 @@ extern "C" {
 #endif
 
 extern const char micronucleus_desc[];
-void micronucleus_initpgm(PROGRAMMER* pgm);
+void micronucleus_initpgm(PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/par.c b/src/par.c
index 9dcb8db8..d06cacb7 100644
--- a/src/par.c
+++ b/src/par.c
@@ -73,8 +73,7 @@ static struct ppipins_t ppipins[] = {
 
 #define NPINS (sizeof(ppipins)/sizeof(struct ppipins_t))
 
-static int par_setpin_internal(PROGRAMMER * pgm, int pin, int value)
-{
+static int par_setpin_internal(const PROGRAMMER *pgm, int pin, int value) {
   int inverted;
 
   inverted = pin & PIN_INVERSE;
@@ -102,13 +101,11 @@ static int par_setpin_internal(PROGRAMMER * pgm, int pin, int value)
   return 0;
 }
 
-static int par_setpin(PROGRAMMER * pgm, int pinfunc, int value)
-{
+static int par_setpin(const PROGRAMMER * pgm, int pinfunc, int value) {
   return par_setpin_internal(pgm, pgm->pinno[pinfunc], value);
 }
 
-static void par_setmany(PROGRAMMER * pgm, int pinfunc, int value)
-{
+static void par_setmany(const PROGRAMMER *pgm, int pinfunc, int value) {
   int pin, mask;
   int pinset = pgm->pinno[pinfunc];
 
@@ -121,8 +118,7 @@ static void par_setmany(PROGRAMMER * pgm, int pinfunc, int value)
   }
 }
 
-static int par_getpin(PROGRAMMER * pgm, int pinfunc)
-{
+static int par_getpin(const PROGRAMMER * pgm, int pinfunc) {
   int value;
   int inverted;
   int pin = pgm->pinno[pinfunc];
@@ -150,8 +146,7 @@ static int par_getpin(PROGRAMMER * pgm, int pinfunc)
 }
 
 
-static int par_highpulsepin(PROGRAMMER * pgm, int pinfunc)
-{
+static int par_highpulsepin(const PROGRAMMER *pgm, int pinfunc) {
   int inverted;
   int pin = pgm->pinno[pinfunc];
 
@@ -190,8 +185,7 @@ static int par_highpulsepin(PROGRAMMER * pgm, int pinfunc)
 /*
  * apply power to the AVR processor
  */
-static void par_powerup(PROGRAMMER * pgm)
-{
+static void par_powerup(const PROGRAMMER *pgm) {
   par_setmany(pgm, PPI_AVR_VCC, 1);	/* power up */
   usleep(100000);
 }
@@ -200,18 +194,15 @@ static void par_powerup(PROGRAMMER * pgm)
 /*
  * remove power from the AVR processor
  */
-static void par_powerdown(PROGRAMMER * pgm)
-{
+static void par_powerdown(const PROGRAMMER *pgm) {
   par_setmany(pgm, PPI_AVR_VCC, 0);	/* power down */
 }
 
-static void par_disable(PROGRAMMER * pgm)
-{
+static void par_disable(const PROGRAMMER *pgm) {
   par_setmany(pgm, PPI_AVR_BUFF, 1); /* turn off */
 }
 
-static void par_enable(PROGRAMMER * pgm)
-{
+static void par_enable(PROGRAMMER *pgm, const AVRPART *p) {
   /*
    * Prepare to start talking to the connected device - pull reset low
    * first, delay a few milliseconds, then enable the buffer.  This
@@ -232,8 +223,7 @@ static void par_enable(PROGRAMMER * pgm)
   par_setmany(pgm, PPI_AVR_BUFF, 0);
 }
 
-static int par_open(PROGRAMMER * pgm, char * port)
-{
+static int par_open(PROGRAMMER *pgm, const char *port) {
   int rc;
 
   if (bitbang_check_prerequisites(pgm) < 0)
@@ -267,8 +257,7 @@ static int par_open(PROGRAMMER * pgm, char * port)
 }
 
 
-static void par_close(PROGRAMMER * pgm)
-{
+static void par_close(PROGRAMMER *pgm) {
 
   /*
    * Restore pin values before closing,
@@ -331,40 +320,41 @@ static void par_close(PROGRAMMER * pgm)
 /*
  * parse the -E string
  */
-static int par_parseexitspecs(PROGRAMMER * pgm, char *s)
-{
-  char *cp;
+static int par_parseexitspecs(PROGRAMMER *pgm, const char *sp) {
+  char *cp, *s, *str = cfg_strdup("par_parseexitspecs()", sp);
 
-  while ((cp = strtok(s, ","))) {
-    if (strcmp(cp, "reset") == 0) {
+  s = str;
+  while((cp = strtok(s, ","))) {
+    if(strcmp(cp, "reset") == 0)
       pgm->exit_reset = EXIT_RESET_ENABLED;
-    }
-    else if (strcmp(cp, "noreset") == 0) {
+
+    else if(strcmp(cp, "noreset") == 0)
       pgm->exit_reset = EXIT_RESET_DISABLED;
-    }
-    else if (strcmp(cp, "vcc") == 0) {
+
+    else if(strcmp(cp, "vcc") == 0)
       pgm->exit_vcc = EXIT_VCC_ENABLED;
-    }
-    else if (strcmp(cp, "novcc") == 0) {
+
+    else if(strcmp(cp, "novcc") == 0)
       pgm->exit_vcc = EXIT_VCC_DISABLED;
-    }
-    else if (strcmp(cp, "d_high") == 0) {
+
+    else if(strcmp(cp, "d_high") == 0)
       pgm->exit_datahigh = EXIT_DATAHIGH_ENABLED;
-    }
-    else if (strcmp(cp, "d_low") == 0) {
+
+    else if(strcmp(cp, "d_low") == 0)
       pgm->exit_datahigh = EXIT_DATAHIGH_DISABLED;
-    }
+
     else {
+      free(str);
       return -1;
     }
-    s = 0; /* strtok() should be called with the actual string only once */
+    s = NULL; // Only call strtok() once with the actual string
   }
 
+  free(str);
   return 0;
 }
 
-void par_initpgm(PROGRAMMER * pgm)
-{
+void par_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "PPI");
 
   pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
@@ -400,10 +390,8 @@ void par_initpgm(PROGRAMMER * pgm)
 
 #else  /* !HAVE_PARPORT */
 
-void par_initpgm(PROGRAMMER * pgm)
-{
-  avrdude_message(MSG_INFO, "%s: parallel port access not available in this configuration\n",
-                  progname);
+void par_initpgm(PROGRAMMER *pgm) {
+  avrdude_message(MSG_INFO, "%s: parallel port access not available in this configuration\n", progname);
 }
 
 #endif /* HAVE_PARPORT */
diff --git a/src/par.h b/src/par.h
index 70899703..de3b8759 100644
--- a/src/par.h
+++ b/src/par.h
@@ -26,7 +26,7 @@ extern "C" {
 #endif
 
 extern const char par_desc[];
-void par_initpgm        (PROGRAMMER * pgm);
+void par_initpgm(PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/pgm.c b/src/pgm.c
index 518b208e..2880a212 100644
--- a/src/pgm.c
+++ b/src/pgm.c
@@ -28,36 +28,37 @@
 #include "avrdude.h"
 #include "libavrdude.h"
 
-static int  pgm_default_2 (struct programmer_t *, AVRPART *);
-static int  pgm_default_3 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
-			   unsigned long addr, unsigned char * value);
-static void pgm_default_4 (struct programmer_t *);
-static int  pgm_default_5 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
-			   unsigned long addr, unsigned char data);
-static void pgm_default_6 (struct programmer_t *, const char *);
+static void pgm_default(void);
+static int  pgm_default_2(const PROGRAMMER *, const AVRPART *);
+static int  pgm_default_3(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
+  unsigned long addr, unsigned char * value);
+static void pgm_default_4(const PROGRAMMER *);
+static int  pgm_default_5(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
+  unsigned long addr, unsigned char data);
+static void pgm_default_6(const PROGRAMMER *, const char *);
 
 
-static int pgm_default_open (struct programmer_t *pgm, char * name)
-{
-  avrdude_message(MSG_INFO, "\n%s: Fatal error: Programmer does not support open()",
-               progname);
+static int pgm_default_open(PROGRAMMER *pgm, const char *name) {
+  avrdude_message(MSG_INFO, "\n%s: programmer does not support open()", progname);
   return -1;
 }
 
-static int  pgm_default_led (struct programmer_t * pgm, int value)
-{
-  /*
-   * If programmer has no LEDs, just do nothing.
-   */
+static void pgm_default_close(PROGRAMMER *pgm) {
+  pgm_default();
+}
+
+static void pgm_default_enable(PROGRAMMER *pgm, const AVRPART *p) {
+  pgm_default();
+}
+
+static int pgm_default_led(const PROGRAMMER *pgm, int value) {
+   // If programmer has no LEDs, just do nothing
   return 0;
 }
 
 
-static void pgm_default_powerup_powerdown (struct programmer_t * pgm)
-{
-  /*
-   * If programmer does not support powerup/down, just do nothing.
-   */
+static void pgm_default_powerup_powerdown(const PROGRAMMER *pgm) {
+   // If programmer does not support powerup/down, just do nothing
 }
 
 
@@ -94,14 +95,14 @@ PROGRAMMER *pgm_new(void) {
    */
   pgm->initialize     = pgm_default_2;
   pgm->display        = pgm_default_6;
-  pgm->enable         = pgm_default_4;
+  pgm->enable         = pgm_default_enable;
   pgm->disable        = pgm_default_4;
   pgm->powerup        = pgm_default_powerup_powerdown;
   pgm->powerdown      = pgm_default_powerup_powerdown;
   pgm->program_enable = pgm_default_2;
   pgm->chip_erase     = pgm_default_2;
   pgm->open           = pgm_default_open;
-  pgm->close          = pgm_default_4;
+  pgm->close          = pgm_default_close;
   pgm->read_byte      = pgm_default_3;
   pgm->write_byte     = pgm_default_5;
 
@@ -189,39 +190,33 @@ PROGRAMMER *pgm_dup(const PROGRAMMER *src) {
 }
 
 
-static void pgm_default(void)
-{
+static void pgm_default(void) {
   avrdude_message(MSG_INFO, "%s: programmer operation not supported\n", progname);
 }
 
 
-static int  pgm_default_2 (struct programmer_t * pgm, AVRPART * p)
-{
+static int  pgm_default_2 (const PROGRAMMER *pgm, const AVRPART *p) {
   pgm_default();
   return -1;
 }
 
-static int  pgm_default_3 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
-			   unsigned long addr, unsigned char * value)
-{
+static int  pgm_default_3 (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
+			   unsigned long addr, unsigned char * value) {
   pgm_default();
   return -1;
 }
 
-static void pgm_default_4 (struct programmer_t * pgm)
-{
+static void pgm_default_4 (const PROGRAMMER *pgm) {
   pgm_default();
 }
 
-static int  pgm_default_5 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
-			   unsigned long addr, unsigned char data)
-{
+static int  pgm_default_5 (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
+			   unsigned long addr, unsigned char data) {
   pgm_default();
   return -1;
 }
 
-static void pgm_default_6 (struct programmer_t * pgm, const char * p)
-{
+static void pgm_default_6 (const PROGRAMMER *pgm, const char *p) {
   pgm_default();
 }
 
diff --git a/src/pgm_type.c b/src/pgm_type.c
index 46090424..45ce8dca 100644
--- a/src/pgm_type.c
+++ b/src/pgm_type.c
@@ -129,7 +129,7 @@ const PROGRAMMER_TYPE * locate_programmer_type(const char * id)
 }
 
 // Return type id given the init function or "" if not found
-const char *locate_programmer_type_id(void (*initpgm)(struct programmer_t *pgm)) {
+const char *locate_programmer_type_id(void (*initpgm)(PROGRAMMER *pgm)) {
   for (int i=0; i < sizeof programmers_types/sizeof*programmers_types; i++)
     if(programmers_types[i].initpgm == initpgm)
       return programmers_types[i].id;
diff --git a/src/pickit2.c b/src/pickit2.c
index a1d32f88..dada4e12 100644
--- a/src/pickit2.c
+++ b/src/pickit2.c
@@ -104,8 +104,8 @@ static int usb_open_device(struct usb_dev_handle **dev, int vid, int pid);
 #define USB_ERROR_IO        5
 #endif  // WIN32
 
-static int pickit2_write_report(PROGRAMMER *pgm, const unsigned char report[65]);
-static int pickit2_read_report(PROGRAMMER *pgm, unsigned char report[65]);
+static int pickit2_write_report(const PROGRAMMER *pgm, const unsigned char report[65]);
+static int pickit2_read_report(const PROGRAMMER *pgm, unsigned char report[65]);
 
 #ifndef MIN
 #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
@@ -179,8 +179,7 @@ static void pickit2_teardown(PROGRAMMER * pgm)
     free(pgm->cookie);
 }
 
-static int pickit2_open(PROGRAMMER * pgm, char * port)
-{
+static int pickit2_open(PROGRAMMER *pgm, const char *port) {
 #if (defined(WIN32) && defined(HAVE_LIBHID))
     PDATA(pgm)->usb_handle = open_hid(PICKIT2_VID, PICKIT2_PID);
 
@@ -241,8 +240,7 @@ static void pickit2_close(PROGRAMMER * pgm)
 }
 
 
-static int pickit2_initialize(PROGRAMMER * pgm, AVRPART * p)
-{
+static int pickit2_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
     unsigned char temp[4];
     memset(temp, 0, sizeof(temp));
 
@@ -317,8 +315,7 @@ static int pickit2_initialize(PROGRAMMER * pgm, AVRPART * p)
         return -1;
 }
 
-static void pickit2_disable(PROGRAMMER * pgm)
-{
+static void pickit2_disable(const PROGRAMMER *pgm) {
     /* make sure all pins are floating & all voltages are off */
     static const unsigned char report[65] =
     {
@@ -339,15 +336,11 @@ static void pickit2_disable(PROGRAMMER * pgm)
     return;
 }
 
-static void pickit2_enable(PROGRAMMER * pgm)
-{
-    /* Do nothing. */
-
+static void pickit2_enable(PROGRAMMER *pgm, const AVRPART *p) {
     return;
 }
 
-static void pickit2_display(PROGRAMMER * pgm, const char * p)
-{
+static void pickit2_display(const PROGRAMMER *pgm, const char *p) {
     DEBUG( "%s: Found \"%s\" version %d.%d.%d\n", progname, p, 1, 1, 1);
     return;
 }
@@ -356,14 +349,12 @@ static void pickit2_display(PROGRAMMER * pgm, const char * p)
 #define readReport(x) 0
 
 #if 0
-static int  pickit2_rdy_led        (struct programmer_t * pgm, int value)
-{
+static int  pickit2_rdy_led(const PROGRAMMER *pgm, int value) {
     // no rdy led
     return 0;
 }
 
-static int  pickit2_err_led(struct programmer_t * pgm, int value)
-{
+static int  pickit2_err_led(const PROGRAMMER *pgm, int value) {
     // there is no error led, so just flash the busy led a few times
     uint8_t report[65] =
     {
@@ -386,8 +377,7 @@ static int  pickit2_err_led(struct programmer_t * pgm, int value)
 }
 #endif
 
-static int  pickit2_pgm_led (struct programmer_t * pgm, int value)
-{
+static int  pickit2_pgm_led(const PROGRAMMER *pgm, int value) {
     // script to set busy led appropriately
     uint8_t report[65] = {0, CMD_EXEC_SCRIPT_2(1),
                         value ? SCR_BUSY_LED_ON : SCR_BUSY_LED_OFF,
@@ -397,26 +387,22 @@ static int  pickit2_pgm_led (struct programmer_t * pgm, int value)
     return pickit2_write_report(pgm, report) != -1;
 }
 
-static int  pickit2_vfy_led        (struct programmer_t * pgm, int value)
-{
+static int  pickit2_vfy_led(const PROGRAMMER *pgm, int value) {
     // no such thing - maybe just call pgm_led
 
     return pgm->pgm_led(pgm, value);
 }
 
-static void pickit2_powerup(struct programmer_t * pgm)
-{
+static void pickit2_powerup(const PROGRAMMER *pgm) {
     // turn vdd on?
 }
 
-static void pickit2_powerdown(struct programmer_t * pgm)
-{
+static void pickit2_powerdown(const PROGRAMMER *pgm) {
     // do what?
     pgm->disable(pgm);
 }
 
-static int  pickit2_program_enable(struct programmer_t * pgm, AVRPART * p)
-{
+static int  pickit2_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
     unsigned char cmd[4];
     unsigned char res[4];
 
@@ -449,8 +435,7 @@ static int  pickit2_program_enable(struct programmer_t * pgm, AVRPART * p)
     return 0;
 }
 
-static int  pickit2_chip_erase(struct programmer_t * pgm, AVRPART * p)
-{
+static int  pickit2_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
     unsigned char cmd[4];
     unsigned char res[4];
 
@@ -475,9 +460,9 @@ static int  pickit2_chip_erase(struct programmer_t * pgm, AVRPART * p)
     return 0;
 }
 
-static int  pickit2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
-                        unsigned int page_size, unsigned int addr, unsigned int n_bytes)
-{
+static int pickit2_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
+  unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
+
     // only supporting flash & eeprom page reads
     if ((!mem->paged || page_size <= 1) || (strcmp(mem->desc, "flash") != 0 && strcmp(mem->desc, "eeprom") != 0))
     {
@@ -568,7 +553,7 @@ static int  pickit2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 }
 
 
-static int pickit2_commit_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int pickit2_commit_page(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                         unsigned long addr)
 {
     OPCODE * wp, * lext;
@@ -618,7 +603,7 @@ static int pickit2_commit_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 }
 
 // not actually a paged write, but a bulk/batch write
-static int  pickit2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int  pickit2_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                          unsigned int page_size, unsigned int addr, unsigned int n_bytes)
 {
     // only paged write for flash implemented
@@ -731,14 +716,14 @@ static int  pickit2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 }
 
 
-static int pickit2_cmd(struct programmer_t * pgm, const unsigned char *cmd,
+static int pickit2_cmd(const PROGRAMMER *pgm, const unsigned char *cmd,
                 unsigned char *res)
 {
     return pgm->spi(pgm, cmd, res, 4);
 }
 
 // breaks up the cmd[] data into  packets & sends to the pickit2. Data shifted in is stored in res[].
-static int pickit2_spi(struct programmer_t * pgm, const unsigned char *cmd,
+static int pickit2_spi(const PROGRAMMER *pgm, const unsigned char *cmd,
                 unsigned char *res, int n_bytes)
 {
     int retval = 0, temp1 = 0, temp2 = 0, count = n_bytes;
@@ -1058,8 +1043,7 @@ static HANDLE open_hid(unsigned short vid, unsigned short pid)
 }
 
 // simple read with timeout
-static int usb_read_interrupt(PROGRAMMER *pgm, void *buff, int size, int timeout)
-{
+static int usb_read_interrupt(const PROGRAMMER *pgm, void *buff, int size, int timeout) {
     OVERLAPPED ovr;
     DWORD bytesRead = 0;
 
@@ -1084,8 +1068,7 @@ static int usb_read_interrupt(PROGRAMMER *pgm, void *buff, int size, int timeout
 }
 
 // simple write with timeout
-static int usb_write_interrupt(PROGRAMMER *pgm, const void *buff, int size, int timeout)
-{
+static int usb_write_interrupt(const PROGRAMMER *pgm, const void *buff, int size, int timeout) {
     OVERLAPPED ovr;
     DWORD bytesWritten = 0;
 
@@ -1109,13 +1092,11 @@ static int usb_write_interrupt(PROGRAMMER *pgm, const void *buff, int size, int
     return bytesWritten > 0 ? bytesWritten : -1;
 }
 
-static int pickit2_write_report(PROGRAMMER * pgm, const unsigned char report[65])
-{
+static int pickit2_write_report(const PROGRAMMER *pgm, const unsigned char report[65]) {
     return usb_write_interrupt(pgm, report, 65, PDATA(pgm)->transaction_timeout); // XXX
 }
 
-static int pickit2_read_report(PROGRAMMER * pgm, unsigned char report[65])
-{
+static int pickit2_read_report(const PROGRAMMER *pgm, unsigned char report[65]) {
     return usb_read_interrupt(pgm, report, 65, PDATA(pgm)->transaction_timeout);
 }
 
@@ -1180,21 +1161,18 @@ static int usb_open_device(struct usb_dev_handle **device, int vendor, int produ
     return -1;
 }
 
-static int pickit2_write_report(PROGRAMMER * pgm, const unsigned char report[65])
-{
+static int pickit2_write_report(const PROGRAMMER *pgm, const unsigned char report[65]) {
     // endpoint 1 OUT??
     return usb_interrupt_write(PDATA(pgm)->usb_handle, USB_ENDPOINT_OUT | 1, (char*)(report+1), 64, PDATA(pgm)->transaction_timeout);
 }
 
-static int pickit2_read_report(PROGRAMMER * pgm, unsigned char report[65])
-{
+static int pickit2_read_report(const PROGRAMMER *pgm, unsigned char report[65]) {
     // endpoint 1 IN??
     return usb_interrupt_read(PDATA(pgm)->usb_handle, USB_ENDPOINT_IN | 1, (char*)(report+1), 64, PDATA(pgm)->transaction_timeout);
 }
 #endif  // WIN32
 
-static int  pickit2_parseextparams(struct programmer_t * pgm, LISTID extparms)
-{
+static int  pickit2_parseextparams(const PROGRAMMER *pgm, const LISTID extparms) {
     LNODEID ln;
     const char *extended_param;
     int rv = 0;
@@ -1251,8 +1229,7 @@ static int  pickit2_parseextparams(struct programmer_t * pgm, LISTID extparms)
 }
 
 
-void pickit2_initpgm (PROGRAMMER * pgm)
-{
+void pickit2_initpgm(PROGRAMMER *pgm) {
     /*
      * mandatory functions - these are called without checking to see
      * whether they are assigned or not
@@ -1307,7 +1284,7 @@ void pickit2_initpgm (PROGRAMMER * pgm)
     strncpy(pgm->type, "pickit2", sizeof(pgm->type));
 }
 #else
-static int pickit2_nousb_open (struct programmer_t *pgm, char * name) {
+static int pickit2_nousb_open(PROGRAMMER *pgm, const char *name) {
     avrdude_message(MSG_INFO, 
 #ifdef WIN32
             "%s: error: no usb or hid support. Please compile again with libusb or HID support from Win32 DDK installed.\n",
@@ -1319,8 +1296,7 @@ static int pickit2_nousb_open (struct programmer_t *pgm, char * name) {
     return -1;
 }
 
-void pickit2_initpgm (PROGRAMMER * pgm)
-{
+void pickit2_initpgm(PROGRAMMER *pgm) {
     /*
      * mandatory functions - these are called without checking to see
      * whether they are assigned or not
diff --git a/src/pickit2.h b/src/pickit2.h
index cdd58d96..4663266f 100644
--- a/src/pickit2.h
+++ b/src/pickit2.h
@@ -26,7 +26,7 @@ extern "C" {
 #endif
 
 extern const char pickit2_desc[];
-void pickit2_initpgm (PROGRAMMER * pgm);
+void pickit2_initpgm(PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/pindefs.c b/src/pindefs.c
index 2e78c8df..7127f539 100644
--- a/src/pindefs.c
+++ b/src/pindefs.c
@@ -118,7 +118,7 @@ static int pin_fill_old_pinlist(const struct pindef_t * const pindef, unsigned i
  *
  * @param[inout] pgm programmer whose pins shall be converted.
  */
-int pgm_fill_old_pins(struct programmer_t * const pgm) {
+int pgm_fill_old_pins(PROGRAMMER * const pgm) {
 
   if (pin_fill_old_pinlist(&(pgm->pin[PPI_AVR_VCC]),  &(pgm->pinno[PPI_AVR_VCC])) < 0)
     return -1;
@@ -218,7 +218,7 @@ const char * pinmask_to_str(const pinmask_t * const pinmask) {
  * @param[in] size the number of entries in checklist
  * @returns 0 if all pin definitions are valid, -1 otherwise
  */
-int pins_check(const struct programmer_t * const pgm, const struct pin_checklist_t * const checklist, const int size, const bool output) {
+int pins_check(const PROGRAMMER *const pgm, const struct pin_checklist_t *const checklist, const int size, const bool output) {
   static const struct pindef_t no_valid_pins = {{0}, {0}}; // default value if check list does not contain anything else
   int rv = 0; // return value
   int pinname; // loop counter through pinnames
diff --git a/src/ppi.c b/src/ppi.c
index 4478115f..f99e44c9 100644
--- a/src/ppi.c
+++ b/src/ppi.c
@@ -51,7 +51,7 @@ enum {
   PPI_SHADOWREAD
 };
 
-static int ppi_shadow_access(union filedescriptor *fdp, int reg,
+static int ppi_shadow_access(const union filedescriptor *fdp, int reg,
 			     unsigned char *v, unsigned char action)
 {
   static unsigned char shadow[3];
@@ -93,8 +93,7 @@ static int ppi_shadow_access(union filedescriptor *fdp, int reg,
 /*
  * set the indicated bit of the specified register.
  */
-int ppi_set(union filedescriptor *fdp, int reg, int bit)
-{
+int ppi_set(const union filedescriptor *fdp, int reg, int bit) {
   unsigned char v;
   int rc;
 
@@ -112,8 +111,7 @@ int ppi_set(union filedescriptor *fdp, int reg, int bit)
 /*
  * clear the indicated bit of the specified register.
  */
-int ppi_clr(union filedescriptor *fdp, int reg, int bit)
-{
+int ppi_clr(const union filedescriptor *fdp, int reg, int bit) {
   unsigned char v;
   int rc;
 
@@ -131,8 +129,7 @@ int ppi_clr(union filedescriptor *fdp, int reg, int bit)
 /*
  * get the indicated bit of the specified register.
  */
-int ppi_get(union filedescriptor *fdp, int reg, int bit)
-{
+int ppi_get(const union filedescriptor *fdp, int reg, int bit) {
   unsigned char v;
   int rc;
 
@@ -148,8 +145,7 @@ int ppi_get(union filedescriptor *fdp, int reg, int bit)
 /*
  * toggle the indicated bit of the specified register.
  */
-int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
-{
+int ppi_toggle(const union filedescriptor *fdp, int reg, int bit) {
   unsigned char v;
   int rc;
 
@@ -167,8 +163,7 @@ int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
 /*
  * get all bits of the specified register.
  */
-int ppi_getall(union filedescriptor *fdp, int reg)
-{
+int ppi_getall(const union filedescriptor *fdp, int reg) {
   unsigned char v;
   int rc;
 
@@ -183,8 +178,7 @@ int ppi_getall(union filedescriptor *fdp, int reg)
 /*
  * set all bits of the specified register to val.
  */
-int ppi_setall(union filedescriptor *fdp, int reg, int val)
-{
+int ppi_setall(const union filedescriptor *fdp, int reg, int val) {
   unsigned char v;
   int rc;
 
@@ -198,8 +192,7 @@ int ppi_setall(union filedescriptor *fdp, int reg, int val)
 }
 
 
-void ppi_open(char * port, union filedescriptor *fdp)
-{
+void ppi_open(const char *port, union filedescriptor *fdp) {
   int fd;
   unsigned char v;
 
@@ -225,8 +218,7 @@ void ppi_open(char * port, union filedescriptor *fdp)
 }
 
 
-void ppi_close(union filedescriptor *fdp)
-{
+void ppi_close(const union filedescriptor *fdp) {
   ppi_release (fdp->ifd);
   close(fdp->ifd);
 }
diff --git a/src/ppi.h b/src/ppi.h
index 38fc1e8b..ec692735 100644
--- a/src/ppi.h
+++ b/src/ppi.h
@@ -34,21 +34,21 @@ enum {
 extern "C" {
 #endif
 
-int ppi_get       (union filedescriptor *fdp, int reg, int bit);
+int ppi_get       (const union filedescriptor *fdp, int reg, int bit);
 
-int ppi_set       (union filedescriptor *fdp, int reg, int bit);
+int ppi_set       (const union filedescriptor *fdp, int reg, int bit);
 
-int ppi_clr       (union filedescriptor *fdp, int reg, int bit);
+int ppi_clr       (const union filedescriptor *fdp, int reg, int bit);
 
-int ppi_getall    (union filedescriptor *fdp, int reg);
+int ppi_getall    (const union filedescriptor *fdp, int reg);
 
-int ppi_setall    (union filedescriptor *fdp, int reg, int val);
+int ppi_setall    (const union filedescriptor *fdp, int reg, int val);
 
-int ppi_toggle    (union filedescriptor *fdp, int reg, int bit);
+int ppi_toggle    (const union filedescriptor *fdp, int reg, int bit);
 
-void ppi_open     (char * port, union filedescriptor *fdp);
+void ppi_open     (const char *port, union filedescriptor *fdp);
 
-void ppi_close    (union filedescriptor *fdp);
+void ppi_close    (const union filedescriptor *fdp);
 
 #ifdef __cplusplus
 }
diff --git a/src/ppiwin.c b/src/ppiwin.c
index 71ec0a9f..76122eb8 100644
--- a/src/ppiwin.c
+++ b/src/ppiwin.c
@@ -84,8 +84,7 @@ static void outb(unsigned char value, unsigned short port);
 
 /* FUNCTION DEFINITIONS */
 
-void ppi_open(char *port, union filedescriptor *fdp)
-{
+void ppi_open(const char *port, union filedescriptor *fdp) {
     unsigned char i;
     int fd;
 	
@@ -138,8 +137,7 @@ void ppi_open(char *port, union filedescriptor *fdp)
 
 
 #define DRIVERNAME      "\\\\.\\giveio"
-static int winnt_pp_open(void)
-{
+static int winnt_pp_open(void) {
     // Only try to use giveio under Windows NT/2000/XP.
     OSVERSIONINFO ver_info;
 
@@ -178,8 +176,7 @@ static int winnt_pp_open(void)
 
 
 
-void ppi_close(union filedescriptor *fdp)
-{
+void ppi_close(const union filedescriptor *fdp) {
     return;
 }
 
@@ -188,8 +185,7 @@ void ppi_close(union filedescriptor *fdp)
 /*
  * set the indicated bit of the specified register.
  */
-int ppi_set(union filedescriptor *fdp, int reg, int bit)
-{
+int ppi_set(const union filedescriptor *fdp, int reg, int bit) {
     unsigned char v;
     unsigned short port;
 
@@ -204,8 +200,7 @@ int ppi_set(union filedescriptor *fdp, int reg, int bit)
 /*
  * clear the indicated bit of the specified register.
  */
-int ppi_clr(union filedescriptor *fdp, int reg, int bit)
-{
+int ppi_clr(const union filedescriptor *fdp, int reg, int bit) {
     unsigned char v;
     unsigned short port;
 
@@ -221,8 +216,7 @@ int ppi_clr(union filedescriptor *fdp, int reg, int bit)
 /*
  * get the indicated bit of the specified register.
  */
-int ppi_get(union filedescriptor *fdp, int reg, int bit)
-{
+int ppi_get(const union filedescriptor *fdp, int reg, int bit) {
     unsigned char v;
 
     v = inb(port_get(fdp, reg));
@@ -237,8 +231,7 @@ int ppi_get(union filedescriptor *fdp, int reg, int bit)
 /*
  * toggle the indicated bit of the specified register.
  */
-int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
-{
+int ppi_toggle(const union filedescriptor *fdp, int reg, int bit) {
     unsigned char v;
     unsigned short port;
 
@@ -255,8 +248,7 @@ int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
 /*
  * get all bits of the specified register.
  */
-int ppi_getall(union filedescriptor *fdp, int reg)
-{
+int ppi_getall(const union filedescriptor *fdp, int reg) {
     unsigned char v;
 
     v = inb(port_get(fdp, reg));
@@ -270,8 +262,7 @@ int ppi_getall(union filedescriptor *fdp, int reg)
 /*
  * set all bits of the specified register to val.
  */
-int ppi_setall(union filedescriptor *fdp, int reg, int val)
-{
+int ppi_setall(const union filedescriptor *fdp, int reg, int val) {
     outb((unsigned char)val, port_get(fdp, reg));
     return 0;
 }
@@ -280,15 +271,13 @@ int ppi_setall(union filedescriptor *fdp, int reg, int val)
 
 
 /* Calculate port address to access. */
-static unsigned short port_get(union filedescriptor *fdp, int reg)
-{
+static unsigned short port_get(const union filedescriptor *fdp, int reg) {
     return((unsigned short)(fdp->ifd + reg2offset(reg)));
 }
 
 
 /* Convert register enum to offset of base address. */
-static unsigned char reg2offset(int reg)
-{
+static unsigned char reg2offset(int reg) {
     unsigned char offset = 0;
 
     switch(reg)
@@ -315,8 +304,7 @@ static unsigned char reg2offset(int reg)
 
 
 /* Read in value from port. */
-static unsigned char inb(unsigned short port)
-{
+static unsigned char inb(unsigned short port) {
     unsigned char t;
     
 	asm volatile ("in %1, %0"
@@ -328,8 +316,7 @@ static unsigned char inb(unsigned short port)
 
 
 /* Write value to port. */
-static void outb(unsigned char value, unsigned short port)
-{
+static void outb(unsigned char value, unsigned short port) {
     asm volatile ("out %1, %0"
         :
         : "d" (port), "a" (value) );
diff --git a/src/ser_avrdoper.c b/src/ser_avrdoper.c
index e459f921..d77465b0 100644
--- a/src/ser_avrdoper.c
+++ b/src/ser_avrdoper.c
@@ -96,8 +96,7 @@ static void usbCloseDevice(union filedescriptor *fdp)
 
 /* ------------------------------------------------------------------------- */
 
-static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer, int len)
-{
+static int usbSetReport(const union filedescriptor *fdp, int reportType, char *buffer, int len) {
   hid_device *udev = (hid_device *)fdp->usb.handle;
   int bytesSent = -1;
 
@@ -122,7 +121,7 @@ static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer,
 
 /* ------------------------------------------------------------------------- */
 
-static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNumber,
+static int usbGetReport(const union filedescriptor *fdp, int reportType, int reportNumber,
 			char *buffer, int *len)
 {
   hid_device *udev = (hid_device *)fdp->usb.handle;
@@ -221,7 +220,7 @@ static char *usbErrorText(int usbErrno)
 
 /* ------------------------------------------------------------------------- */
 
-static int avrdoper_open(char *port, union pinfo pinfo, union filedescriptor *fdp)
+static int avrdoper_open(const char *port, union pinfo pinfo, union filedescriptor *fdp)
 {
     int rval;
     char *vname = "obdev.at";
@@ -255,7 +254,7 @@ static int  chooseDataSize(int len)
     return i - 1;
 }
 
-static int avrdoper_send(union filedescriptor *fdp, const unsigned char *buf, size_t buflen)
+static int avrdoper_send(const union filedescriptor *fdp, const unsigned char *buf, size_t buflen)
 {
     if(verbose > 3)
         dumpBlock("Send", buf, buflen);
@@ -282,8 +281,7 @@ static int avrdoper_send(union filedescriptor *fdp, const unsigned char *buf, si
 
 /* ------------------------------------------------------------------------- */
 
-static int avrdoperFillBuffer(union filedescriptor *fdp)
-{
+static int avrdoperFillBuffer(const union filedescriptor *fdp) {
     int bytesPending = reportDataSizes[1];  /* guess how much data is buffered in device */
 
     avrdoperRxPosition = avrdoperRxLength = 0;
@@ -316,7 +314,7 @@ static int avrdoperFillBuffer(union filedescriptor *fdp)
     return 0;
 }
 
-static int avrdoper_recv(union filedescriptor *fdp, unsigned char *buf, size_t buflen)
+static int avrdoper_recv(const union filedescriptor *fdp, unsigned char *buf, size_t buflen)
 {
     unsigned char   *p = buf;
     int             remaining = buflen;
@@ -341,7 +339,7 @@ static int avrdoper_recv(union filedescriptor *fdp, unsigned char *buf, size_t b
 
 /* ------------------------------------------------------------------------- */
 
-static int avrdoper_drain(union filedescriptor *fdp, int display)
+static int avrdoper_drain(const union filedescriptor *fdp, int display)
 {
     do{
         if (avrdoperFillBuffer(fdp) < 0)
@@ -352,7 +350,7 @@ static int avrdoper_drain(union filedescriptor *fdp, int display)
 
 /* ------------------------------------------------------------------------- */
 
-static int avrdoper_set_dtr_rts(union filedescriptor *fdp, int is_on)
+static int avrdoper_set_dtr_rts(const union filedescriptor *fdp, int is_on)
 {
 	avrdude_message(MSG_INFO, "%s: AVR-Doper doesn't support DTR/RTS setting\n", progname);
     return -1;
diff --git a/src/ser_posix.c b/src/ser_posix.c
index 53d8cd15..d48abad7 100644
--- a/src/ser_posix.c
+++ b/src/ser_posix.c
@@ -122,8 +122,7 @@ static struct baud_mapping baud_lookup_table [] = {
 static struct termios original_termios;
 static int saved_original_termios;
 
-static speed_t serial_baud_lookup(long baud, bool *nonstandard)
-{
+static speed_t serial_baud_lookup(long baud, bool *nonstandard) {
   struct baud_mapping *map = baud_lookup_table;
 
   *nonstandard = false;
@@ -146,8 +145,7 @@ static speed_t serial_baud_lookup(long baud, bool *nonstandard)
   return baud;
 }
 
-static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cflags)
-{
+static int ser_setparams(const union filedescriptor *fd, long baud, unsigned long cflags) {
   int rc;
   struct termios termios;
   bool nonstandard;
@@ -283,9 +281,7 @@ static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cfla
  * terminal/console server with serial parameters configured
  * appropriately (e. g. 115200-8-N-1 for a STK500.)
  */
-static int
-net_open(const char *port, union filedescriptor *fdp)
-{
+static int net_open(const char *port, union filedescriptor *fdp) {
   char *hp, *hstr, *pstr;
   int s, fd, ret = -1;
   struct addrinfo hints;
@@ -361,8 +357,7 @@ error:
 }
 
 
-static int ser_set_dtr_rts(union filedescriptor *fdp, int is_on)
-{
+static int ser_set_dtr_rts(const union filedescriptor *fdp, int is_on) {
   unsigned int	ctl;
   int           r;
 
@@ -390,8 +385,7 @@ static int ser_set_dtr_rts(union filedescriptor *fdp, int is_on)
   return 0;
 }
 
-static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
-{
+static int ser_open(const char *port, union pinfo pinfo, union filedescriptor *fdp) {
   int rc;
   int fd;
 
@@ -428,8 +422,7 @@ static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
   return 0;
 }
 
-static void ser_close(union filedescriptor *fd)
-{
+static void ser_close(union filedescriptor *fd) {
   /*
    * restore original termios settings from ser_open
    */
@@ -446,8 +439,7 @@ static void ser_close(union filedescriptor *fd)
 }
 
 
-static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t buflen)
-{
+static int ser_send(const union filedescriptor *fd, const unsigned char * buf, size_t buflen) {
   int rc;
   const unsigned char * p = buf;
   size_t len = buflen;
@@ -491,8 +483,7 @@ static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t
 }
 
 
-static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
-{
+static int ser_recv(const union filedescriptor *fd, unsigned char * buf, size_t buflen) {
   struct timeval timeout, to2;
   fd_set rfds;
   int nfds;
@@ -564,8 +555,7 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
 }
 
 
-static int ser_drain(union filedescriptor *fd, int display)
-{
+static int ser_drain(const union filedescriptor *fd, int display) {
   struct timeval timeout;
   fd_set rfds;
   int nfds;
diff --git a/src/ser_win32.c b/src/ser_win32.c
index 970a3ecb..252499e2 100644
--- a/src/ser_win32.c
+++ b/src/ser_win32.c
@@ -95,8 +95,7 @@ static BOOL serial_w32SetTimeOut(HANDLE hComPort, DWORD timeout) // in ms
 	return SetCommTimeouts(hComPort, &ctmo);
 }
 
-static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cflags)
-{
+static int ser_setparams(const union filedescriptor *fd, long baud, unsigned long cflags) {
 	if (serial_over_ethernet) {
 		return -ENOTTY;
 	} else {
@@ -150,9 +149,7 @@ static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cfla
 	}
 }
 
-static int
-net_open(const char *port, union filedescriptor *fdp)
-{
+static int net_open(const char *port, union filedescriptor *fdp) {
 	WSADATA wsaData;
 	LPVOID lpMsgBuf;
 
@@ -243,8 +240,7 @@ net_open(const char *port, union filedescriptor *fdp)
 }
 
 
-static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
-{
+static int ser_open(const char *port, union pinfo pinfo, union filedescriptor *fdp) {
 	LPVOID lpMsgBuf;
 	HANDLE hComPort=INVALID_HANDLE_VALUE;
 	char *newname = 0;
@@ -325,8 +321,7 @@ static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
 }
 
 
-static void ser_close(union filedescriptor *fd)
-{
+static void ser_close(union filedescriptor *fd) {
 	if (serial_over_ethernet) {
 		closesocket(fd->ifd);
 		WSACleanup();
@@ -339,8 +334,7 @@ static void ser_close(union filedescriptor *fd)
 	}
 }
 
-static int ser_set_dtr_rts(union filedescriptor *fd, int is_on)
-{
+static int ser_set_dtr_rts(const union filedescriptor *fd, int is_on) {
 	if (serial_over_ethernet) {
 		return 0;
 	} else {
@@ -357,8 +351,7 @@ static int ser_set_dtr_rts(union filedescriptor *fd, int is_on)
 	}
 }
 
-static int net_send(union filedescriptor *fd, const unsigned char * buf, size_t buflen)
-{
+static int net_send(const union filedescriptor *fd, const unsigned char * buf, size_t buflen) {
 	LPVOID lpMsgBuf;
 	int rc;
 	const unsigned char *p = buf;
@@ -417,8 +410,7 @@ static int net_send(union filedescriptor *fd, const unsigned char * buf, size_t
 }
 
 
-static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t buflen)
-{
+static int ser_send(const union filedescriptor *fd, const unsigned char * buf, size_t buflen) {
 	if (serial_over_ethernet) {
 		return net_send(fd, buf, buflen);
 	}
@@ -476,8 +468,7 @@ static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t
 }
 
 
-static int net_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
-{
+static int net_recv(const union filedescriptor *fd, unsigned char * buf, size_t buflen) {
 	LPVOID lpMsgBuf;
 	struct timeval timeout, to2;
 	fd_set rfds;
@@ -570,8 +561,7 @@ reselect:
 	return 0;
 }
 
-static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
-{
+static int ser_recv(const union filedescriptor *fd, unsigned char * buf, size_t buflen) {
 	if (serial_over_ethernet) {
 		return net_recv(fd, buf, buflen);
 	}
@@ -639,8 +629,7 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
   return 0;
 }
 
-static int net_drain(union filedescriptor *fd, int display)
-{
+static int net_drain(const union filedescriptor *fd, int display) {
 	LPVOID lpMsgBuf;
 	struct timeval timeout;
 	fd_set rfds;
@@ -718,8 +707,7 @@ static int net_drain(union filedescriptor *fd, int display)
 	return 0;
 }
 
-static int ser_drain(union filedescriptor *fd, int display)
-{
+static int ser_drain(const union filedescriptor *fd, int display) {
 	if (serial_over_ethernet) {
 		return net_drain(fd, display);
 	}
diff --git a/src/serbb.h b/src/serbb.h
index 3257ea0f..da7c9a31 100644
--- a/src/serbb.h
+++ b/src/serbb.h
@@ -26,7 +26,7 @@ extern "C" {
 #endif
 
 extern const char serbb_desc[];
-void serbb_initpgm        (PROGRAMMER * pgm);
+void serbb_initpgm(PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/serbb_posix.c b/src/serbb_posix.c
index 9f10dccf..7addad4e 100644
--- a/src/serbb_posix.c
+++ b/src/serbb_posix.c
@@ -70,8 +70,7 @@ static char *serpins[DB9PINS + 1] =
   { "NONE", "CD", "RXD", "TXD", "DTR", "GND", "DSR", "RTS", "CTS", "RI" };
 #endif
 
-static int serbb_setpin(PROGRAMMER * pgm, int pinfunc, int value)
-{
+static int serbb_setpin(const PROGRAMMER *pgm, int pinfunc, int value) {
   unsigned int	ctl;
   int           r;
   int pin = pgm->pinno[pinfunc]; // get its value
@@ -127,8 +126,7 @@ static int serbb_setpin(PROGRAMMER * pgm, int pinfunc, int value)
   return 0;
 }
 
-static int serbb_getpin(PROGRAMMER * pgm, int pinfunc)
-{
+static int serbb_getpin(const PROGRAMMER *pgm, int pinfunc) {
   unsigned int	ctl;
   unsigned char invert;
   int           r;
@@ -178,8 +176,7 @@ static int serbb_getpin(PROGRAMMER * pgm, int pinfunc)
   }
 }
 
-static int serbb_highpulsepin(PROGRAMMER * pgm, int pinfunc)
-{
+static int serbb_highpulsepin(const PROGRAMMER *pgm, int pinfunc) {
   int pin = pgm->pinno[pinfunc]; // replace pin name by its value
 
   if ( (pin & PIN_MASK) < 1 || (pin & PIN_MASK) > DB9PINS )
@@ -193,33 +190,27 @@ static int serbb_highpulsepin(PROGRAMMER * pgm, int pinfunc)
 
 
 
-static void serbb_display(PROGRAMMER *pgm, const char *p)
-{
+static void serbb_display(const PROGRAMMER *pgm, const char *p) {
   /* MAYBE */
 }
 
-static void serbb_enable(PROGRAMMER *pgm)
-{
+static void serbb_enable(PROGRAMMER *pgm, const AVRPART *p) {
   /* nothing */
 }
 
-static void serbb_disable(PROGRAMMER *pgm)
-{
+static void serbb_disable(const PROGRAMMER *pgm) {
   /* nothing */
 }
 
-static void serbb_powerup(PROGRAMMER *pgm)
-{
+static void serbb_powerup(const PROGRAMMER *pgm) {
   /* nothing */
 }
 
-static void serbb_powerdown(PROGRAMMER *pgm)
-{
+static void serbb_powerdown(const PROGRAMMER *pgm) {
   /* nothing */
 }
 
-static int serbb_open(PROGRAMMER *pgm, char *port)
-{
+static int serbb_open(PROGRAMMER *pgm, const char *port) {
   struct termios mode;
   int flags;
   int r;
@@ -276,8 +267,7 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
   return(0);
 }
 
-static void serbb_close(PROGRAMMER *pgm)
-{
+static void serbb_close(PROGRAMMER *pgm) {
   if (pgm->fd.ifd != -1)
   {
 	  (void)tcsetattr(pgm->fd.ifd, TCSANOW, &oldmode);
@@ -289,8 +279,7 @@ static void serbb_close(PROGRAMMER *pgm)
 
 const char serbb_desc[] = "Serial port bitbanging";
 
-void serbb_initpgm(PROGRAMMER *pgm)
-{
+void serbb_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "SERBB");
 
   pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
diff --git a/src/serbb_win32.c b/src/serbb_win32.c
index 9a58be10..181d177d 100644
--- a/src/serbb_win32.c
+++ b/src/serbb_win32.c
@@ -61,8 +61,7 @@ static int dtr, rts, txd;
 
 #define DB9PINS 9
 
-static int serbb_setpin(PROGRAMMER * pgm, int pinfunc, int value)
-{
+static int serbb_setpin(const PROGRAMMER *pgm, int pinfunc, int value) {
 	int pin = pgm->pinno[pinfunc];
 	HANDLE hComPort = (HANDLE)pgm->fd.pfd;
         LPVOID lpMsgBuf;
@@ -129,8 +128,7 @@ static int serbb_setpin(PROGRAMMER * pgm, int pinfunc, int value)
         return 0;
 }
 
-static int serbb_getpin(PROGRAMMER * pgm, int pinfunc)
-{
+static int serbb_getpin(const PROGRAMMER *pgm, int pinfunc) {
 	int pin = pgm->pinno[pinfunc];
 	HANDLE hComPort = (HANDLE)pgm->fd.pfd;
         LPVOID lpMsgBuf;
@@ -216,8 +214,7 @@ static int serbb_getpin(PROGRAMMER * pgm, int pinfunc)
         return rv;
 }
 
-static int serbb_highpulsepin(PROGRAMMER * pgm, int pinfunc)
-{
+static int serbb_highpulsepin(const PROGRAMMER *pgm, int pinfunc) {
 	    int pin = pgm->pinno[pinfunc];
         if ( (pin & PIN_MASK) < 1 || (pin & PIN_MASK) > DB9PINS )
           return -1;
@@ -229,33 +226,27 @@ static int serbb_highpulsepin(PROGRAMMER * pgm, int pinfunc)
 }
 
 
-static void serbb_display(PROGRAMMER *pgm, const char *p)
-{
+static void serbb_display(const PROGRAMMER *pgm, const char *p) {
   /* MAYBE */
 }
 
-static void serbb_enable(PROGRAMMER *pgm)
-{
+static void serbb_enable(PROGRAMMER *pgm, const AVRPART *p) {
   /* nothing */
 }
 
-static void serbb_disable(PROGRAMMER *pgm)
-{
+static void serbb_disable(const PROGRAMMER *pgm) {
   /* nothing */
 }
 
-static void serbb_powerup(PROGRAMMER *pgm)
-{
+static void serbb_powerup(const PROGRAMMER *pgm) {
   /* nothing */
 }
 
-static void serbb_powerdown(PROGRAMMER *pgm)
-{
+static void serbb_powerdown(const PROGRAMMER *pgm) {
   /* nothing */
 }
 
-static int serbb_open(PROGRAMMER *pgm, char *port)
-{
+static int serbb_open(PROGRAMMER *pgm, const char *port) {
         DCB dcb;
 	LPVOID lpMsgBuf;
 	HANDLE hComPort = INVALID_HANDLE_VALUE;
@@ -319,8 +310,7 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
         return 0;
 }
 
-static void serbb_close(PROGRAMMER *pgm)
-{
+static void serbb_close(PROGRAMMER *pgm) {
 	HANDLE hComPort=(HANDLE)pgm->fd.pfd;
 	if (hComPort != INVALID_HANDLE_VALUE)
 	{
@@ -335,8 +325,7 @@ static void serbb_close(PROGRAMMER *pgm)
 
 const char serbb_desc[] = "Serial port bitbanging";
 
-void serbb_initpgm(PROGRAMMER *pgm)
-{
+void serbb_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "SERBB");
 
   pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
diff --git a/src/serialupdi.c b/src/serialupdi.c
index cb72daee..e8cd4565 100644
--- a/src/serialupdi.c
+++ b/src/serialupdi.c
@@ -43,8 +43,8 @@
 #include "updi_nvm.h"
 #include "updi_constants.h"
 
-static int serialupdi_enter_progmode(PROGRAMMER * pgm);
-static int serialupdi_leave_progmode(PROGRAMMER * pgm);
+static int serialupdi_enter_progmode(const PROGRAMMER *pgm);
+static int serialupdi_leave_progmode(const PROGRAMMER *pgm);
 
 static void serialupdi_setup(PROGRAMMER * pgm)
 {
@@ -64,8 +64,7 @@ static void serialupdi_teardown(PROGRAMMER * pgm)
   free(pgm->cookie);
 }
 
-static int serialupdi_open(PROGRAMMER * pgm, char * port)
-{
+static int serialupdi_open(PROGRAMMER *pgm, const char *port) {
   strcpy(pgm->port, port);
   return updi_link_open(pgm);
 }
@@ -75,8 +74,7 @@ typedef enum {
   RELEASE_RESET
 } reset_mode;
 
-static int serialupdi_reset(PROGRAMMER * pgm, reset_mode mode)
-{
+static int serialupdi_reset(const PROGRAMMER *pgm, reset_mode mode) {
 /*
     def reset(self, apply_reset):
         """
@@ -102,8 +100,7 @@ static int serialupdi_reset(PROGRAMMER * pgm, reset_mode mode)
   return -1;
 }
 
-static int serialupdi_reset_connection(PROGRAMMER * pgm)
-{
+static int serialupdi_reset_connection(const PROGRAMMER *pgm) {
   if (serialupdi_reset(pgm, APPLY_RESET) < 0) {
     avrdude_message(MSG_INFO, "%s: Apply reset operation failed\n", progname);
     return -1;
@@ -117,8 +114,7 @@ static int serialupdi_reset_connection(PROGRAMMER * pgm)
   return updi_link_init(pgm);
 }
 
-static int serialupdi_decode_sib(PROGRAMMER * pgm, updi_sib_info * sib_info)
-{
+static int serialupdi_decode_sib(const PROGRAMMER *pgm, updi_sib_info *sib_info) {
   char * str_ptr;
 
   sib_info->sib_string[SIB_INFO_STRING_LENGTH]=0;
@@ -192,7 +188,7 @@ static void serialupdi_close(PROGRAMMER * pgm)
   updi_link_close(pgm);
 }
 
-static int serialupdi_wait_for_unlock(PROGRAMMER * pgm, unsigned int ms) {
+static int serialupdi_wait_for_unlock(const PROGRAMMER *pgm, unsigned int ms) {
 /*
     def wait_unlocked(self, timeout_ms):
         """
@@ -236,7 +232,7 @@ typedef enum {
   WAIT_FOR_UROW_HIGH
 } urow_wait_mode;
 
-static int serialupdi_wait_for_urow(PROGRAMMER * pgm, unsigned int ms, urow_wait_mode mode) {
+static int serialupdi_wait_for_urow(const PROGRAMMER *pgm, unsigned int ms, urow_wait_mode mode) {
 /*
     def wait_urow_prog(self, timeout_ms, wait_for_high):
         """
@@ -286,8 +282,7 @@ static int serialupdi_wait_for_urow(PROGRAMMER * pgm, unsigned int ms, urow_wait
   return -1;
 }
 
-static int serialupdi_in_prog_mode(PROGRAMMER * pgm, uint8_t * in_prog_mode)
-{
+static int serialupdi_in_prog_mode(const PROGRAMMER *pgm, uint8_t *in_prog_mode) {
 /*
     def in_prog_mode(self):
         """
@@ -315,8 +310,7 @@ static int serialupdi_in_prog_mode(PROGRAMMER * pgm, uint8_t * in_prog_mode)
   return 0;
 }
 
-static int serialupdi_enter_progmode(PROGRAMMER * pgm)
-{
+static int serialupdi_enter_progmode(const PROGRAMMER *pgm) {
 /*
 def enter_progmode(self):
         """
@@ -415,8 +409,7 @@ def enter_progmode(self):
   return 0;
 }
 
-static int serialupdi_leave_progmode(PROGRAMMER * pgm)
-{
+static int serialupdi_leave_progmode(const PROGRAMMER *pgm) {
 /*
     def leave_progmode(self):
         """
@@ -441,7 +434,7 @@ static int serialupdi_leave_progmode(PROGRAMMER * pgm)
   return updi_write_cs(pgm, UPDI_CS_CTRLB, (1 << UPDI_CTRLB_UPDIDIS_BIT) | (1 << UPDI_CTRLB_CCDETDIS_BIT));
 }
 
-static int serialupdi_write_userrow(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int serialupdi_write_userrow(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                     unsigned int page_size,
                                     unsigned int addr, unsigned int n_bytes)
 {
@@ -576,8 +569,7 @@ static int serialupdi_write_userrow(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return 0;
 }
 
-static int serialupdi_initialize(PROGRAMMER * pgm, AVRPART * p)
-{
+static int serialupdi_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
   uint8_t value;
   uint8_t reset_link_required=0;
   
@@ -660,26 +652,23 @@ static int serialupdi_initialize(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static void serialupdi_disable(PROGRAMMER * pgm)
-{
+static void serialupdi_disable(const PROGRAMMER *pgm) {
   /* Do nothing. */
 
   return;
 }
 
-static void serialupdi_enable(PROGRAMMER * pgm)
-{
+static void serialupdi_enable(PROGRAMMER * pgm, const AVRPART *p) {
   /* Do nothing. */
 
   return;
 }
 
-static void serialupdi_display(PROGRAMMER * pgm, const char * p)
-{
+static void serialupdi_display(const PROGRAMMER *pgm, const char *p) {
   return;
 }
 
-static int serialupdi_cmd(PROGRAMMER * pgm, const unsigned char * cmd,
+static int serialupdi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd,
                           unsigned char * res)
 {
   avrdude_message(MSG_INFO, "%s: error: cmd %s[%s] not implemented yet\n",
@@ -687,20 +676,19 @@ static int serialupdi_cmd(PROGRAMMER * pgm, const unsigned char * cmd,
   return -1;
 }
 
-static int serialupdi_program_enable(PROGRAMMER * pgm, AVRPART * p)
-{
+static int serialupdi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
   avrdude_message(MSG_INFO, "%s: error: program enable not implemented yet\n",
     	    progname);
   return -1;
 }
 
-static int serialupdi_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, 
+static int serialupdi_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                                 unsigned long addr, unsigned char * value)
 {
   return updi_read_byte(pgm, mem->offset + addr, value);
 }
 
-static int serialupdi_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int serialupdi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                                  unsigned long addr, unsigned char value)
 {
   if (strstr(mem->desc, "fuse") != 0) {
@@ -723,7 +711,7 @@ static int serialupdi_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 }
 
 
-static int serialupdi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int serialupdi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                  unsigned int page_size,
                                  unsigned int addr, unsigned int n_bytes)
 {
@@ -750,7 +738,7 @@ static int serialupdi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   }
 }
 
-static int serialupdi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int serialupdi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                   unsigned int page_size,
                                   unsigned int addr, unsigned int n_bytes)
 {
@@ -806,8 +794,7 @@ static int serialupdi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   }
 }
 
-static int serialupdi_unlock(PROGRAMMER * pgm, AVRPART * p)
-{
+static int serialupdi_unlock(const PROGRAMMER *pgm, const AVRPART *p) {
 /*
     def unlock(self):
         """
@@ -875,8 +862,7 @@ static int serialupdi_unlock(PROGRAMMER * pgm, AVRPART * p)
   return serialupdi_enter_progmode(pgm);
 }
 
-static int serialupdi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+static int serialupdi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
   uint8_t value;
 
   if (updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value)<0) {
@@ -896,7 +882,7 @@ static int serialupdi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
   return -1;
 }
 
-static int serialupdi_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int serialupdi_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                  unsigned int baseaddr)
 {
   avrdude_message(MSG_INFO, "%s: error: page erase not implemented yet\n",
@@ -904,7 +890,7 @@ static int serialupdi_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return -1;
 }
 
-static int serialupdi_read_signature(PROGRAMMER * pgm, AVRPART *p, AVRMEM *m) {
+static int serialupdi_read_signature(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m) {
 
   uint8_t value;
 
@@ -926,7 +912,7 @@ static int serialupdi_read_signature(PROGRAMMER * pgm, AVRPART *p, AVRMEM *m) {
   return 3;
 }
 
-static int serialupdi_read_sib(PROGRAMMER * pgm, AVRPART *p, char *sib) {
+static int serialupdi_read_sib(const PROGRAMMER *pgm, const AVRPART *p, char *sib) {
 
   updi_sib_info * sib_info = updi_get_sib_info(pgm);
 
@@ -935,8 +921,7 @@ static int serialupdi_read_sib(PROGRAMMER * pgm, AVRPART *p, char *sib) {
   return 0;
 }
 
-static int serialupdi_parseextparms(PROGRAMMER * pgm, LISTID extparms)
-{
+static int serialupdi_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
   LNODEID ln;
   const char *extended_param;
   char rts_mode[5];
@@ -965,8 +950,7 @@ static int serialupdi_parseextparms(PROGRAMMER * pgm, LISTID extparms)
   return rv;
 }
 
-void serialupdi_initpgm(PROGRAMMER * pgm)
-{
+void serialupdi_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "serialupdi");
 
   /*
diff --git a/src/serialupdi.h b/src/serialupdi.h
index ff7270d5..701a915f 100644
--- a/src/serialupdi.h
+++ b/src/serialupdi.h
@@ -34,7 +34,7 @@ extern "C" {
 #endif
 
 extern const char serialupdi_desc[];
-void serialupdi_initpgm (PROGRAMMER * pgm);
+void serialupdi_initpgm(PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/stk500.c b/src/stk500.c
index 27334297..89667477 100644
--- a/src/stk500.c
+++ b/src/stk500.c
@@ -45,28 +45,17 @@
 #define STK500_XTAL 7372800U
 #define MAX_SYNC_ATTEMPTS 10
 
-struct pdata
-{
-  unsigned char ext_addr_byte; // Record ext-addr byte set in the target device (if used)
-  int retry_attempts; // Number of connection attempts provided by the user
-};
-
-#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
+static int stk500_getparm(const PROGRAMMER *pgm, unsigned parm, unsigned *value);
+static int stk500_setparm(const PROGRAMMER *pgm, unsigned parm, unsigned value);
+static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p);
 
 
-static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value);
-static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value);
-static void stk500_print_parms1(PROGRAMMER * pgm, const char * p);
-
-
-static int stk500_send(PROGRAMMER * pgm, unsigned char * buf, size_t len)
-{
+static int stk500_send(const PROGRAMMER *pgm, unsigned char *buf, size_t len) {
   return serial_send(&pgm->fd, buf, len);
 }
 
 
-static int stk500_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
-{
+static int stk500_recv(const PROGRAMMER *pgm, unsigned char *buf, size_t len) {
   int rv;
 
   rv = serial_recv(&pgm->fd, buf, len);
@@ -79,14 +68,12 @@ static int stk500_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
 }
 
 
-int stk500_drain(PROGRAMMER * pgm, int display)
-{
+int stk500_drain(const PROGRAMMER *pgm, int display) {
   return serial_drain(&pgm->fd, display);
 }
 
 
-int stk500_getsync(PROGRAMMER * pgm)
-{
+int stk500_getsync(const PROGRAMMER *pgm) {
   unsigned char buf[32], resp[32];
   int attempt;
   int max_sync_attempts;
@@ -148,7 +135,7 @@ int stk500_getsync(PROGRAMMER * pgm)
  * transmit an AVR device command and return the results; 'cmd' and
  * 'res' must point to at least a 4 byte data buffer
  */
-static int stk500_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
+static int stk500_cmd(const PROGRAMMER *pgm, const unsigned char *cmd,
                       unsigned char *res)
 {
   unsigned char buf[32];
@@ -190,8 +177,7 @@ static int stk500_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
 /*
  * issue the 'chip erase' command to the AVR device
  */
-static int stk500_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+static int stk500_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char cmd[4];
   unsigned char res[4];
 
@@ -224,8 +210,7 @@ static int stk500_chip_erase(PROGRAMMER * pgm, AVRPART * p)
 /*
  * issue the 'program enable' command to the AVR device
  */
-static int stk500_program_enable(PROGRAMMER * pgm, AVRPART * p)
-{
+static int stk500_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char buf[16];
   int tries=0;
 
@@ -283,7 +268,7 @@ static int stk500_program_enable(PROGRAMMER * pgm, AVRPART * p)
 
 
 
-static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,
+static int stk500_set_extended_parms(const PROGRAMMER *pgm, int n,
                                      unsigned char * cmd)
 {
   unsigned char buf[16];
@@ -351,8 +336,7 @@ static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,
  * Crossbow MIB510 initialization and shutdown.  Use cmd = 1 to
  * initialize, cmd = 0 to close.
  */
-static int mib510_isp(PROGRAMMER * pgm, unsigned char cmd)
-{
+static int mib510_isp(const PROGRAMMER *pgm, unsigned char cmd) {
   unsigned char buf[9];
   int tries = 0;
 
@@ -420,8 +404,7 @@ static int mib510_isp(PROGRAMMER * pgm, unsigned char cmd)
 /*
  * initialize the AVR device and prepare it to accept commands
  */
-static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
-{
+static int stk500_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char buf[32];
   AVRMEM * m;
   int tries;
@@ -609,7 +592,7 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
   return pgm->program_enable(pgm, p);
 }
 
-static int stk500_parseextparms(PROGRAMMER * pgm, LISTID extparms)
+static int stk500_parseextparms(const PROGRAMMER *pgm, const LISTID extparms)
  {
    LNODEID ln;
    const char *extended_param;
@@ -634,8 +617,7 @@ static int stk500_parseextparms(PROGRAMMER * pgm, LISTID extparms)
    return rv;
  }
 
-static void stk500_disable(PROGRAMMER * pgm)
-{
+static void stk500_disable(const PROGRAMMER *pgm) {
   unsigned char buf[16];
   int tries=0;
 
@@ -683,14 +665,12 @@ static void stk500_disable(PROGRAMMER * pgm)
   return;
 }
 
-static void stk500_enable(PROGRAMMER * pgm)
-{
+static void stk500_enable(PROGRAMMER *pgm, const AVRPART *p) {
   return;
 }
 
 
-static int stk500_open(PROGRAMMER * pgm, char * port)
-{
+static int stk500_open(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo;
   strcpy(pgm->port, port);
   pinfo.serialinfo.baud = pgm->baudrate? pgm->baudrate: 115200;
@@ -727,8 +707,7 @@ static void stk500_close(PROGRAMMER * pgm)
 }
 
 
-static int stk500_loadaddr(PROGRAMMER * pgm, AVRMEM * mem, unsigned int addr)
-{
+static int stk500_loadaddr(const PROGRAMMER *pgm, const AVRMEM *mem, const unsigned int addr) {
   unsigned char buf[16];
   int tries;
   unsigned char ext_byte;
@@ -791,7 +770,7 @@ static int stk500_loadaddr(PROGRAMMER * pgm, AVRMEM * mem, unsigned int addr)
 }
 
 
-static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int stk500_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                               unsigned int page_size,
                               unsigned int addr, unsigned int n_bytes)
 {
@@ -887,7 +866,7 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return n_bytes;
 }
 
-static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int stk500_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                              unsigned int page_size,
                              unsigned int addr, unsigned int n_bytes)
 {
@@ -984,8 +963,7 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 }
 
 
-static int stk500_set_vtarget(PROGRAMMER * pgm, double v)
-{
+static int stk500_set_vtarget(const PROGRAMMER *pgm, double v) {
   unsigned uaref, utarg;
 
   utarg = (unsigned)((v + 0.049) * 10);
@@ -1007,7 +985,7 @@ static int stk500_set_vtarget(PROGRAMMER * pgm, double v)
 }
 
 
-static int stk500_set_varef(PROGRAMMER * pgm, unsigned int chan /* unused */,
+static int stk500_set_varef(const PROGRAMMER *pgm, unsigned int chan /* unused */,
                             double v)
 {
   unsigned uaref, utarg;
@@ -1030,8 +1008,7 @@ static int stk500_set_varef(PROGRAMMER * pgm, unsigned int chan /* unused */,
 }
 
 
-static int stk500_set_fosc(PROGRAMMER * pgm, double v)
-{
+static int stk500_set_fosc(const PROGRAMMER *pgm, double v) {
   unsigned prescale, cmatch, fosc;
   static unsigned ps[] = {
     1, 8, 32, 64, 128, 256, 1024
@@ -1087,8 +1064,7 @@ static int stk500_set_fosc(PROGRAMMER * pgm, double v)
    For small duration values, the actual SCK width is larger than
    expected.  As the duration value increases, the SCK width error
    diminishes. */
-static int stk500_set_sck_period(PROGRAMMER * pgm, double v)
-{
+static int stk500_set_sck_period(const PROGRAMMER *pgm, double v) {
   int dur;
   double min, max;
 
@@ -1110,8 +1086,7 @@ static int stk500_set_sck_period(PROGRAMMER * pgm, double v)
 }
 
 
-static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
-{
+static int stk500_getparm(const PROGRAMMER *pgm, unsigned parm, unsigned *value) {
   unsigned char buf[16];
   unsigned v;
   int tries = 0;
@@ -1167,8 +1142,7 @@ static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
 }
 
   
-static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value)
-{
+static int stk500_setparm(const PROGRAMMER *pgm, unsigned parm, unsigned value) {
   unsigned char buf[16];
   int tries = 0;
 
@@ -1222,8 +1196,7 @@ static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value)
 }
 
   
-static void stk500_display(PROGRAMMER * pgm, const char * p)
-{
+static void stk500_display(const PROGRAMMER *pgm, const char *p) {
   unsigned maj, min, hdw, topcard;
 
   stk500_getparm(pgm, Parm_STK_HW_VER, &hdw);
@@ -1254,8 +1227,7 @@ static void stk500_display(PROGRAMMER * pgm, const char * p)
 }
 
 
-static void stk500_print_parms1(PROGRAMMER * pgm, const char * p)
-{
+static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p) {
   unsigned vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration;
 
   stk500_getparm(pgm, Parm_STK_VTARGET, &vtarget);
@@ -1301,8 +1273,7 @@ static void stk500_print_parms1(PROGRAMMER * pgm, const char * p)
 }
 
 
-static void stk500_print_parms(PROGRAMMER * pgm)
-{
+static void stk500_print_parms(const PROGRAMMER *pgm) {
   stk500_print_parms1(pgm, "");
 }
 
@@ -1314,8 +1285,8 @@ static void stk500_setup(PROGRAMMER * pgm)
     return;
   }
   memset(pgm->cookie, 0, sizeof(struct pdata));
-  PDATA(pgm)->ext_addr_byte = 0xff; /* Ensures it is programmed before
-				     * first memory address */
+  PDATA(pgm)->ext_addr_byte = 0xff;
+  PDATA(pgm)->xbeeResetPin = XBEE_DEFAULT_RESET_PIN;
 }
 
 static void stk500_teardown(PROGRAMMER * pgm)
@@ -1325,8 +1296,7 @@ static void stk500_teardown(PROGRAMMER * pgm)
 
 const char stk500_desc[] = "Atmel STK500 Version 1.x firmware";
 
-void stk500_initpgm(PROGRAMMER * pgm)
-{
+void stk500_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "STK500");
 
   /*
diff --git a/src/stk500.h b/src/stk500.h
index d0bce452..3d28b064 100644
--- a/src/stk500.h
+++ b/src/stk500.h
@@ -26,16 +26,26 @@ extern "C" {
 #endif
 
 extern const char stk500_desc[];
-void stk500_initpgm (PROGRAMMER * pgm);
+void stk500_initpgm(PROGRAMMER *pgm);
 
 /* used by arduino.c to avoid duplicate code */
-int stk500_getsync(PROGRAMMER * pgm);
-int stk500_drain(PROGRAMMER * pgm, int display);
+int stk500_getsync(const PROGRAMMER *pgm);
+int stk500_drain(const PROGRAMMER *pgm, int display);
 
 #ifdef __cplusplus
 }
 #endif
 
+#include "xbee.h"
+
+struct pdata {
+  unsigned char ext_addr_byte;  // Record ext-addr byte set in the target device (if used)
+  int retry_attempts;           // Number of connection attempts provided by the user
+  int xbeeResetPin;             // Piggy back variable used by xbee programmmer
+};
+
+#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
+
 #endif
 
 
diff --git a/src/stk500generic.c b/src/stk500generic.c
index 9c1ea403..76031f7d 100644
--- a/src/stk500generic.c
+++ b/src/stk500generic.c
@@ -38,8 +38,7 @@
 #include "stk500.h"
 #include "stk500v2.h"
 
-static int stk500generic_open(PROGRAMMER * pgm, char * port)
-{
+static int stk500generic_open(PROGRAMMER *pgm, const char *port) {
   stk500_initpgm(pgm);
   if (pgm->open(pgm, port) >= 0)
     {
@@ -80,8 +79,7 @@ static void stk500generic_teardown(PROGRAMMER * pgm)
 
 const char stk500generic_desc[] = "Atmel STK500, autodetect firmware version";
 
-void stk500generic_initpgm(PROGRAMMER * pgm)
-{
+void stk500generic_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "STK500GENERIC");
 
   pgm->open           = stk500generic_open;
diff --git a/src/stk500generic.h b/src/stk500generic.h
index 0c059012..c970ac42 100644
--- a/src/stk500generic.h
+++ b/src/stk500generic.h
@@ -22,7 +22,7 @@
 #define stk500generic_h__
 
 extern const char stk500generic_desc[];
-void stk500generic_initpgm (PROGRAMMER * pgm);
+void stk500generic_initpgm(PROGRAMMER *pgm);
 
 #endif
 
diff --git a/src/stk500v2.c b/src/stk500v2.c
index 8f16ae41..bdff4612 100644
--- a/src/stk500v2.c
+++ b/src/stk500v2.c
@@ -257,29 +257,29 @@ static const struct carddata socket_cards[] =
   { 0xF1, "STK600-DIP" },
 };
 
-static int stk500v2_getparm(PROGRAMMER * pgm, unsigned char parm, unsigned char * value);
-static int stk500v2_setparm(PROGRAMMER * pgm, unsigned char parm, unsigned char value);
-static int stk500v2_getparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int * value);
-static int stk500v2_setparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int value);
-static int stk500v2_setparm_real(PROGRAMMER * pgm, unsigned char parm, unsigned char value);
-static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p);
-static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int stk500v2_getparm(const PROGRAMMER *pgm, unsigned char parm, unsigned char *value);
+static int stk500v2_setparm(const PROGRAMMER *pgm, unsigned char parm, unsigned char value);
+static int stk500v2_getparm2(const PROGRAMMER *pgm, unsigned char parm, unsigned int *value);
+static int stk500v2_setparm2(const PROGRAMMER *pgm, unsigned char parm, unsigned int value);
+static int stk500v2_setparm_real(const PROGRAMMER *pgm, unsigned char parm, unsigned char value);
+static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p);
+static int stk500v2_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                unsigned int page_size,
                                unsigned int addr, unsigned int n_bytes);
-static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int stk500v2_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                 unsigned int page_size,
                                 unsigned int addr, unsigned int n_bytes);
 
 static unsigned int stk500v2_mode_for_pagesize(unsigned int pagesize);
 
-static double stk500v2_sck_to_us(PROGRAMMER * pgm, unsigned char dur);
-static int stk500v2_set_sck_period_mk2(PROGRAMMER * pgm, double v);
+static double stk500v2_sck_to_us(const PROGRAMMER *pgm, unsigned char dur);
+static int stk500v2_set_sck_period_mk2(const PROGRAMMER *pgm, double v);
 
-static int stk600_set_sck_period(PROGRAMMER * pgm, double v);
+static int stk600_set_sck_period(const PROGRAMMER *pgm, double v);
 
-static void stk600_setup_xprog(PROGRAMMER * pgm);
-static void stk600_setup_isp(PROGRAMMER * pgm);
-static int stk600_xprog_program_enable(PROGRAMMER * pgm, AVRPART * p);
+static void stk600_setup_xprog(PROGRAMMER *pgm);
+static void stk600_setup_isp(PROGRAMMER *pgm);
+static int stk600_xprog_program_enable(const PROGRAMMER *pgm, const AVRPART *p);
 
 void stk500v2_setup(PROGRAMMER * pgm)
 {
@@ -380,8 +380,7 @@ b2_to_u16(unsigned char *b)
   return l;
 }
 
-static int stk500v2_send_mk2(PROGRAMMER * pgm, unsigned char * data, size_t len)
-{
+static int stk500v2_send_mk2(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
   if (serial_send(&pgm->fd, data, len) != 0) {
     avrdude_message(MSG_INFO, "%s: stk500_send_mk2(): failed to send command to serial port\n",progname);
     return -1;
@@ -405,12 +404,10 @@ static unsigned short get_jtagisp_return_size(unsigned char cmd)
  * response buffer prepended, and replies with RSP_SPI_DATA
  * if successful.
  */
-static int stk500v2_jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
-{
+static int stk500v2_jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
   unsigned char *cmdbuf;
   int rv;
   unsigned short sz;
-  void *mycookie;
 
   sz = get_jtagisp_return_size(data[0]);
   if (sz == 0) {
@@ -438,15 +435,15 @@ static int stk500v2_jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t
             progname);
     exit(1);
   }
-  mycookie = pgm->cookie;
-  pgm->cookie = PDATA(pgm)->chained_pdata;
+  PROGRAMMER *pgmcp = pgm_dup(pgm);
+  pgmcp->cookie = PDATA(pgm)->chained_pdata;
   cmdbuf[0] = CMND_ISP_PACKET;
   cmdbuf[1] = sz & 0xff;
   cmdbuf[2] = (sz >> 8) & 0xff;
   memcpy(cmdbuf + 3, data, len);
-  rv = jtagmkII_send(pgm, cmdbuf, len + 3);
+  rv = jtagmkII_send(pgmcp, cmdbuf, len + 3);
   free(cmdbuf);
-  pgm->cookie = mycookie;
+  pgm_free(pgmcp);
 
   return rv;
 }
@@ -454,30 +451,28 @@ static int stk500v2_jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t
 /*
  * Send the data as a JTAGICE3 encapsulated ISP packet.
  */
-static int stk500v2_jtag3_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
-{
+static int stk500v2_jtag3_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
   unsigned char *cmdbuf;
   int rv;
-  void *mycookie;
 
   if ((cmdbuf = malloc(len + 1)) == NULL) {
     avrdude_message(MSG_INFO, "%s: out of memory for command packet\n",
             progname);
     exit(1);
   }
-  mycookie = pgm->cookie;
-  pgm->cookie = PDATA(pgm)->chained_pdata;
+
+  PROGRAMMER *pgmcp = pgm_dup(pgm);
+  pgmcp->cookie = PDATA(pgm)->chained_pdata;
   cmdbuf[0] = SCOPE_AVR_ISP;
   memcpy(cmdbuf + 1, data, len);
-  rv = jtag3_send(pgm, cmdbuf, len + 1);
+  rv = jtag3_send(pgmcp, cmdbuf, len + 1);
   free(cmdbuf);
-  pgm->cookie = mycookie;
+  pgm_free(pgmcp);
 
   return rv;
 }
 
-static int stk500v2_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
-{
+static int stk500v2_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
   unsigned char buf[275 + 6];		// max MESSAGE_BODY of 275 bytes, 6 bytes overhead
 
   if (PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII ||
@@ -514,12 +509,11 @@ static int stk500v2_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
 }
 
 
-int stk500v2_drain(PROGRAMMER * pgm, int display)
-{
+int stk500v2_drain(const PROGRAMMER *pgm, int display) {
   return serial_drain(&pgm->fd, display);
 }
 
-static int stk500v2_recv_mk2(PROGRAMMER * pgm, unsigned char *msg,
+static int stk500v2_recv_mk2(const PROGRAMMER *pgm, unsigned char *msg,
 			     size_t maxsize)
 {
   int rv;
@@ -533,17 +527,16 @@ static int stk500v2_recv_mk2(PROGRAMMER * pgm, unsigned char *msg,
   return rv;
 }
 
-static int stk500v2_jtagmkII_recv(PROGRAMMER * pgm, unsigned char *msg,
+static int stk500v2_jtagmkII_recv(const PROGRAMMER *pgm, unsigned char *msg,
                                   size_t maxsize)
 {
   int rv;
   unsigned char *jtagmsg;
-  void *mycookie;
 
-  mycookie = pgm->cookie;
-  pgm->cookie = PDATA(pgm)->chained_pdata;
-  rv = jtagmkII_recv(pgm, &jtagmsg);
-  pgm->cookie = mycookie;
+  PROGRAMMER *pgmcp = pgm_dup(pgm);
+  pgmcp->cookie = PDATA(pgm)->chained_pdata;
+  rv = jtagmkII_recv(pgmcp, &jtagmsg);
+  pgm_free(pgmcp);
   if (rv <= 0) {
     avrdude_message(MSG_INFO, "%s: stk500v2_jtagmkII_recv(): error in jtagmkII_recv()\n",
             progname);
@@ -575,17 +568,17 @@ static int stk500v2_jtagmkII_recv(PROGRAMMER * pgm, unsigned char *msg,
   return rv;
 }
 
-static int stk500v2_jtag3_recv(PROGRAMMER * pgm, unsigned char *msg,
+static int stk500v2_jtag3_recv(const PROGRAMMER *pgm, unsigned char *msg,
 			       size_t maxsize)
 {
   int rv;
   unsigned char *jtagmsg;
-  void *mycookie;
 
-  mycookie = pgm->cookie;
-  pgm->cookie = PDATA(pgm)->chained_pdata;
-  rv = jtag3_recv(pgm, &jtagmsg);
-  pgm->cookie = mycookie;
+  PROGRAMMER *pgmcp = pgm_dup(pgm);
+  pgmcp->cookie = PDATA(pgm)->chained_pdata;
+  rv = jtag3_recv(pgmcp, &jtagmsg);
+  pgm_free(pgmcp);
+
   if (rv <= 0) {
     avrdude_message(MSG_INFO, "%s: stk500v2_jtag3_recv(): error in jtagmkII_recv()\n",
             progname);
@@ -611,7 +604,7 @@ static int stk500v2_jtag3_recv(PROGRAMMER * pgm, unsigned char *msg,
   return rv;
 }
 
-static int stk500v2_recv(PROGRAMMER * pgm, unsigned char *msg, size_t maxsize) {
+static int stk500v2_recv(const PROGRAMMER *pgm, unsigned char *msg, size_t maxsize) {
   enum states { sINIT, sSTART, sSEQNUM, sSIZE1, sSIZE2, sTOKEN, sDATA, sCSUM, sDONE }  state = sSTART;
   unsigned int msglen = 0;
   unsigned int curlen = 0;
@@ -731,7 +724,7 @@ static int stk500v2_recv(PROGRAMMER * pgm, unsigned char *msg, size_t maxsize) {
 
 
 
-int stk500v2_getsync(PROGRAMMER * pgm) {
+int stk500v2_getsync(const PROGRAMMER *pgm) {
   int tries = 0;
   unsigned char buf[1], resp[32];
   int status;
@@ -810,7 +803,7 @@ retry:
   return 0;
 }
 
-static int stk500v2_command(PROGRAMMER * pgm, unsigned char * buf,
+static int stk500v2_command(const PROGRAMMER *pgm, unsigned char *buf,
                             size_t len, size_t maxlen) {
   int tries = 0;
   int status;
@@ -923,7 +916,7 @@ retry:
   return 0;
 }
 
-static int stk500v2_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
+static int stk500v2_cmd(const PROGRAMMER *pgm, const unsigned char *cmd,
                         unsigned char *res)
 {
   unsigned char buf[8];
@@ -960,7 +953,7 @@ static int stk500v2_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
 }
 
 
-static int stk500v2_jtag3_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
+static int stk500v2_jtag3_cmd(const PROGRAMMER *pgm, const unsigned char *cmd,
 			      unsigned char *res)
 {
   avrdude_message(MSG_INFO, "%s: stk500v2_jtag3_cmd(): Not available in JTAGICE3\n",
@@ -973,8 +966,7 @@ static int stk500v2_jtag3_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
 /*
  * issue the 'chip erase' command to the AVR device
  */
-static int stk500v2_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+static int stk500v2_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
   int result;
   unsigned char buf[16];
 
@@ -1003,8 +995,7 @@ static int stk500v2_chip_erase(PROGRAMMER * pgm, AVRPART * p)
 /*
  * issue the 'chip erase' command to the AVR device, generic HV mode
  */
-static int stk500hv_chip_erase(PROGRAMMER * pgm, AVRPART * p, enum hvmode mode)
-{
+static int stk500hv_chip_erase(const PROGRAMMER *pgm, const AVRPART *p, enum hvmode mode) {
   int result;
   unsigned char buf[3];
 
@@ -1031,16 +1022,14 @@ static int stk500hv_chip_erase(PROGRAMMER * pgm, AVRPART * p, enum hvmode mode)
 /*
  * issue the 'chip erase' command to the AVR device, parallel mode
  */
-static int stk500pp_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+static int stk500pp_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
   return stk500hv_chip_erase(pgm, p, PPMODE);
 }
 
 /*
  * issue the 'chip erase' command to the AVR device, HVSP mode
  */
-static int stk500hvsp_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+static int stk500hvsp_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
   return stk500hv_chip_erase(pgm, p, HVSPMODE);
 }
 
@@ -1091,8 +1080,7 @@ stk500v2_translate_conn_status(unsigned char status, char *msg)
 /*
  * issue the 'program enable' command to the AVR device
  */
-static int stk500v2_program_enable(PROGRAMMER * pgm, AVRPART * p)
-{
+static int stk500v2_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char buf[16];
   char msg[100];             /* see remarks above about size needed */
   int rv, tries;
@@ -1144,19 +1132,18 @@ retry:
     case PGMTYPE_JTAGICE3:
         if (buf[1] == STATUS_CMD_FAILED &&
             (p->flags & AVRPART_HAS_DW) != 0) {
-            void *mycookie;
             unsigned char cmd[4], *resp;
 
             /* Try debugWIRE, and MONCON_DISABLE */
             avrdude_message(MSG_NOTICE2, "%s: No response in ISP mode, trying debugWIRE\n",
                                 progname);
 
-            mycookie = pgm->cookie;
-            pgm->cookie = PDATA(pgm)->chained_pdata;
+            PROGRAMMER *pgmcp = pgm_dup(pgm);
+            pgmcp->cookie = PDATA(pgm)->chained_pdata;
 
             cmd[0] = PARM3_CONN_DW;
-            if (jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, cmd, 1) < 0) {
-                pgm->cookie = mycookie;
+            if (jtag3_setparm(pgmcp, SCOPE_AVR, 1, PARM3_CONNECTION, cmd, 1) < 0) {
+                pgm_free(pgmcp);
                 break;
             }
 
@@ -1164,19 +1151,19 @@ retry:
 
             cmd[1] = CMD3_SIGN_ON;
             cmd[2] = cmd[3] = 0;
-            if (jtag3_command(pgm, cmd, 4, &resp, "AVR sign-on") >= 0) {
+            if (jtag3_command(pgmcp, cmd, 4, &resp, "AVR sign-on") >= 0) {
                 free(resp);
 
                 cmd[1] = CMD3_START_DW_DEBUG;
-                if (jtag3_command(pgm, cmd, 4, &resp, "start DW debug") >= 0) {
+                if (jtag3_command(pgmcp, cmd, 4, &resp, "start DW debug") >= 0) {
                     free(resp);
 
                     cmd[1] = CMD3_MONCON_DISABLE;
-                    if (jtag3_command(pgm, cmd, 3, &resp, "MonCon disable") >= 0)
+                    if (jtag3_command(pgmcp, cmd, 3, &resp, "MonCon disable") >= 0)
                         free(resp);
                 }
             }
-            pgm->cookie = mycookie;
+            pgm_free(pgmcp);
             if (tries++ > 3) {
                 avrdude_message(MSG_INFO, "%s: Failed to return from debugWIRE to ISP.\n",
                                 progname);
@@ -1201,8 +1188,7 @@ retry:
 /*
  * issue the 'program enable' command to the AVR device, parallel mode
  */
-static int stk500pp_program_enable(PROGRAMMER * pgm, AVRPART * p)
-{
+static int stk500pp_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char buf[16];
 
   PDATA(pgm)->lastpart = p;
@@ -1222,8 +1208,7 @@ static int stk500pp_program_enable(PROGRAMMER * pgm, AVRPART * p)
 /*
  * issue the 'program enable' command to the AVR device, HVSP mode
  */
-static int stk500hvsp_program_enable(PROGRAMMER * pgm, AVRPART * p)
-{
+static int stk500hvsp_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char buf[16];
 
   PDATA(pgm)->lastpart = p;
@@ -1247,8 +1232,7 @@ static int stk500hvsp_program_enable(PROGRAMMER * pgm, AVRPART * p)
 /*
  * initialize the AVR device and prepare it to accept commands
  */
-static int stk500v2_initialize(PROGRAMMER * pgm, AVRPART * p)
-{
+static int stk500v2_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
   LNODEID ln;
   AVRMEM * m;
 
@@ -1274,9 +1258,9 @@ static int stk500v2_initialize(PROGRAMMER * pgm, AVRPART * p)
         PDATA(pgm)->boot_start = bootmem->offset - flashmem->offset;
       }
     }
-    stk600_setup_xprog(pgm);
+    // stk600_setup_xprog(pgm); [moved to pgm->enable()]
   } else {
-    stk600_setup_isp(pgm);
+    // stk600_setup_isp(pgm); [moved to pgm->enable()]
   }
 
   /*
@@ -1331,12 +1315,10 @@ static int stk500v2_initialize(PROGRAMMER * pgm, AVRPART * p)
 /*
  * initialize the AVR device and prepare it to accept commands
  */
-static int stk500v2_jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
-{
+static int stk500v2_jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char parm[4], *resp;
   LNODEID ln;
   AVRMEM * m;
-  void *mycookie;
 
   if ((p->flags & AVRPART_HAS_PDI) ||
       (p->flags & AVRPART_HAS_TPI)) {
@@ -1345,38 +1327,38 @@ static int stk500v2_jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
     return -1;
   }
 
-  mycookie = pgm->cookie;
-  pgm->cookie = PDATA(pgm)->chained_pdata;
+  PROGRAMMER *pgmcp = pgm_dup(pgm);
+  pgmcp->cookie = PDATA(pgm)->chained_pdata;
 
   if (p->flags & AVRPART_HAS_DW)
     parm[0] = PARM3_ARCH_TINY;
   else
     parm[0] = PARM3_ARCH_MEGA;
-  if (jtag3_setparm(pgm, SCOPE_AVR, 0, PARM3_ARCH, parm, 1) < 0) {
-    pgm->cookie = mycookie;
+  if (jtag3_setparm(pgmcp, SCOPE_AVR, 0, PARM3_ARCH, parm, 1) < 0) {
+    pgm_free(pgmcp);
     return -1;
   }
 
   parm[0] = PARM3_SESS_PROGRAMMING;
-  if (jtag3_setparm(pgm, SCOPE_AVR, 0, PARM3_SESS_PURPOSE, parm, 1) < 0) {
-    pgm->cookie = mycookie;
+  if (jtag3_setparm(pgmcp, SCOPE_AVR, 0, PARM3_SESS_PURPOSE, parm, 1) < 0) {
+    pgm_free(pgmcp);
     return -1;
   }
 
   parm[0] = PARM3_CONN_ISP;
-  if (jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, parm, 1) < 0) {
-    pgm->cookie = mycookie;
+  if (jtag3_setparm(pgmcp, SCOPE_AVR, 1, PARM3_CONNECTION, parm, 1) < 0) {
+    pgm_free(pgmcp);
     return -1;
   }
 
   parm[0] = SCOPE_AVR_ISP;
   parm[1] = 0x1e;
-  jtag3_send(pgm, parm, 2);
+  jtag3_send(pgmcp, parm, 2);
 
-  if (jtag3_recv(pgm, &resp) > 0)
+  if (jtag3_recv(pgmcp, &resp) > 0)
     free(resp);
 
-  pgm->cookie = mycookie;
+  free(pgmcp);
 
   /*
    * Examine the avrpart's memory definitions, and initialize the page
@@ -1421,8 +1403,7 @@ static int stk500v2_jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
 /*
  * initialize the AVR device and prepare it to accept commands, generic HV mode
  */
-static int stk500hv_initialize(PROGRAMMER * pgm, AVRPART * p, enum hvmode mode)
-{
+static int stk500hv_initialize(const PROGRAMMER *pgm, const AVRPART *p, enum hvmode mode) {
   unsigned char buf[CTL_STACK_SIZE + 1];
   int result;
   LNODEID ln;
@@ -1491,21 +1472,18 @@ static int stk500hv_initialize(PROGRAMMER * pgm, AVRPART * p, enum hvmode mode)
 /*
  * initialize the AVR device and prepare it to accept commands, PP mode
  */
-static int stk500pp_initialize(PROGRAMMER * pgm, AVRPART * p)
-{
+static int stk500pp_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
   return stk500hv_initialize(pgm, p, PPMODE);
 }
 
 /*
  * initialize the AVR device and prepare it to accept commands, HVSP mode
  */
-static int stk500hvsp_initialize(PROGRAMMER * pgm, AVRPART * p)
-{
+static int stk500hvsp_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
   return stk500hv_initialize(pgm, p, HVSPMODE);
 }
 
-static void stk500v2_jtag3_disable(PROGRAMMER * pgm)
-{
+static void stk500v2_jtag3_disable(const PROGRAMMER *pgm) {
   unsigned char buf[16];
   int result;
 
@@ -1528,8 +1506,7 @@ static void stk500v2_jtag3_disable(PROGRAMMER * pgm)
   return;
 }
 
-static void stk500v2_disable(PROGRAMMER * pgm)
-{
+static void stk500v2_disable(const PROGRAMMER *pgm) {
   unsigned char buf[16];
   int result;
 
@@ -1550,8 +1527,7 @@ static void stk500v2_disable(PROGRAMMER * pgm)
 /*
  * Leave programming mode, generic HV mode
  */
-static void stk500hv_disable(PROGRAMMER * pgm, enum hvmode mode)
-{
+static void stk500hv_disable(const PROGRAMMER *pgm, enum hvmode mode) {
   unsigned char buf[16];
   int result;
 
@@ -1581,27 +1557,35 @@ static void stk500hv_disable(PROGRAMMER * pgm, enum hvmode mode)
 /*
  * Leave programming mode, PP mode
  */
-static void stk500pp_disable(PROGRAMMER * pgm)
-{
+static void stk500pp_disable(const PROGRAMMER *pgm) {
   stk500hv_disable(pgm, PPMODE);
 }
 
 /*
  * Leave programming mode, HVSP mode
  */
-static void stk500hvsp_disable(PROGRAMMER * pgm)
-{
+static void stk500hvsp_disable(const PROGRAMMER *pgm) {
   stk500hv_disable(pgm, HVSPMODE);
 }
 
-static void stk500v2_enable(PROGRAMMER * pgm)
-{
+static void stk500v2_enable(PROGRAMMER *pgm, const AVRPART *p) {
+  // Previously stk500v2_initialize() set up pgm
+  if(pgm->initialize == stk500v2_initialize) {
+    if((PDATA(pgm)->pgmtype == PGMTYPE_STK600 ||
+      PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII ||
+      PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) != 0
+      && (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_TPI)) != 0) {
+      stk600_setup_xprog(pgm);
+    } else {
+      stk600_setup_isp(pgm);
+    }
+  }
+
   return;
 }
 
 
-static int stk500v2_open(PROGRAMMER * pgm, char * port)
-{
+static int stk500v2_open(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo = { .serialinfo.baud = 115200, .serialinfo.cflags = SERIAL_8N1 };
 
   DEBUG("STK500V2: stk500v2_open()\n");
@@ -1668,8 +1652,7 @@ static int stk500v2_open(PROGRAMMER * pgm, char * port)
 }
 
 
-static int stk600_open(PROGRAMMER * pgm, char * port)
-{
+static int stk600_open(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo = { .serialinfo.baud = 115200, .serialinfo.cflags = SERIAL_8N1 };
 
   DEBUG("STK500V2: stk600_open()\n");
@@ -1726,8 +1709,7 @@ static int stk600_open(PROGRAMMER * pgm, char * port)
 }
 
 
-static void stk500v2_close(PROGRAMMER * pgm)
-{
+static void stk500v2_close(PROGRAMMER *pgm) {
   DEBUG("STK500V2: stk500v2_close()\n");
 
   serial_close(&pgm->fd);
@@ -1735,8 +1717,7 @@ static void stk500v2_close(PROGRAMMER * pgm)
 }
 
 
-static int stk500v2_loadaddr(PROGRAMMER * pgm, unsigned int addr)
-{
+static int stk500v2_loadaddr(const PROGRAMMER *pgm, unsigned int addr) {
   unsigned char buf[16];
   int result;
 
@@ -1763,7 +1744,7 @@ static int stk500v2_loadaddr(PROGRAMMER * pgm, unsigned int addr)
 /*
  * Read a single byte, generic HV mode
  */
-static int stk500hv_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int stk500hv_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 			      unsigned long addr, unsigned char * value,
 			      enum hvmode mode)
 {
@@ -1872,7 +1853,7 @@ static int stk500hv_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 /*
  * Read a single byte, PP mode
  */
-static int stk500pp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int stk500pp_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 			      unsigned long addr, unsigned char * value)
 {
   return stk500hv_read_byte(pgm, p, mem, addr, value, PPMODE);
@@ -1881,7 +1862,7 @@ static int stk500pp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 /*
  * Read a single byte, HVSP mode
  */
-static int stk500hvsp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int stk500hvsp_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 				unsigned long addr, unsigned char * value)
 {
   return stk500hv_read_byte(pgm, p, mem, addr, value, HVSPMODE);
@@ -1893,7 +1874,7 @@ static int stk500hvsp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
  * By now, only used on the JTAGICE3 which does not implement the
  * CMD_SPI_MULTI SPI passthrough command.
  */
-static int stk500isp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int stk500isp_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 			       unsigned long addr, unsigned char * value)
 {
   int result, pollidx;
@@ -1991,7 +1972,7 @@ static int stk500isp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 /*
  * Write one byte, generic HV mode
  */
-static int stk500hv_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int stk500hv_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 			       unsigned long addr, unsigned char data,
 			       enum hvmode mode)
 {
@@ -2132,7 +2113,7 @@ static int stk500hv_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 /*
  * Write one byte, PP mode
  */
-static int stk500pp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int stk500pp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 			       unsigned long addr, unsigned char data)
 {
   return stk500hv_write_byte(pgm, p, mem, addr, data, PPMODE);
@@ -2141,7 +2122,7 @@ static int stk500pp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 /*
  * Write one byte, HVSP mode
  */
-static int stk500hvsp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int stk500hvsp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 			       unsigned long addr, unsigned char data)
 {
   return stk500hv_write_byte(pgm, p, mem, addr, data, HVSPMODE);
@@ -2151,7 +2132,7 @@ static int stk500hvsp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 /*
  * Write one byte, ISP mode
  */
-static int stk500isp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int stk500isp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 				unsigned long addr, unsigned char data)
 {
   int result;
@@ -2258,7 +2239,7 @@ static int stk500isp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
   return 0;
 }
 
-static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int stk500v2_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                 unsigned int page_size,
                                 unsigned int addr, unsigned int n_bytes)
 {
@@ -2393,7 +2374,7 @@ static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 /*
  * Write pages of flash/EEPROM, generic HV mode
  */
-static int stk500hv_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int stk500hv_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                 unsigned int page_size,
                                 unsigned int addr, unsigned int n_bytes,
                                 enum hvmode mode)
@@ -2488,7 +2469,7 @@ static int stk500hv_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 /*
  * Write pages of flash/EEPROM, PP mode
  */
-static int stk500pp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int stk500pp_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                 unsigned int page_size,
                                 unsigned int addr, unsigned int n_bytes)
 {
@@ -2498,14 +2479,14 @@ static int stk500pp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 /*
  * Write pages of flash/EEPROM, HVSP mode
  */
-static int stk500hvsp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int stk500hvsp_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                   unsigned int page_size,
                                   unsigned int addr, unsigned int n_bytes)
 {
   return stk500hv_paged_write(pgm, p, m, page_size, addr, n_bytes, HVSPMODE);
 }
 
-static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int stk500v2_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                unsigned int page_size,
                                unsigned int addr, unsigned int n_bytes)
 {
@@ -2600,7 +2581,7 @@ static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 /*
  * Read pages of flash/EEPROM, generic HV mode
  */
-static int stk500hv_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int stk500hv_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                unsigned int page_size,
                                unsigned int addr, unsigned int n_bytes,
                                enum hvmode mode)
@@ -2679,7 +2660,7 @@ static int stk500hv_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 /*
  * Read pages of flash/EEPROM, PP mode
  */
-static int stk500pp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int stk500pp_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                unsigned int page_size,
                                unsigned int addr, unsigned int n_bytes)
 {
@@ -2689,7 +2670,7 @@ static int stk500pp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 /*
  * Read pages of flash/EEPROM, HVSP mode
  */
-static int stk500hvsp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int stk500hvsp_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                  unsigned int page_size,
                                  unsigned int addr, unsigned int n_bytes)
 {
@@ -2697,7 +2678,7 @@ static int stk500hvsp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 }
 
 
-static int stk500v2_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int stk500v2_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                unsigned int addr)
 {
   avrdude_message(MSG_INFO, "%s: stk500v2_page_erase(): this function must never be called\n",
@@ -2705,8 +2686,7 @@ static int stk500v2_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return -1;
 }
 
-static int stk500v2_set_vtarget(PROGRAMMER * pgm, double v)
-{
+static int stk500v2_set_vtarget(const PROGRAMMER *pgm, double v) {
   unsigned char uaref, utarg;
 
   utarg = (unsigned)((v + 0.049) * 10);
@@ -2728,7 +2708,7 @@ static int stk500v2_set_vtarget(PROGRAMMER * pgm, double v)
 }
 
 
-static int stk500v2_set_varef(PROGRAMMER * pgm, unsigned int chan /* unused */,
+static int stk500v2_set_varef(const PROGRAMMER *pgm, unsigned int chan /* unused */,
                               double v)
 {
   unsigned char uaref, utarg;
@@ -2751,8 +2731,7 @@ static int stk500v2_set_varef(PROGRAMMER * pgm, unsigned int chan /* unused */,
 }
 
 
-static int stk500v2_set_fosc(PROGRAMMER * pgm, double v)
-{
+static int stk500v2_set_fosc(const PROGRAMMER *pgm, double v) {
   int fosc;
   unsigned char prescale, cmatch;
   static unsigned ps[] = {
@@ -2825,8 +2804,7 @@ static double avrispmkIIfreqs[] = {
 	65.0, 61.9, 59.0, 56.3, 53.6, 51.1
 };
 
-static int stk500v2_set_sck_period_mk2(PROGRAMMER * pgm, double v)
-{
+static int stk500v2_set_sck_period_mk2(const PROGRAMMER *pgm, double v) {
   size_t i;
 
   for (i = 0; i < sizeof(avrispmkIIfreqs) / sizeof(avrispmkIIfreqs[0]); i++) {
@@ -2879,8 +2857,7 @@ static unsigned int stk500v2_mode_for_pagesize(unsigned int pagesize)
  * uses a different algorithm below), it's probably not worth the
  * hassle.
  */
-static int stk500v2_set_sck_period(PROGRAMMER * pgm, double v)
-{
+static int stk500v2_set_sck_period(const PROGRAMMER *pgm, double v) {
   unsigned int d;
   unsigned char dur;
   double f = 1 / v;
@@ -2902,8 +2879,7 @@ static int stk500v2_set_sck_period(PROGRAMMER * pgm, double v)
   return stk500v2_setparm(pgm, PARAM_SCK_DURATION, dur);
 }
 
-static double stk500v2_sck_to_us(PROGRAMMER * pgm, unsigned char dur)
-{
+static double stk500v2_sck_to_us(const PROGRAMMER *pgm, unsigned char dur) {
   double x;
 
   if (dur == 0)
@@ -2923,8 +2899,7 @@ static double stk500v2_sck_to_us(PROGRAMMER * pgm, unsigned char dur)
 }
 
 
-static int stk600_set_vtarget(PROGRAMMER * pgm, double v)
-{
+static int stk600_set_vtarget(const PROGRAMMER *pgm, double v) {
   unsigned char utarg;
   unsigned int uaref;
   int rv;
@@ -2975,8 +2950,7 @@ static int stk600_set_vtarget(PROGRAMMER * pgm, double v)
 }
 
 
-static int stk600_set_varef(PROGRAMMER * pgm, unsigned int chan, double v)
-{
+static int stk600_set_varef(const PROGRAMMER *pgm, unsigned int chan, double v) {
   unsigned char utarg;
   unsigned int uaref;
 
@@ -3011,8 +2985,7 @@ static int stk600_set_varef(PROGRAMMER * pgm, unsigned int chan, double v)
 }
 
 
-static int stk600_set_fosc(PROGRAMMER * pgm, double v)
-{
+static int stk600_set_fosc(const PROGRAMMER *pgm, double v) {
   unsigned int oct, dac;
 
   oct = 1.443 * log(v / 1039.0);
@@ -3021,8 +2994,7 @@ static int stk600_set_fosc(PROGRAMMER * pgm, double v)
   return stk500v2_setparm2(pgm, PARAM2_CLOCK_CONF, (oct << 12) | (dac << 2));
 }
 
-static int stk600_set_sck_period(PROGRAMMER * pgm, double v)
-{
+static int stk600_set_sck_period(const PROGRAMMER *pgm, double v) {
   unsigned int sck;
 
   sck = ceil((16e6 / (2 * 1.0 / v)) - 1);
@@ -3033,8 +3005,7 @@ static int stk600_set_sck_period(PROGRAMMER * pgm, double v)
   return stk500v2_setparm2(pgm, PARAM2_SCK_DURATION, sck);
 }
 
-static int stk500v2_jtag3_set_sck_period(PROGRAMMER * pgm, double v)
-{
+static int stk500v2_jtag3_set_sck_period(const PROGRAMMER *pgm, double v) {
   unsigned char value[3];
   unsigned int sck;
 
@@ -3056,8 +3027,7 @@ static int stk500v2_jtag3_set_sck_period(PROGRAMMER * pgm, double v)
   return 0;
 }
 
-static int stk500v2_getparm(PROGRAMMER * pgm, unsigned char parm, unsigned char * value)
-{
+static int stk500v2_getparm(const PROGRAMMER *pgm, unsigned char parm, unsigned char *value) {
   unsigned char buf[32];
 
   buf[0] = CMD_GET_PARAMETER;
@@ -3074,8 +3044,7 @@ static int stk500v2_getparm(PROGRAMMER * pgm, unsigned char parm, unsigned char
   return 0;
 }
 
-static int stk500v2_setparm_real(PROGRAMMER * pgm, unsigned char parm, unsigned char value)
-{
+static int stk500v2_setparm_real(const PROGRAMMER *pgm, unsigned char parm, unsigned char value) {
   unsigned char buf[32];
 
   buf[0] = CMD_SET_PARAMETER;
@@ -3091,8 +3060,7 @@ static int stk500v2_setparm_real(PROGRAMMER * pgm, unsigned char parm, unsigned
   return 0;
 }
 
-static int stk500v2_setparm(PROGRAMMER * pgm, unsigned char parm, unsigned char value)
-{
+static int stk500v2_setparm(const PROGRAMMER *pgm, unsigned char parm, unsigned char value) {
   unsigned char current_value = value;
   int res;
 
@@ -3111,8 +3079,7 @@ static int stk500v2_setparm(PROGRAMMER * pgm, unsigned char parm, unsigned char
   return stk500v2_setparm_real(pgm, parm, value);
 }
 
-static int stk500v2_getparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int * value)
-{
+static int stk500v2_getparm2(const PROGRAMMER *pgm, unsigned char parm, unsigned int *value) {
   unsigned char buf[32];
 
   buf[0] = CMD_GET_PARAMETER;
@@ -3129,8 +3096,7 @@ static int stk500v2_getparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int
   return 0;
 }
 
-static int stk500v2_setparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int value)
-{
+static int stk500v2_setparm2(const PROGRAMMER *pgm, unsigned char parm, unsigned int value) {
   unsigned char buf[32];
 
   buf[0] = CMD_SET_PARAMETER;
@@ -3164,8 +3130,7 @@ static const char *stk600_get_cardname(const struct carddata *table,
 }
 
 
-static void stk500v2_display(PROGRAMMER * pgm, const char * p)
-{
+static void stk500v2_display(const PROGRAMMER *pgm, const char *p) {
   unsigned char maj = 0, min = 0, hdw = 0, topcard = 0,
                 maj_s1 = 0, min_s1 = 0, maj_s2 = 0, min_s2 = 0;
   unsigned int rev = 0;
@@ -3245,30 +3210,28 @@ f_to_kHz_MHz(double f, const char **unit)
   return f;
 }
 
-static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p)
-{
+static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) {
   unsigned char vtarget = 0, vadjust = 0, osc_pscale = 0, osc_cmatch = 0, sck_duration =0; //XXX 0 is not correct, check caller
   unsigned int sck_stk600, clock_conf, dac, oct, varef;
   unsigned char vtarget_jtag[4];
   int prescale;
   double f;
   const char *unit;
-  void *mycookie;
 
   memset(vtarget_jtag, 0, sizeof vtarget_jtag);
 
   if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) {
-    mycookie = pgm->cookie;
-    pgm->cookie = PDATA(pgm)->chained_pdata;
-    jtagmkII_getparm(pgm, PAR_OCD_VTARGET, vtarget_jtag);
-    pgm->cookie = mycookie;
+    PROGRAMMER *pgmcp = pgm_dup(pgm);
+    pgmcp->cookie = PDATA(pgm)->chained_pdata;
+    jtagmkII_getparm(pgmcp, PAR_OCD_VTARGET, vtarget_jtag);
+    pgm_free(pgmcp);
     avrdude_message(MSG_INFO, "%sVtarget         : %.1f V\n", p,
 	    b2_to_u16(vtarget_jtag) / 1000.0);
   } else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3) {
-    mycookie = pgm->cookie;
-    pgm->cookie = PDATA(pgm)->chained_pdata;
-    jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, vtarget_jtag, 2);
-    pgm->cookie = mycookie;
+    PROGRAMMER *pgmcp = pgm_dup(pgm);
+    pgmcp->cookie = PDATA(pgm)->chained_pdata;
+    jtag3_getparm(pgmcp, SCOPE_GENERAL, 1, PARM3_VTARGET, vtarget_jtag, 2);
+    pgm_free(pgmcp);
     avrdude_message(MSG_INFO, "%sVtarget         : %.1f V\n", p,
 	    b2_to_u16(vtarget_jtag) / 1000.0);
 
@@ -3356,13 +3319,11 @@ static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p)
 }
 
 
-static void stk500v2_print_parms(PROGRAMMER * pgm)
-{
+static void stk500v2_print_parms(const PROGRAMMER *pgm) {
   stk500v2_print_parms1(pgm, "");
 }
 
-static int stk500v2_perform_osccal(PROGRAMMER * pgm)
-{
+static int stk500v2_perform_osccal(const PROGRAMMER *pgm) {
   unsigned char buf[32];
   int rv;
 
@@ -3388,8 +3349,7 @@ static int stk500v2_perform_osccal(PROGRAMMER * pgm)
 /*
  * Open a JTAG ICE mkII in ISP mode.
  */
-static int stk500v2_jtagmkII_open(PROGRAMMER * pgm, char * port)
-{
+static int stk500v2_jtagmkII_open(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo;
   void *mycookie;
   int rv;
@@ -3501,8 +3461,7 @@ static void stk500v2_jtag3_close(PROGRAMMER * pgm)
 /*
  * Open an AVR Dragon in ISP mode.
  */
-static int stk500v2_dragon_isp_open(PROGRAMMER * pgm, char * port)
-{
+static int stk500v2_dragon_isp_open(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo;
   void *mycookie;
 
@@ -3580,10 +3539,8 @@ static int stk500v2_dragon_isp_open(PROGRAMMER * pgm, char * port)
 /*
  * Open an AVR Dragon in HV mode (HVSP or parallel).
  */
-static int stk500v2_dragon_hv_open(PROGRAMMER * pgm, char * port)
-{
+static int stk500v2_dragon_hv_open(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo;
-  void *mycookie;
 
   avrdude_message(MSG_NOTICE2, "%s: stk500v2_dragon_hv_open()\n", progname);
 
@@ -3628,16 +3585,15 @@ static int stk500v2_dragon_hv_open(PROGRAMMER * pgm, char * port)
    */
   stk500v2_drain(pgm, 0);
 
-  mycookie = pgm->cookie;
-  pgm->cookie = PDATA(pgm)->chained_pdata;
-  if (jtagmkII_getsync(pgm, EMULATOR_MODE_HV) != 0) {
+  PROGRAMMER *pgmcp = pgm_dup(pgm);
+  pgmcp->cookie = PDATA(pgm)->chained_pdata;
+  if (jtagmkII_getsync(pgmcp, EMULATOR_MODE_HV) != 0) {
     avrdude_message(MSG_INFO, "%s: failed to sync with the AVR Dragon in HV mode\n",
             progname);
-    pgm->cookie = mycookie;
+    pgm_free(pgmcp);
     return -1;
   }
-  pgm->cookie = mycookie;
-
+  pgm_free(pgmcp);
   PDATA(pgm)->pgmtype = PGMTYPE_JTAGICE_MKII;
 
   if (pgm->bitclock != 0.0) {
@@ -3658,8 +3614,7 @@ static int stk500v2_dragon_hv_open(PROGRAMMER * pgm, char * port)
 /*
  * Open a JTAGICE3 in ISP mode.
  */
-static int stk500v2_jtag3_open(PROGRAMMER * pgm, char * port)
-{
+static int stk500v2_jtag3_open(PROGRAMMER *pgm, const char *port) {
   void *mycookie;
   int rv;
 
@@ -3693,7 +3648,7 @@ static int stk500v2_jtag3_open(PROGRAMMER * pgm, char * port)
 /*
  * XPROG wrapper
  */
-static int stk600_xprog_command(PROGRAMMER * pgm, unsigned char *b,
+static int stk600_xprog_command(const PROGRAMMER *pgm, unsigned char *b,
                                 unsigned int cmdsize, unsigned int responsesize)
 {
     unsigned char *newb;
@@ -3727,8 +3682,7 @@ static int stk600_xprog_command(PROGRAMMER * pgm, unsigned char *b,
 /*
  * issue the 'program enable' command to the AVR device, XPROG version
  */
-static int stk600_xprog_program_enable(PROGRAMMER * pgm, AVRPART * p)
-{
+static int stk600_xprog_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
     unsigned char buf[16];
     unsigned int eepagesize = 42;
     unsigned int nvm_base;
@@ -3830,8 +3784,7 @@ static int stk600_xprog_program_enable(PROGRAMMER * pgm, AVRPART * p)
     return 0;
 }
 
-static unsigned char stk600_xprog_memtype(PROGRAMMER * pgm, unsigned long addr)
-{
+static unsigned char stk600_xprog_memtype(const PROGRAMMER *pgm, unsigned long addr) {
     if (addr >= PDATA(pgm)->boot_start)
         return XPRG_MEM_TYPE_BOOT;
     else
@@ -3839,8 +3792,7 @@ static unsigned char stk600_xprog_memtype(PROGRAMMER * pgm, unsigned long addr)
 }
 
 
-static void stk600_xprog_disable(PROGRAMMER * pgm)
-{
+static void stk600_xprog_disable(const PROGRAMMER *pgm) {
     unsigned char buf[2];
 
     buf[0] = XPRG_CMD_LEAVE_PROGMODE;
@@ -3850,7 +3802,7 @@ static void stk600_xprog_disable(PROGRAMMER * pgm)
     }
 }
 
-static int stk600_xprog_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int stk600_xprog_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
 				   unsigned long addr, unsigned char data)
 {
     unsigned char b[9 + 256];
@@ -3932,7 +3884,7 @@ static int stk600_xprog_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 }
 
 
-static int stk600_xprog_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int stk600_xprog_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                                   unsigned long addr, unsigned char * value)
 {
     unsigned char b[8];
@@ -3982,7 +3934,7 @@ static int stk600_xprog_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 }
 
 
-static int stk600_xprog_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int stk600_xprog_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                                    unsigned int page_size,
                                    unsigned int addr, unsigned int n_bytes)
 {
@@ -4084,7 +4036,7 @@ static int stk600_xprog_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
     return n_bytes_orig;
 }
 
-static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+static int stk600_xprog_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
                                     unsigned int page_size,
                                     unsigned int addr, unsigned int n_bytes)
 {
@@ -4260,8 +4212,7 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
     return n_bytes_orig;
 }
 
-static int stk600_xprog_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+static int stk600_xprog_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
     unsigned char b[6];
     AVRMEM *mem;
     unsigned int addr = 0;
@@ -4289,7 +4240,7 @@ static int stk600_xprog_chip_erase(PROGRAMMER * pgm, AVRPART * p)
     return 0;
 }
 
-static int stk600_xprog_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int stk600_xprog_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                    unsigned int addr)
 {
     unsigned char b[6];
@@ -4359,8 +4310,7 @@ static void stk600_setup_isp(PROGRAMMER * pgm)
 
 const char stk500v2_desc[] = "Atmel STK500 Version 2.x firmware";
 
-void stk500v2_initpgm(PROGRAMMER * pgm)
-{
+void stk500v2_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "STK500V2");
 
   /*
@@ -4397,8 +4347,7 @@ void stk500v2_initpgm(PROGRAMMER * pgm)
 
 const char stk500pp_desc[] = "Atmel STK500 V2 in parallel programming mode";
 
-void stk500pp_initpgm(PROGRAMMER * pgm)
-{
+void stk500pp_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "STK500PP");
 
   /*
@@ -4432,8 +4381,7 @@ void stk500pp_initpgm(PROGRAMMER * pgm)
 
 const char stk500hvsp_desc[] = "Atmel STK500 V2 in high-voltage serial programming mode";
 
-void stk500hvsp_initpgm(PROGRAMMER * pgm)
-{
+void stk500hvsp_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "STK500HVSP");
 
   /*
@@ -4467,8 +4415,7 @@ void stk500hvsp_initpgm(PROGRAMMER * pgm)
 
 const char stk500v2_jtagmkII_desc[] = "Atmel JTAG ICE mkII in ISP mode";
 
-void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm)
-{
+void stk500v2_jtagmkII_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "JTAGMKII_ISP");
 
   /*
@@ -4502,8 +4449,7 @@ void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm)
 
 const char stk500v2_dragon_isp_desc[] = "Atmel AVR Dragon in ISP mode";
 
-void stk500v2_dragon_isp_initpgm(PROGRAMMER * pgm)
-{
+void stk500v2_dragon_isp_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "DRAGON_ISP");
 
   /*
@@ -4536,8 +4482,7 @@ void stk500v2_dragon_isp_initpgm(PROGRAMMER * pgm)
 
 const char stk500v2_dragon_pp_desc[] = "Atmel AVR Dragon in PP mode";
 
-void stk500v2_dragon_pp_initpgm(PROGRAMMER * pgm)
-{
+void stk500v2_dragon_pp_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "DRAGON_PP");
 
   /*
@@ -4571,8 +4516,7 @@ void stk500v2_dragon_pp_initpgm(PROGRAMMER * pgm)
 
 const char stk500v2_dragon_hvsp_desc[] = "Atmel AVR Dragon in HVSP mode";
 
-void stk500v2_dragon_hvsp_initpgm(PROGRAMMER * pgm)
-{
+void stk500v2_dragon_hvsp_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "DRAGON_HVSP");
 
   /*
@@ -4606,8 +4550,7 @@ void stk500v2_dragon_hvsp_initpgm(PROGRAMMER * pgm)
 
 const char stk600_desc[] = "Atmel STK600";
 
-void stk600_initpgm(PROGRAMMER * pgm)
-{
+void stk600_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "STK600");
 
   /*
@@ -4644,8 +4587,7 @@ void stk600_initpgm(PROGRAMMER * pgm)
 
 const char stk600pp_desc[] = "Atmel STK600 in parallel programming mode";
 
-void stk600pp_initpgm(PROGRAMMER * pgm)
-{
+void stk600pp_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "STK600PP");
 
   /*
@@ -4679,8 +4621,7 @@ void stk600pp_initpgm(PROGRAMMER * pgm)
 
 const char stk600hvsp_desc[] = "Atmel STK600 in high-voltage serial programming mode";
 
-void stk600hvsp_initpgm(PROGRAMMER * pgm)
-{
+void stk600hvsp_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "STK600HVSP");
 
   /*
@@ -4714,8 +4655,7 @@ void stk600hvsp_initpgm(PROGRAMMER * pgm)
 
 const char stk500v2_jtag3_desc[] = "Atmel JTAGICE3 in ISP mode";
 
-void stk500v2_jtag3_initpgm(PROGRAMMER * pgm)
-{
+void stk500v2_jtag3_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "JTAG3_ISP");
 
   /*
@@ -4746,4 +4686,3 @@ void stk500v2_jtag3_initpgm(PROGRAMMER * pgm)
   pgm->teardown       = stk500v2_jtag3_teardown;
   pgm->page_size      = 256;
 }
-
diff --git a/src/stk500v2.h b/src/stk500v2.h
index c56056bd..89e40ded 100644
--- a/src/stk500v2.h
+++ b/src/stk500v2.h
@@ -37,22 +37,22 @@ extern const char stk500v2_jtag3_desc[];
 extern const char stk600_desc[];
 extern const char stk600hvsp_desc[];
 extern const char stk600pp_desc[];
-void stk500v2_initpgm (PROGRAMMER * pgm);
-void stk500hvsp_initpgm (PROGRAMMER * pgm);
-void stk500pp_initpgm (PROGRAMMER * pgm);
-void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm);
-void stk500v2_jtag3_initpgm(PROGRAMMER * pgm);
-void stk500v2_dragon_hvsp_initpgm(PROGRAMMER * pgm);
-void stk500v2_dragon_isp_initpgm(PROGRAMMER * pgm);
-void stk500v2_dragon_pp_initpgm(PROGRAMMER * pgm);
-void stk600_initpgm (PROGRAMMER * pgm);
-void stk600hvsp_initpgm (PROGRAMMER * pgm);
-void stk600pp_initpgm (PROGRAMMER * pgm);
+void stk500v2_initpgm(PROGRAMMER *pgm);
+void stk500hvsp_initpgm(PROGRAMMER *pgm);
+void stk500pp_initpgm(PROGRAMMER *pgm);
+void stk500v2_jtagmkII_initpgm(PROGRAMMER *pgm);
+void stk500v2_jtag3_initpgm(PROGRAMMER *pgm);
+void stk500v2_dragon_hvsp_initpgm(PROGRAMMER *pgm);
+void stk500v2_dragon_isp_initpgm(PROGRAMMER *pgm);
+void stk500v2_dragon_pp_initpgm(PROGRAMMER *pgm);
+void stk600_initpgm(PROGRAMMER *pgm);
+void stk600hvsp_initpgm(PROGRAMMER *pgm);
+void stk600pp_initpgm(PROGRAMMER *pgm);
 
 void stk500v2_setup(PROGRAMMER * pgm);
 void stk500v2_teardown(PROGRAMMER * pgm);
-int stk500v2_drain(PROGRAMMER * pgm, int display);
-int stk500v2_getsync(PROGRAMMER * pgm);
+int stk500v2_drain(const PROGRAMMER *pgm, int display);
+int stk500v2_getsync(const PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/stk500v2_private.h b/src/stk500v2_private.h
index 2ac0d05c..5531a269 100644
--- a/src/stk500v2_private.h
+++ b/src/stk500v2_private.h
@@ -312,7 +312,7 @@ struct pdata
     }
         pgmtype;
 
-  AVRPART *lastpart;
+  const AVRPART *lastpart;
 
   /* Start address of Xmega boot area */
   unsigned long boot_start;
diff --git a/src/teensy.c b/src/teensy.c
index b6bfc772..2aa286df 100644
--- a/src/teensy.c
+++ b/src/teensy.c
@@ -86,8 +86,7 @@ static void delay_ms(uint32_t duration)
     usleep(duration * 1000);
 }
 
-static int teensy_get_bootloader_info(pdata_t* pdata, AVRPART* p)
-{
+static int teensy_get_bootloader_info(pdata_t* pdata, const AVRPART* p) {
     switch (pdata->hid_usage)
     {
     case 0x19:
@@ -253,8 +252,7 @@ static void teensy_teardown(PROGRAMMER* pgm)
     free(pgm->cookie);
 }
 
-static int teensy_initialize(PROGRAMMER* pgm, AVRPART* p)
-{
+static int teensy_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
     avrdude_message(MSG_DEBUG, "%s: teensy_initialize()\n", progname);
 
     pdata_t* pdata = PDATA(pgm);
@@ -268,18 +266,15 @@ static int teensy_initialize(PROGRAMMER* pgm, AVRPART* p)
     return 0;
 }
 
-static void teensy_display(PROGRAMMER* pgm, const char* prefix)
-{
+static void teensy_display(const PROGRAMMER *pgm, const char *prefix) {
     avrdude_message(MSG_DEBUG, "%s: teensy_display()\n", progname);
 }
 
-static void teensy_powerup(PROGRAMMER* pgm)
-{
+static void teensy_powerup(const PROGRAMMER *pgm) {
     avrdude_message(MSG_DEBUG, "%s: teensy_powerup()\n", progname);
 }
 
-static void teensy_powerdown(PROGRAMMER* pgm)
-{
+static void teensy_powerdown(const PROGRAMMER *pgm) {
     avrdude_message(MSG_DEBUG, "%s: teensy_powerdown()\n", progname);
 
     pdata_t* pdata = PDATA(pgm);
@@ -297,24 +292,20 @@ static void teensy_powerdown(PROGRAMMER* pgm)
     }
 }
 
-static void teensy_enable(PROGRAMMER* pgm)
-{
+static void teensy_enable(PROGRAMMER* pgm, const AVRPART *p) {
     avrdude_message(MSG_DEBUG, "%s: teensy_enable()\n", progname);
 }
 
-static void teensy_disable(PROGRAMMER* pgm)
-{
+static void teensy_disable(const PROGRAMMER *pgm) {
     avrdude_message(MSG_DEBUG, "%s: teensy_disable()\n", progname);
 }
 
-static int teensy_program_enable(PROGRAMMER* pgm, AVRPART* p)
-{
+static int teensy_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
     avrdude_message(MSG_DEBUG, "%s: teensy_program_enable()\n", progname);
     return 0;
 }
 
-static int teensy_read_sig_bytes(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem)
-{
+static int teensy_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem) {
     avrdude_message(MSG_DEBUG, "%s: teensy_read_sig_bytes()\n", progname);
 
     if (mem->size < 3)
@@ -329,8 +320,7 @@ static int teensy_read_sig_bytes(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem)
     return 0;
 }
 
-static int teensy_chip_erase(PROGRAMMER* pgm, AVRPART* p)
-{
+static int teensy_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
     avrdude_message(MSG_DEBUG, "%s: teensy_chip_erase()\n", progname);
 
     pdata_t* pdata = PDATA(pgm);
@@ -341,12 +331,11 @@ static int teensy_chip_erase(PROGRAMMER* pgm, AVRPART* p)
     return 0;
 }
 
-static int teensy_open(PROGRAMMER* pgm, char* port)
-{
+static int teensy_open(PROGRAMMER *pgm, const char *port) {
     avrdude_message(MSG_DEBUG, "%s: teensy_open(\"%s\")\n", progname, port);
 
     pdata_t* pdata = PDATA(pgm);
-    char* bus_name = NULL;
+    const char *bus_name = NULL;
     char* dev_name = NULL;
 
     // if no -P was given or '-P usb' was given
@@ -472,7 +461,7 @@ static void teensy_close(PROGRAMMER* pgm)
     }
 }
 
-static int teensy_read_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
+static int teensy_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
     unsigned long addr, unsigned char* value)
 {
     avrdude_message(MSG_DEBUG, "%s: teensy_read_byte(desc=%s, addr=0x%0X)\n",
@@ -493,7 +482,7 @@ static int teensy_read_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
     }
 }
 
-static int teensy_write_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
+static int teensy_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
     unsigned long addr, unsigned char value)
 {
     avrdude_message(MSG_DEBUG, "%s: teensy_write_byte(desc=%s, addr=0x%0X)\n",
@@ -501,7 +490,7 @@ static int teensy_write_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
     return -1;
 }
 
-static int teensy_paged_load(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
+static int teensy_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
     unsigned int page_size,
     unsigned int addr, unsigned int n_bytes)
 {
@@ -510,7 +499,7 @@ static int teensy_paged_load(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
     return -1;
 }
 
-static int teensy_paged_write(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
+static int teensy_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
     unsigned int page_size,
     unsigned int addr, unsigned int n_bytes)
 {
@@ -567,8 +556,7 @@ static int teensy_paged_write(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
     }
 }
 
-static int teensy_parseextparams(PROGRAMMER* pgm, LISTID xparams)
-{
+static int teensy_parseextparams(const PROGRAMMER *pgm, const LISTID xparams) {
     avrdude_message(MSG_DEBUG, "%s: teensy_parseextparams()\n", progname);
 
     pdata_t* pdata = PDATA(pgm);
@@ -596,8 +584,7 @@ static int teensy_parseextparams(PROGRAMMER* pgm, LISTID xparams)
     return 0;
 }
 
-void teensy_initpgm(PROGRAMMER* pgm)
-{
+void teensy_initpgm(PROGRAMMER *pgm) {
     strcpy(pgm->type, "teensy");
 
     pgm->setup = teensy_setup;
@@ -624,14 +611,12 @@ void teensy_initpgm(PROGRAMMER* pgm)
 #else /* !HAVE_LIBHIDAPI */
 
  // Give a proper error if we were not compiled with libhidapi
-static int teensy_nousb_open(struct programmer_t* pgm, char* name)
-{
+static int teensy_nousb_open(PROGRAMMER *pgm, const char *name) {
     avrdude_message(MSG_INFO, "%s: error: No HID support. Please compile again with libhidapi installed.\n", progname);
     return -1;
 }
 
-void teensy_initpgm(PROGRAMMER* pgm)
-{
+void teensy_initpgm(PROGRAMMER *pgm) {
     strcpy(pgm->type, "teensy");
     pgm->open = teensy_nousb_open;
 }
diff --git a/src/teensy.h b/src/teensy.h
index 8cec458a..f617e9d5 100644
--- a/src/teensy.h
+++ b/src/teensy.h
@@ -26,7 +26,7 @@ extern "C" {
 #endif
 
 extern const char teensy_desc[];
-void teensy_initpgm(PROGRAMMER* pgm);
+void teensy_initpgm(PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/updi_link.c b/src/updi_link.c
index 1f179398..aff93906 100644
--- a/src/updi_link.c
+++ b/src/updi_link.c
@@ -39,8 +39,7 @@
 #include "updi_constants.h"
 #include "updi_state.h"
 
-static void updi_set_rtsdtr_mode(PROGRAMMER* pgm)
-{
+static void updi_set_rtsdtr_mode(const PROGRAMMER *pgm) {
   updi_rts_mode rts_mode = updi_get_rts_mode(pgm);
 
   if (rts_mode == RTS_MODE_DEFAULT) {
@@ -87,8 +86,7 @@ static void updi_physical_close(PROGRAMMER* pgm)
   pgm->fd.ifd = -1;
 }
 
-static int updi_physical_send(PROGRAMMER * pgm, unsigned char * buf, size_t len)
-{
+static int updi_physical_send(const PROGRAMMER *pgm, unsigned char *buf, size_t len) {
   size_t i;
   int rv;
 
@@ -106,8 +104,7 @@ static int updi_physical_send(PROGRAMMER * pgm, unsigned char * buf, size_t len)
   return rv;
 }
 
-static int updi_physical_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
-{
+static int updi_physical_recv(const PROGRAMMER *pgm, unsigned char *buf, size_t len) {
   size_t i;
   int rv;
 
@@ -131,8 +128,7 @@ static int updi_physical_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
   return len;
 }
 
-static int updi_physical_send_double_break(PROGRAMMER * pgm)
-{
+static int updi_physical_send_double_break(const PROGRAMMER *pgm) {
   unsigned char buffer[1];
 
   avrdude_message(MSG_DEBUG, "%s: Sending double break\n", progname);
@@ -171,8 +167,7 @@ static int updi_physical_send_double_break(PROGRAMMER * pgm)
   return 0;
 }
 
-int updi_physical_sib(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size)
-{
+int updi_physical_sib(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size) {
 /*
     def sib(self):
         """
@@ -196,8 +191,7 @@ int updi_physical_sib(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size)
   return updi_physical_recv(pgm, buffer, size);
 }
 
-int updi_link_open(PROGRAMMER * pgm) 
-{
+int updi_link_open(PROGRAMMER *pgm)  {
   unsigned char init_buffer[1];
 
   if (updi_physical_open(pgm, pgm->baudrate? pgm->baudrate: 115200, SERIAL_8E2) < 0) {
@@ -208,13 +202,11 @@ int updi_link_open(PROGRAMMER * pgm)
   return updi_physical_send(pgm, init_buffer, 1);
 }
 
-void updi_link_close(PROGRAMMER * pgm)
-{
+void updi_link_close(PROGRAMMER *pgm) {
   updi_physical_close(pgm);
 }
 
-static int updi_link_init_session_parameters(PROGRAMMER * pgm) 
-{
+static int updi_link_init_session_parameters(const PROGRAMMER *pgm)  {
 /*
     def _init_session_parameters(self):
         """
@@ -234,8 +226,7 @@ static int updi_link_init_session_parameters(PROGRAMMER * pgm)
   return 0;
 }
 
-static int updi_link_check(PROGRAMMER * pgm)
-{
+static int updi_link_check(const PROGRAMMER *pgm) {
 /*
     def _check_datalink(self):
         """
@@ -269,8 +260,7 @@ static int updi_link_check(PROGRAMMER * pgm)
 }
 
 
-int updi_link_init(PROGRAMMER * pgm)
-{
+int updi_link_init(const PROGRAMMER *pgm) {
 /*
     def init_datalink(self):
         """
@@ -308,8 +298,7 @@ int updi_link_init(PROGRAMMER * pgm)
   return 0;
 }
 
-int updi_link_ldcs(PROGRAMMER * pgm, uint8_t address, uint8_t * value) 
-{
+int updi_link_ldcs(const PROGRAMMER *pgm, uint8_t address, uint8_t *value)  {
 /*
     def ldcs(self, address):
         """
@@ -347,8 +336,7 @@ int updi_link_ldcs(PROGRAMMER * pgm, uint8_t address, uint8_t * value)
   return 0;
 }
 
-int updi_link_stcs(PROGRAMMER * pgm, uint8_t address, uint8_t value)
-{
+int updi_link_stcs(const PROGRAMMER *pgm, uint8_t address, uint8_t value) {
 /*
     def stcs(self, address, value):
         """
@@ -368,8 +356,7 @@ int updi_link_stcs(PROGRAMMER * pgm, uint8_t address, uint8_t value)
   return updi_physical_send(pgm, buffer, 3);
 }
 
-int updi_link_ld_ptr_inc(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size)
-{
+int updi_link_ld_ptr_inc(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size) {
 /*
     def ld_ptr_inc(self, size):
         """
@@ -394,8 +381,7 @@ int updi_link_ld_ptr_inc(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size
   return updi_physical_recv(pgm, buffer, size);
 }
 
-int updi_link_ld_ptr_inc16(PROGRAMMER * pgm, unsigned char * buffer, uint16_t words)
-{
+int updi_link_ld_ptr_inc16(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words) {
 /*
     def ld_ptr_inc16(self, words):
         """
@@ -420,8 +406,7 @@ int updi_link_ld_ptr_inc16(PROGRAMMER * pgm, unsigned char * buffer, uint16_t wo
   return updi_physical_recv(pgm, buffer, words << 2);
 }
 
-int updi_link_st_ptr_inc(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size)
-{
+int updi_link_st_ptr_inc(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size) {
 /*
     def st_ptr_inc(self, data):
         """
@@ -484,8 +469,7 @@ int updi_link_st_ptr_inc(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size
   return 0;
 }
 
-int updi_link_st_ptr_inc16(PROGRAMMER * pgm, unsigned char * buffer, uint16_t words)
-{
+int updi_link_st_ptr_inc16(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words) {
 /*
     def st_ptr_inc16(self, data):
         """
@@ -550,7 +534,7 @@ int updi_link_st_ptr_inc16(PROGRAMMER * pgm, unsigned char * buffer, uint16_t wo
   return 0;
 }
 
-int updi_link_st_ptr_inc16_RSD(PROGRAMMER * pgm, unsigned char * buffer, uint16_t words, int blocksize) {
+int updi_link_st_ptr_inc16_RSD(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words, int blocksize) {
 /*
     def st_ptr_inc16_RSD(self, data, blocksize):
         """
@@ -653,8 +637,7 @@ int updi_link_st_ptr_inc16_RSD(PROGRAMMER * pgm, unsigned char * buffer, uint16_
   return 0;
 }
 
-int updi_link_repeat(PROGRAMMER * pgm, uint16_t repeats)
-{
+int updi_link_repeat(const PROGRAMMER *pgm, uint16_t repeats) {
 /*
     def repeat(self, repeats):
         """
@@ -683,8 +666,7 @@ int updi_link_repeat(PROGRAMMER * pgm, uint16_t repeats)
   return updi_physical_send(pgm, buffer, 3);
 }
 
-int updi_link_read_sib(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size)
-{
+int updi_link_read_sib(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size) {
 /*
     def read_sib(self):
         """
@@ -695,8 +677,7 @@ int updi_link_read_sib(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size)
   return updi_physical_sib(pgm, buffer, size);
 }
 
-int updi_link_key(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size_type, uint16_t size)
-{
+int updi_link_key(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size_type, uint16_t size) {
 /*
     def key(self, size, key):
         """
@@ -732,8 +713,7 @@ int updi_link_key(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size_type, u
   return updi_physical_send(pgm, reversed_key, size);
 }
 
-int updi_link_ld(PROGRAMMER * pgm, uint32_t address, uint8_t * value)
-{
+int updi_link_ld(const PROGRAMMER *pgm, uint32_t address, uint8_t *value) {
 /*
     def ld(self, address):
         """
@@ -768,8 +748,7 @@ int updi_link_ld(PROGRAMMER * pgm, uint32_t address, uint8_t * value)
   return 0;
 }
 
-int updi_link_ld16(PROGRAMMER * pgm, uint32_t address, uint16_t * value)
-{
+int updi_link_ld16(const PROGRAMMER *pgm, uint32_t address, uint16_t *value) {
 /*
     def ld16(self, address):
         """
@@ -804,8 +783,7 @@ int updi_link_ld16(PROGRAMMER * pgm, uint32_t address, uint16_t * value)
   return 0;
 }
 
-static int updi_link_st_data_phase(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size)
-{
+static int updi_link_st_data_phase(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size) {
 /*
     def _st_data_phase(self, values):
         """
@@ -848,8 +826,7 @@ static int updi_link_st_data_phase(PROGRAMMER * pgm, unsigned char * buffer, uin
   return 0;
 }
 
-int updi_link_st(PROGRAMMER * pgm, uint32_t address, uint8_t value)
-{
+int updi_link_st(const PROGRAMMER *pgm, uint32_t address, uint8_t value) {
 /*
     def st(self, address, value):
         """
@@ -879,8 +856,7 @@ int updi_link_st(PROGRAMMER * pgm, uint32_t address, uint8_t value)
   return updi_link_st_data_phase(pgm, send_buffer, 1);
 }
 
-int updi_link_st16(PROGRAMMER * pgm, uint32_t address, uint16_t value)
-{
+int updi_link_st16(const PROGRAMMER *pgm, uint32_t address, uint16_t value) {
 /*
     def st16(self, address, value):
         """
@@ -911,8 +887,7 @@ int updi_link_st16(PROGRAMMER * pgm, uint32_t address, uint16_t value)
   return updi_link_st_data_phase(pgm, send_buffer, 2);
 }
 
-int updi_link_st_ptr(PROGRAMMER * pgm, uint32_t address)
-{
+int updi_link_st_ptr(const PROGRAMMER *pgm, uint32_t address) {
 /*
     def st_ptr(self, address):
         """
diff --git a/src/updi_link.h b/src/updi_link.h
index 5b5e5bda..796788ad 100644
--- a/src/updi_link.h
+++ b/src/updi_link.h
@@ -35,22 +35,22 @@ extern "C" {
 
 int updi_link_open(PROGRAMMER * pgm);
 void updi_link_close(PROGRAMMER * pgm);
-int updi_link_init(PROGRAMMER * pgm);
-int updi_link_ldcs(PROGRAMMER * pgm, uint8_t address, uint8_t * value);
-int updi_link_stcs(PROGRAMMER * pgm, uint8_t address, uint8_t value);
-int updi_link_ld_ptr_inc(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size);
-int updi_link_ld_ptr_inc16(PROGRAMMER * pgm, unsigned char * buffer, uint16_t words);
-int updi_link_st_ptr_inc(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size);
-int updi_link_st_ptr_inc16(PROGRAMMER * pgm, unsigned char * buffer, uint16_t words);
-int updi_link_st_ptr_inc16_RSD(PROGRAMMER * pgm, unsigned char * buffer, uint16_t words, int blocksize);
-int updi_link_repeat(PROGRAMMER * pgm, uint16_t repeats);
-int updi_link_read_sib(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size);
-int updi_link_key(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size_type, uint16_t size);
-int updi_link_ld(PROGRAMMER * pgm, uint32_t address, uint8_t * value);
-int updi_link_ld16(PROGRAMMER * pgm, uint32_t address, uint16_t * value);
-int updi_link_st(PROGRAMMER * pgm, uint32_t address, uint8_t value);
-int updi_link_st16(PROGRAMMER * pgm, uint32_t address, uint16_t value);
-int updi_link_st_ptr(PROGRAMMER * pgm, uint32_t address);
+int updi_link_init(const PROGRAMMER *pgm);
+int updi_link_ldcs(const PROGRAMMER *pgm, uint8_t address, uint8_t *value);
+int updi_link_stcs(const PROGRAMMER *pgm, uint8_t address, uint8_t value);
+int updi_link_ld_ptr_inc(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size);
+int updi_link_ld_ptr_inc16(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words);
+int updi_link_st_ptr_inc(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size);
+int updi_link_st_ptr_inc16(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words);
+int updi_link_st_ptr_inc16_RSD(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words, int blocksize);
+int updi_link_repeat(const PROGRAMMER *pgm, uint16_t repeats);
+int updi_link_read_sib(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size);
+int updi_link_key(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size_type, uint16_t size);
+int updi_link_ld(const PROGRAMMER *pgm, uint32_t address, uint8_t *value);
+int updi_link_ld16(const PROGRAMMER *pgm, uint32_t address, uint16_t *value);
+int updi_link_st(const PROGRAMMER *pgm, uint32_t address, uint8_t value);
+int updi_link_st16(const PROGRAMMER *pgm, uint32_t address, uint16_t value);
+int updi_link_st_ptr(const PROGRAMMER *pgm, uint32_t address);
 
 #ifdef __cplusplus
 }
diff --git a/src/updi_nvm.c b/src/updi_nvm.c
index f3d899a9..9b1275f6 100644
--- a/src/updi_nvm.c
+++ b/src/updi_nvm.c
@@ -47,8 +47,7 @@ typedef enum
 
 #define USE_DEFAULT_COMMAND 0xFF
 
-static int nvm_chip_erase_V0(PROGRAMMER * pgm, AVRPART * p)
-{
+static int nvm_chip_erase_V0(const PROGRAMMER *pgm, const AVRPART *p) {
 /*
     def chip_erase(self):
         """
@@ -88,8 +87,7 @@ static int nvm_chip_erase_V0(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static int nvm_erase_flash_page_V0(PROGRAMMER * pgm, AVRPART * p, uint32_t address)
-{
+static int nvm_erase_flash_page_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address) {
 /*
     def erase_flash_page(self, address):
         """
@@ -136,8 +134,7 @@ static int nvm_erase_flash_page_V0(PROGRAMMER * pgm, AVRPART * p, uint32_t addre
   return 0;
 }
 
-static int nvm_erase_eeprom_V0(PROGRAMMER * pgm, AVRPART * p)
-{
+static int nvm_erase_eeprom_V0(const PROGRAMMER *pgm, const AVRPART *p) {
 /*
     def erase_eeprom(self):
         """
@@ -172,8 +169,7 @@ static int nvm_erase_eeprom_V0(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static int nvm_erase_user_row_V0(PROGRAMMER * pgm, AVRPART *p, uint32_t address, uint16_t size)
-{
+static int nvm_erase_user_row_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint16_t size) {
 /*
     def erase_user_row(self, address, size):
         """
@@ -226,14 +222,13 @@ static int nvm_erase_user_row_V0(PROGRAMMER * pgm, AVRPART *p, uint32_t address,
   return 0;
 }
 
-static int nvm_write_V0(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, 
+static int nvm_write_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer,
                         uint16_t size, access_mode mode, uint8_t nvm_command);
 
-static int nvm_write_eeprom_V0(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, uint16_t size);
+static int nvm_write_eeprom_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size);
 
 
-static int nvm_write_flash_V0(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, uint16_t size)
-{
+static int nvm_write_flash_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) {
 /*
     def write_flash(self, address, data):
         """
@@ -247,8 +242,7 @@ static int nvm_write_flash_V0(PROGRAMMER * pgm, AVRPART *p, uint32_t address, un
   return nvm_write_V0(pgm, p, address, buffer, size, USE_WORD_ACCESS, USE_DEFAULT_COMMAND);
 }
 
-static int nvm_write_user_row_V0(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, uint16_t size)
-{
+static int nvm_write_user_row_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) {
 /*
     def write_user_row(self, address, data):
         """
@@ -263,8 +257,7 @@ static int nvm_write_user_row_V0(PROGRAMMER * pgm, AVRPART *p, uint32_t address,
   return nvm_write_eeprom_V0(pgm, p, address, buffer, size);
 }
 
-static int nvm_write_eeprom_V0(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, uint16_t size)
-{
+static int nvm_write_eeprom_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) {
 /*
     def write_eeprom(self, address, data):
         """
@@ -279,8 +272,7 @@ static int nvm_write_eeprom_V0(PROGRAMMER * pgm, AVRPART *p, uint32_t address, u
   return nvm_write_V0(pgm, p, address, buffer, size, DONT_USE_WORD_ACCESS, UPDI_V0_NVMCTRL_CTRLA_ERASE_WRITE_PAGE);
 }
 
-static int nvm_write_fuse_V0(PROGRAMMER * pgm, AVRPART *p, uint32_t address, uint8_t value)
-{
+static int nvm_write_fuse_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint8_t value) {
 /*
     def write_fuse(self, address, data):
         """
@@ -340,7 +332,7 @@ static int nvm_write_fuse_V0(PROGRAMMER * pgm, AVRPART *p, uint32_t address, uin
   return 0;
 }
 
-static int nvm_write_V0(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, 
+static int nvm_write_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer,
                         uint16_t size, access_mode mode, uint8_t nvm_command)
 {
 /*
@@ -423,8 +415,7 @@ static int nvm_write_V0(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned
   return 0;
 }
 
-static int nvm_chip_erase_V2(PROGRAMMER * pgm, AVRPART * p)
-{
+static int nvm_chip_erase_V2(const PROGRAMMER *pgm, const AVRPART *p) {
 /*
     def chip_erase(self):
         """
@@ -463,8 +454,7 @@ static int nvm_chip_erase_V2(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static int nvm_erase_flash_page_V2(PROGRAMMER * pgm, AVRPART * p, uint32_t address)
-{
+static int nvm_erase_flash_page_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address) {
 /*
     def erase_flash_page(self, address):
         """
@@ -515,8 +505,7 @@ static int nvm_erase_flash_page_V2(PROGRAMMER * pgm, AVRPART * p, uint32_t addre
   return 0;
 }
 
-static int nvm_erase_eeprom_V2(PROGRAMMER * pgm, AVRPART * p)
-{
+static int nvm_erase_eeprom_V2(const PROGRAMMER *pgm, const AVRPART *p) {
 /*
     def erase_eeprom(self):
         """
@@ -560,8 +549,7 @@ static int nvm_erase_eeprom_V2(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static int nvm_erase_user_row_V2(PROGRAMMER * pgm, AVRPART *p, uint32_t address, uint16_t size)
-{
+static int nvm_erase_user_row_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint16_t size) {
 /*
     def erase_user_row(self, address, size):
         """
@@ -578,11 +566,10 @@ static int nvm_erase_user_row_V2(PROGRAMMER * pgm, AVRPART *p, uint32_t address,
   return nvm_erase_flash_page_V2(pgm, p, address);
 }
 
-static int nvm_write_V2(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, 
+static int nvm_write_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer,
                         uint16_t size, access_mode mode);
 
-static int nvm_write_flash_V2(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, uint16_t size)
-{
+static int nvm_write_flash_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) {
 /*
     def write_flash(self, address, data):
         """
@@ -596,8 +583,7 @@ static int nvm_write_flash_V2(PROGRAMMER * pgm, AVRPART *p, uint32_t address, un
   return nvm_write_V2(pgm, p, address, buffer, size, USE_WORD_ACCESS);
 }
 
-static int nvm_write_user_row_V2(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, uint16_t size)
-{
+static int nvm_write_user_row_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) {
 /*
     def write_user_row(self, address, data):
         """
@@ -612,8 +598,7 @@ static int nvm_write_user_row_V2(PROGRAMMER * pgm, AVRPART *p, uint32_t address,
   return nvm_write_V2(pgm, p, address, buffer, size, DONT_USE_WORD_ACCESS);
 }
 
-static int nvm_write_eeprom_V2(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, uint16_t size)
-{
+static int nvm_write_eeprom_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) {
 /*
     def write_eeprom(self, address, data):
         """
@@ -668,8 +653,7 @@ static int nvm_write_eeprom_V2(PROGRAMMER * pgm, AVRPART *p, uint32_t address, u
   return 0;
 }
 
-static int nvm_write_fuse_V2(PROGRAMMER * pgm, AVRPART *p, uint32_t address, uint8_t value)
-{
+static int nvm_write_fuse_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint8_t value) {
 /*
     def write_fuse(self, address, data):
         """
@@ -686,7 +670,7 @@ static int nvm_write_fuse_V2(PROGRAMMER * pgm, AVRPART *p, uint32_t address, uin
   return nvm_write_eeprom_V2(pgm, p, address, buffer, 1);
 }
 
-static int nvm_write_V2(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, 
+static int nvm_write_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer,
                         uint16_t size, access_mode mode)
 {
 /*
@@ -755,8 +739,7 @@ static int nvm_write_V2(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned
   return 0;
 }
 
-static int nvm_chip_erase_V3(PROGRAMMER * pgm, AVRPART * p)
-{
+static int nvm_chip_erase_V3(const PROGRAMMER *pgm, const AVRPART *p) {
 /*
     def chip_erase(self):
         """
@@ -805,8 +788,7 @@ static int nvm_chip_erase_V3(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static int nvm_erase_flash_page_V3(PROGRAMMER * pgm, AVRPART * p, uint32_t address)
-{
+static int nvm_erase_flash_page_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address) {
 /*
     def erase_flash_page(self, address):
         """
@@ -858,8 +840,7 @@ static int nvm_erase_flash_page_V3(PROGRAMMER * pgm, AVRPART * p, uint32_t addre
   return 0;
 }
 
-static int nvm_erase_eeprom_V3(PROGRAMMER * pgm, AVRPART * p)
-{
+static int nvm_erase_eeprom_V3(const PROGRAMMER *pgm, const AVRPART *p) {
 /*
     def erase_eeprom(self):
         """
@@ -903,8 +884,7 @@ static int nvm_erase_eeprom_V3(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static int nvm_erase_user_row_V3(PROGRAMMER * pgm, AVRPART *p, uint32_t address, uint16_t size)
-{
+static int nvm_erase_user_row_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint16_t size) {
 /*
     def erase_user_row(self, address, size):
         """
@@ -923,11 +903,10 @@ static int nvm_erase_user_row_V3(PROGRAMMER * pgm, AVRPART *p, uint32_t address,
   return nvm_erase_flash_page_V3(pgm, p, address);
 }
 
-static int nvm_write_V3(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, 
+static int nvm_write_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer,
                         uint16_t size, access_mode mode, uint8_t nvm_command);
 
-static int nvm_write_flash_V3(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, uint16_t size)
-{
+static int nvm_write_flash_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) {
 /*
     def write_flash(self, address, data):
         """
@@ -941,8 +920,7 @@ static int nvm_write_flash_V3(PROGRAMMER * pgm, AVRPART *p, uint32_t address, un
   return nvm_write_V3(pgm, p, address, buffer, size, USE_WORD_ACCESS, USE_DEFAULT_COMMAND);
 }
 
-static int nvm_write_user_row_V3(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, uint16_t size)
-{
+static int nvm_write_user_row_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) {
 /*
     def write_user_row(self, address, data):
         """
@@ -957,8 +935,7 @@ static int nvm_write_user_row_V3(PROGRAMMER * pgm, AVRPART *p, uint32_t address,
   return nvm_write_V3(pgm, p, address, buffer, size, USE_WORD_ACCESS, USE_DEFAULT_COMMAND);
 }
 
-static int nvm_write_eeprom_V3(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, uint16_t size)
-{
+static int nvm_write_eeprom_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) {
 /*
     def write_eeprom(self, address, data):
         """
@@ -973,8 +950,7 @@ static int nvm_write_eeprom_V3(PROGRAMMER * pgm, AVRPART *p, uint32_t address, u
   return nvm_write_V3(pgm, p, address, buffer, size, DONT_USE_WORD_ACCESS, UPDI_V3_NVMCTRL_CTRLA_EEPROM_PAGE_ERASE_WRITE);
 }
 
-static int nvm_write_fuse_V3(PROGRAMMER * pgm, AVRPART *p, uint32_t address, uint8_t value)
-{
+static int nvm_write_fuse_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint8_t value) {
 /*
     def write_fuse(self, address, data):
         """
@@ -990,7 +966,7 @@ static int nvm_write_fuse_V3(PROGRAMMER * pgm, AVRPART *p, uint32_t address, uin
   return nvm_write_eeprom_V3(pgm, p, address, buffer, 1);
 }
 
-static int nvm_write_V3(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, 
+static int nvm_write_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer,
                         uint16_t size, access_mode mode, uint8_t nvm_command)
 {
 /*
@@ -1081,8 +1057,7 @@ static int nvm_write_V3(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned
 }
 
 
-int updi_nvm_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+int updi_nvm_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
   switch(updi_get_nvm_mode(pgm))
   {
     case UPDI_NVM_MODE_V0:
@@ -1097,8 +1072,7 @@ int updi_nvm_chip_erase(PROGRAMMER * pgm, AVRPART * p)
   }
 }
 
-int updi_nvm_erase_flash_page(PROGRAMMER * pgm, AVRPART *p, uint32_t address)
-{
+int updi_nvm_erase_flash_page(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address) {
   switch(updi_get_nvm_mode(pgm))
   {
     case UPDI_NVM_MODE_V0:
@@ -1113,8 +1087,7 @@ int updi_nvm_erase_flash_page(PROGRAMMER * pgm, AVRPART *p, uint32_t address)
   }
 }
 
-int updi_nvm_erase_eeprom(PROGRAMMER * pgm, AVRPART *p)
-{
+int updi_nvm_erase_eeprom(const PROGRAMMER *pgm, const AVRPART *p) {
   switch(updi_get_nvm_mode(pgm))
   {
     case UPDI_NVM_MODE_V0:
@@ -1129,8 +1102,7 @@ int updi_nvm_erase_eeprom(PROGRAMMER * pgm, AVRPART *p)
   }
 }
 
-int updi_nvm_erase_user_row(PROGRAMMER * pgm, AVRPART *p, uint32_t address, uint16_t size)
-{
+int updi_nvm_erase_user_row(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint16_t size) {
   switch(updi_get_nvm_mode(pgm))
   {
     case UPDI_NVM_MODE_V0:
@@ -1145,8 +1117,7 @@ int updi_nvm_erase_user_row(PROGRAMMER * pgm, AVRPART *p, uint32_t address, uint
   }
 }
 
-int updi_nvm_write_flash(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, uint16_t size)
-{
+int updi_nvm_write_flash(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) {
   switch(updi_get_nvm_mode(pgm))
   {
     case UPDI_NVM_MODE_V0:
@@ -1161,8 +1132,7 @@ int updi_nvm_write_flash(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigne
   }
 }
 
-int updi_nvm_write_user_row(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, uint16_t size)
-{
+int updi_nvm_write_user_row(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) {
   switch(updi_get_nvm_mode(pgm))
   {
     case UPDI_NVM_MODE_V0:
@@ -1177,8 +1147,7 @@ int updi_nvm_write_user_row(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsi
   }
 }
 
-int updi_nvm_write_eeprom(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, uint16_t size)
-{
+int updi_nvm_write_eeprom(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) {
   switch(updi_get_nvm_mode(pgm))
   {
     case UPDI_NVM_MODE_V0:
@@ -1193,8 +1162,7 @@ int updi_nvm_write_eeprom(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsign
   }
 }
 
-int updi_nvm_write_fuse(PROGRAMMER * pgm, AVRPART *p, uint32_t address, uint8_t value)
-{
+int updi_nvm_write_fuse(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint8_t value) {
   switch(updi_get_nvm_mode(pgm))
   {
     case UPDI_NVM_MODE_V0:
@@ -1209,8 +1177,7 @@ int updi_nvm_write_fuse(PROGRAMMER * pgm, AVRPART *p, uint32_t address, uint8_t
   }
 }
 
-int updi_nvm_wait_ready(PROGRAMMER * pgm, AVRPART *p)
-{
+int updi_nvm_wait_ready(const PROGRAMMER *pgm, const AVRPART *p) {
 /*
     def wait_nvm_ready(self):
         """
@@ -1257,8 +1224,7 @@ int updi_nvm_wait_ready(PROGRAMMER * pgm, AVRPART *p)
   return -1;
 }
 
-int updi_nvm_command(PROGRAMMER * pgm, AVRPART *p, uint8_t command)
-{
+int updi_nvm_command(const PROGRAMMER *pgm, const AVRPART *p, uint8_t command) {
 /*
     def execute_nvm_command(self, command):
         """
diff --git a/src/updi_nvm.h b/src/updi_nvm.h
index c0c1544e..a6439f01 100644
--- a/src/updi_nvm.h
+++ b/src/updi_nvm.h
@@ -33,16 +33,16 @@
 extern "C" {
 #endif
 
-int updi_nvm_chip_erase(PROGRAMMER * pgm, AVRPART * p);
-int updi_nvm_erase_flash_page(PROGRAMMER * pgm, AVRPART *p, uint32_t address);
-int updi_nvm_erase_eeprom(PROGRAMMER * pgm, AVRPART *p);
-int updi_nvm_erase_user_row(PROGRAMMER * pgm, AVRPART *p, uint32_t address, uint16_t size);
-int updi_nvm_write_flash(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, uint16_t size);
-int updi_nvm_write_user_row(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, uint16_t size);
-int updi_nvm_write_eeprom(PROGRAMMER * pgm, AVRPART *p, uint32_t address, unsigned char * buffer, uint16_t size);
-int updi_nvm_write_fuse(PROGRAMMER * pgm, AVRPART *p, uint32_t address, uint8_t value);
-int updi_nvm_wait_ready(PROGRAMMER * pgm, AVRPART *p);
-int updi_nvm_command(PROGRAMMER * pgm, AVRPART *p, uint8_t command);
+int updi_nvm_chip_erase(const PROGRAMMER *pgm, const AVRPART *p);
+int updi_nvm_erase_flash_page(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address);
+int updi_nvm_erase_eeprom(const PROGRAMMER *pgm, const AVRPART *p);
+int updi_nvm_erase_user_row(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint16_t size);
+int updi_nvm_write_flash(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size);
+int updi_nvm_write_user_row(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size);
+int updi_nvm_write_eeprom(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size);
+int updi_nvm_write_fuse(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint8_t value);
+int updi_nvm_wait_ready(const PROGRAMMER *pgm, const AVRPART *p);
+int updi_nvm_command(const PROGRAMMER *pgm, const AVRPART *p, uint8_t command);
 
 #ifdef __cplusplus
 }
diff --git a/src/updi_readwrite.c b/src/updi_readwrite.c
index dcc3a849..08b6eb4a 100644
--- a/src/updi_readwrite.c
+++ b/src/updi_readwrite.c
@@ -39,8 +39,7 @@
 #include "updi_link.h"
 #include "updi_readwrite.h"
 
-int updi_read_cs(PROGRAMMER * pgm, uint8_t address, uint8_t * value)
-{
+int updi_read_cs(const PROGRAMMER *pgm, uint8_t address, uint8_t *value) {
 /*
     def read_cs(self, address):
         """
@@ -54,8 +53,7 @@ int updi_read_cs(PROGRAMMER * pgm, uint8_t address, uint8_t * value)
   return updi_link_ldcs(pgm, address, value);
 }
 
-int updi_write_cs(PROGRAMMER * pgm, uint8_t address, uint8_t value)
-{
+int updi_write_cs(const PROGRAMMER *pgm, uint8_t address, uint8_t value) {
 /*
     def write_cs(self, address, value):
         """
@@ -69,8 +67,7 @@ int updi_write_cs(PROGRAMMER * pgm, uint8_t address, uint8_t value)
   return updi_link_stcs(pgm, address, value);
 }
 
-int updi_write_key(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size_type, uint16_t size)
-{
+int updi_write_key(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size_type, uint16_t size) {
 /*
     def write_key(self, size, key):
         """
@@ -84,8 +81,7 @@ int updi_write_key(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size_type,
   return updi_link_key(pgm, buffer, size_type, size);
 }
 
-int updi_read_sib(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size)
-{
+int updi_read_sib(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size) {
 /*
     def read_sib(self):
         """
@@ -98,8 +94,7 @@ int updi_read_sib(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size)
   return updi_link_read_sib(pgm, buffer, size);
 }
 
-int updi_read_byte(PROGRAMMER * pgm, uint32_t address, uint8_t * value)
-{
+int updi_read_byte(const PROGRAMMER *pgm, uint32_t address, uint8_t *value) {
 /*
     def read_byte(self, address):
         """
@@ -113,8 +108,7 @@ int updi_read_byte(PROGRAMMER * pgm, uint32_t address, uint8_t * value)
   return updi_link_ld(pgm, address, value);
 }
 
-int updi_write_byte(PROGRAMMER * pgm, uint32_t address, uint8_t value)
-{
+int updi_write_byte(const PROGRAMMER *pgm, uint32_t address, uint8_t value) {
 /*
     def write_byte(self, address, value):
         """
@@ -128,8 +122,7 @@ int updi_write_byte(PROGRAMMER * pgm, uint32_t address, uint8_t value)
   return updi_link_st(pgm, address, value);
 }
 
-int updi_read_data(PROGRAMMER * pgm, uint32_t address, uint8_t * buffer, uint16_t size)
-{
+int updi_read_data(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uint16_t size) {
 /*
     def read_data(self, address, size):
         """
@@ -174,8 +167,7 @@ int updi_read_data(PROGRAMMER * pgm, uint32_t address, uint8_t * buffer, uint16_
   return updi_link_ld_ptr_inc(pgm, buffer, size);
 }
 
-int updi_write_data(PROGRAMMER * pgm, uint32_t address, uint8_t * buffer, uint16_t size)
-{
+int updi_write_data(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uint16_t size) {
 /*
     def write_data(self, address, data):
         """
@@ -228,8 +220,7 @@ int updi_write_data(PROGRAMMER * pgm, uint32_t address, uint8_t * buffer, uint16
   return updi_link_st_ptr_inc(pgm, buffer, size);
 }
 
-int updi_read_data_words(PROGRAMMER * pgm, uint32_t address, uint8_t * buffer, uint16_t size)
-{
+int updi_read_data_words(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uint16_t size) {
 /*
     def read_data_words(self, address, words):
         """
@@ -275,8 +266,7 @@ int updi_read_data_words(PROGRAMMER * pgm, uint32_t address, uint8_t * buffer, u
   return updi_link_ld_ptr_inc16(pgm, buffer, size);
 }
 
-int updi_write_data_words(PROGRAMMER * pgm, uint32_t address, uint8_t * buffer, uint16_t size)
-{
+int updi_write_data_words(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uint16_t size) {
 /*
     def write_data_words(self, address, data):
         """
diff --git a/src/updi_readwrite.h b/src/updi_readwrite.h
index 9519d179..53e74520 100644
--- a/src/updi_readwrite.h
+++ b/src/updi_readwrite.h
@@ -33,16 +33,16 @@
 extern "C" {
 #endif
 
-int updi_read_cs(PROGRAMMER * pgm, uint8_t address, uint8_t * value);
-int updi_write_cs(PROGRAMMER * pgm, uint8_t address, uint8_t value);
-int updi_write_key(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size_type, uint16_t size);
-int updi_read_sib(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size);
-int updi_read_byte(PROGRAMMER * pgm, uint32_t address, uint8_t * value);
-int updi_write_byte(PROGRAMMER * pgm, uint32_t address, uint8_t value);
-int updi_read_data(PROGRAMMER * pgm, uint32_t address, uint8_t * buffer, uint16_t size);
-int updi_write_data(PROGRAMMER * pgm, uint32_t address, uint8_t * buffer, uint16_t size);
-int updi_read_data_words(PROGRAMMER * pgm, uint32_t address, uint8_t * buffer, uint16_t size);
-int updi_write_data_words(PROGRAMMER * pgm, uint32_t address, uint8_t * buffer, uint16_t size);
+int updi_read_cs(const PROGRAMMER *pgm, uint8_t address, uint8_t *value);
+int updi_write_cs(const PROGRAMMER *pgm, uint8_t address, uint8_t value);
+int updi_write_key(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size_type, uint16_t size);
+int updi_read_sib(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size);
+int updi_read_byte(const PROGRAMMER *pgm, uint32_t address, uint8_t *value);
+int updi_write_byte(const PROGRAMMER *pgm, uint32_t address, uint8_t value);
+int updi_read_data(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uint16_t size);
+int updi_write_data(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uint16_t size);
+int updi_read_data_words(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uint16_t size);
+int updi_write_data_words(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uint16_t size);
 
 #ifdef __cplusplus
 }
diff --git a/src/updi_state.c b/src/updi_state.c
index 2ca583c7..4e2a9b20 100644
--- a/src/updi_state.c
+++ b/src/updi_state.c
@@ -29,37 +29,30 @@
 #include "libavrdude.h"
 #include "updi_state.h"
 
-updi_sib_info* updi_get_sib_info(PROGRAMMER * pgm)
-{
+updi_sib_info* updi_get_sib_info(const PROGRAMMER *pgm) {
   return &((updi_state *)(pgm->cookie))->sib_info;
 }
 
-updi_datalink_mode updi_get_datalink_mode(PROGRAMMER * pgm)
-{
+updi_datalink_mode updi_get_datalink_mode(const PROGRAMMER *pgm) {
   return ((updi_state *)(pgm->cookie))->datalink_mode;
 }
 
-void updi_set_datalink_mode(PROGRAMMER * pgm, updi_datalink_mode mode)
-{
+void updi_set_datalink_mode(const PROGRAMMER *pgm, updi_datalink_mode mode) {
   ((updi_state *)(pgm->cookie))->datalink_mode = mode;
 }
 
-updi_nvm_mode updi_get_nvm_mode(PROGRAMMER * pgm)
-{
+updi_nvm_mode updi_get_nvm_mode(const PROGRAMMER *pgm) {
   return ((updi_state *)(pgm->cookie))->nvm_mode;
 }
 
-void updi_set_nvm_mode(PROGRAMMER * pgm, updi_nvm_mode mode)
-{
+void updi_set_nvm_mode(const PROGRAMMER *pgm, updi_nvm_mode mode) {
   ((updi_state *)(pgm->cookie))->nvm_mode = mode;
 }
 
-updi_rts_mode updi_get_rts_mode(PROGRAMMER * pgm)
-{
+updi_rts_mode updi_get_rts_mode(const PROGRAMMER *pgm) {
   return ((updi_state *)(pgm->cookie))->rts_mode;
 }
 
-void updi_set_rts_mode(PROGRAMMER * pgm, updi_rts_mode mode)
-{
+void updi_set_rts_mode(const PROGRAMMER *pgm, updi_rts_mode mode) {
   ((updi_state *)(pgm->cookie))->rts_mode = mode;
 }
diff --git a/src/updi_state.h b/src/updi_state.h
index a8a2702a..2fa6ca14 100644
--- a/src/updi_state.h
+++ b/src/updi_state.h
@@ -80,13 +80,13 @@ typedef struct
 extern "C" {
 #endif
 
-updi_sib_info* updi_get_sib_info(PROGRAMMER * pgm);
-updi_datalink_mode updi_get_datalink_mode(PROGRAMMER * pgm);
-void updi_set_datalink_mode(PROGRAMMER * pgm, updi_datalink_mode mode);
-updi_nvm_mode updi_get_nvm_mode(PROGRAMMER * pgm);
-void updi_set_nvm_mode(PROGRAMMER * pgm, updi_nvm_mode mode);
-updi_rts_mode updi_get_rts_mode(PROGRAMMER * pgm);
-void updi_set_rts_mode(PROGRAMMER * pgm, updi_rts_mode mode);
+updi_sib_info* updi_get_sib_info(const PROGRAMMER *pgm);
+updi_datalink_mode updi_get_datalink_mode(const PROGRAMMER *pgm);
+void updi_set_datalink_mode(const PROGRAMMER *pgm, updi_datalink_mode mode);
+updi_nvm_mode updi_get_nvm_mode(const PROGRAMMER *pgm);
+void updi_set_nvm_mode(const PROGRAMMER *pgm, updi_nvm_mode mode);
+updi_rts_mode updi_get_rts_mode(const PROGRAMMER *pgm);
+void updi_set_rts_mode(const PROGRAMMER *pgm, updi_rts_mode mode);
 
 #ifdef __cplusplus
 }
diff --git a/src/usb_hidapi.c b/src/usb_hidapi.c
index 5ceca60a..82c2e255 100644
--- a/src/usb_hidapi.c
+++ b/src/usb_hidapi.c
@@ -46,8 +46,7 @@
  * The "baud" parameter is meaningless for USB devices, so we reuse it
  * to pass the desired USB device ID.
  */
-static int usbhid_open(char * port, union pinfo pinfo, union filedescriptor *fd)
-{
+static int usbhid_open(const char *port, union pinfo pinfo, union filedescriptor *fd) {
   hid_device *dev;
   char *serno, *cp2;
   size_t x;
@@ -233,7 +232,7 @@ static void usbhid_close(union filedescriptor *fd)
 }
 
 
-static int usbhid_send(union filedescriptor *fd, const unsigned char *bp, size_t mlen)
+static int usbhid_send(const union filedescriptor *fd, const unsigned char *bp, size_t mlen)
 {
   hid_device *udev = (hid_device *)fd->usb.handle;
   int rv;
@@ -282,7 +281,7 @@ static int usbhid_send(union filedescriptor *fd, const unsigned char *bp, size_t
   return 0;
 }
 
-static int usbhid_recv(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
+static int usbhid_recv(const union filedescriptor *fd, unsigned char *buf, size_t nbytes)
 {
   hid_device *udev = (hid_device *)fd->usb.handle;
   int i, rv;
@@ -320,7 +319,7 @@ static int usbhid_recv(union filedescriptor *fd, unsigned char *buf, size_t nbyt
   return rv;
 }
 
-static int usbhid_drain(union filedescriptor *fd, int display)
+static int usbhid_drain(const union filedescriptor *fd, int display)
 {
   /*
    * There is not much point in trying to flush any data
diff --git a/src/usb_libusb.c b/src/usb_libusb.c
index 0d9ad440..5929be9d 100644
--- a/src/usb_libusb.c
+++ b/src/usb_libusb.c
@@ -62,8 +62,7 @@ static int usb_interface;
  * The "baud" parameter is meaningless for USB devices, so we reuse it
  * to pass the desired USB device ID.
  */
-static int usbdev_open(char * port, union pinfo pinfo, union filedescriptor *fd)
-{
+static int usbdev_open(const char *port, union pinfo pinfo, union filedescriptor *fd) {
   char string[256];
   char product[256];
   struct usb_bus *bus;
@@ -328,7 +327,7 @@ static void usbdev_close(union filedescriptor *fd)
 }
 
 
-static int usbdev_send(union filedescriptor *fd, const unsigned char *bp, size_t mlen)
+static int usbdev_send(const union filedescriptor *fd, const unsigned char *bp, size_t mlen)
 {
   usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
   int rv;
@@ -415,7 +414,7 @@ usb_fill_buf(usb_dev_handle *udev, int maxsize, int ep, int use_interrupt_xfer)
   return 0;
 }
 
-static int usbdev_recv(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
+static int usbdev_recv(const union filedescriptor *fd, unsigned char *buf, size_t nbytes)
 {
   usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
   int i, amnt;
@@ -470,7 +469,7 @@ static int usbdev_recv(union filedescriptor *fd, unsigned char *buf, size_t nbyt
  *
  * This is used for the AVRISP mkII device.
  */
-static int usbdev_recv_frame(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
+static int usbdev_recv_frame(const union filedescriptor *fd, unsigned char *buf, size_t nbytes)
 {
   usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
   int rv, n;
@@ -570,7 +569,7 @@ static int usbdev_recv_frame(union filedescriptor *fd, unsigned char *buf, size_
   return n;
 }
 
-static int usbdev_drain(union filedescriptor *fd, int display)
+static int usbdev_drain(const union filedescriptor *fd, int display)
 {
   /*
    * There is not much point in trying to flush any data
diff --git a/src/usbasp.c b/src/usbasp.c
index 2b4c4831..6a0e00f0 100644
--- a/src/usbasp.c
+++ b/src/usbasp.c
@@ -154,9 +154,9 @@ struct pdata
 // interface - management
 static void usbasp_setup(PROGRAMMER * pgm);
 static void usbasp_teardown(PROGRAMMER * pgm);
-static int usbasp_parseextparms(PROGRAMMER * pgm, LISTID extparms);
+static int usbasp_parseextparms(const PROGRAMMER *pgm, const LISTID extparms);
 // internal functions
-static int usbasp_transmit(PROGRAMMER * pgm, unsigned char receive,
+static int usbasp_transmit(const PROGRAMMER *pgm, unsigned char receive,
 			   unsigned char functionid, const unsigned char *send,
 			   unsigned char *buffer, int buffersize);
 #ifdef USE_LIBUSB_1_0
@@ -165,39 +165,98 @@ static int usbOpenDevice(libusb_device_handle **device, int vendor, const char *
 static int usbOpenDevice(usb_dev_handle **device, int vendor, const char *vendorName, int product, const char *productName);
 #endif
 // interface - prog.
-static int usbasp_open(PROGRAMMER * pgm, char * port);
-static void usbasp_close(PROGRAMMER * pgm);
+static int usbasp_open(PROGRAMMER *pgm, const char *port);
+static void usbasp_close(PROGRAMMER *pgm);
 // dummy functions
-static void usbasp_disable(PROGRAMMER * pgm);
-static void usbasp_enable(PROGRAMMER * pgm);
-static void usbasp_display(PROGRAMMER * pgm, const char * p);
+static void usbasp_disable(const PROGRAMMER *pgm);
+static void usbasp_enable(PROGRAMMER *pgm, const AVRPART *p);
+static void usbasp_display(const PROGRAMMER *pgm, const char *p);
 // universal functions
-static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p);
+static int usbasp_initialize(const PROGRAMMER *pgm, const AVRPART *p);
 // SPI specific functions
-static int usbasp_spi_cmd(PROGRAMMER * pgm, const unsigned char *cmd, unsigned char *res);
-static int usbasp_spi_program_enable(PROGRAMMER * pgm, AVRPART * p);
-static int usbasp_spi_chip_erase(PROGRAMMER * pgm, AVRPART * p);
-static int usbasp_spi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int usbasp_spi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res);
+static int usbasp_spi_program_enable(const PROGRAMMER *pgm, const AVRPART *p);
+static int usbasp_spi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p);
+static int usbasp_spi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                  unsigned int page_size,
                                  unsigned int addr, unsigned int n_bytes);
-static int usbasp_spi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int usbasp_spi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                   unsigned int page_size,
                                   unsigned int addr, unsigned int n_bytes);
-static int usbasp_spi_set_sck_period(PROGRAMMER *pgm, double sckperiod);
+static int usbasp_spi_set_sck_period(const PROGRAMMER *pgm, double sckperiod);
 // TPI specific functions
-static void usbasp_tpi_send_byte(PROGRAMMER * pgm, uint8_t b);
-static int usbasp_tpi_cmd(PROGRAMMER * pgm, const unsigned char *cmd, unsigned char *res);
-static int usbasp_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p);
-static int usbasp_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p);
-static int usbasp_tpi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static void usbasp_tpi_send_byte(const PROGRAMMER *pgm, uint8_t b);
+static int usbasp_tpi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res);
+static int usbasp_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p);
+static int usbasp_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p);
+static int usbasp_tpi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                  unsigned int page_size,
                                  unsigned int addr, unsigned int n_bytes);
-static int usbasp_tpi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int usbasp_tpi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                   unsigned int page_size,
                                   unsigned int addr, unsigned int n_bytes);
-static int usbasp_tpi_set_sck_period(PROGRAMMER *pgm, double sckperiod);
-static int usbasp_tpi_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr, unsigned char * value);
-static int usbasp_tpi_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr, unsigned char data);
+static int usbasp_tpi_set_sck_period(const PROGRAMMER *pgm, double sckperiod);
+static int usbasp_tpi_read_byte(const PROGRAMMER * pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char *value);
+static int usbasp_tpi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char data);
+
+
+// Dispatching wrappers
+
+static int usbasp_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) {
+  return PDATA(pgm)->use_tpi?
+    usbasp_tpi_cmd(pgm, cmd, res):
+    usbasp_spi_cmd(pgm, cmd, res);
+}
+
+static int usbasp_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
+  return PDATA(pgm)->use_tpi?
+    usbasp_tpi_program_enable(pgm, p):
+    usbasp_spi_program_enable(pgm, p);
+}
+
+static int usbasp_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
+  return PDATA(pgm)->use_tpi?
+    usbasp_tpi_chip_erase(pgm, p):
+    usbasp_spi_chip_erase(pgm, p);
+}
+
+static int usbasp_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
+  unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
+
+  return PDATA(pgm)->use_tpi?
+    usbasp_tpi_paged_load(pgm, p, m, page_size, addr, n_bytes):
+    usbasp_spi_paged_load(pgm, p, m, page_size, addr, n_bytes);
+}
+
+static int usbasp_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
+  unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
+
+  return PDATA(pgm)->use_tpi?
+    usbasp_tpi_paged_write(pgm, p, m, page_size, addr, n_bytes):
+    usbasp_spi_paged_write(pgm, p, m, page_size, addr, n_bytes);
+}
+
+static int usbasp_set_sck_period(const PROGRAMMER *pgm, double sckperiod) {
+  return PDATA(pgm)->use_tpi?
+    usbasp_tpi_set_sck_period(pgm, sckperiod):
+    usbasp_spi_set_sck_period(pgm, sckperiod);
+}
+
+static int usbasp_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
+  unsigned long addr, unsigned char * value) {
+
+  return PDATA(pgm)->use_tpi?
+    usbasp_tpi_read_byte(pgm, p, m, addr, value):
+    avr_read_byte_default(pgm, p, m, addr, value);
+}
+
+static int usbasp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
+  unsigned long addr, unsigned char data) {
+
+  return PDATA(pgm)->use_tpi?
+    usbasp_tpi_write_byte(pgm, p, m, addr, data):
+    avr_write_byte_default(pgm, p, m, addr, data);
+}
 
 
 /* Interface - management */
@@ -216,8 +275,7 @@ static void usbasp_teardown(PROGRAMMER * pgm)
   free(pgm->cookie);
 }
 
-static int usbasp_parseextparms(PROGRAMMER * pgm, LISTID extparms)
-{
+static int usbasp_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
   LNODEID ln;
   const char *extended_param;
   int rv = 0;
@@ -270,7 +328,7 @@ static const char *usbasp_get_funcname(unsigned char functionid)
 /*
  * wrapper for usb_control_msg call
  */
-static int usbasp_transmit(PROGRAMMER * pgm,
+static int usbasp_transmit(const PROGRAMMER *pgm,
 			   unsigned char receive, unsigned char functionid,
 			   const unsigned char *send,
 			   unsigned char *buffer, int buffersize)
@@ -491,8 +549,7 @@ static int           didUsbInit = 0;
 
 
 /* Interface - prog. */
-static int usbasp_open(PROGRAMMER * pgm, char * port)
-{
+static int usbasp_open(PROGRAMMER *pgm, const char *port) {
   avrdude_message(MSG_DEBUG, "%s: usbasp_open(\"%s\")\n",
 	    progname, port);
 
@@ -582,29 +639,28 @@ static void usbasp_close(PROGRAMMER * pgm)
 
 
 /* Dummy functions */
-static void usbasp_disable(PROGRAMMER * pgm)
-{
+static void usbasp_disable(const PROGRAMMER *pgm) {
   /* Do nothing. */
 
   return;
 }
 
-static void usbasp_enable(PROGRAMMER * pgm)
-{
+static void usbasp_enable(PROGRAMMER *pgm, const AVRPART *p) {
   /* Do nothing. */
 
   return;
 }
 
-static void usbasp_display(PROGRAMMER * pgm, const char * p)
-{
+static void usbasp_display(const PROGRAMMER *pgm, const char *p) {
   return;
 }
 
 
+
+// @@@
+
 /* Universal functions: for both SPI and TPI */
-static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p)
-{
+static int usbasp_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char temp[4];
   unsigned char res[4];
   IMPORT_PDATA(pgm);
@@ -618,7 +674,7 @@ static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p)
   else
     pdata->capabilities = 0;
 
-  pdata->use_tpi = ((pdata->capabilities & USBASP_CAP_TPI) != 0 && (p->flags & AVRPART_HAS_TPI) != 0) ? 1 : 0;
+  pdata->use_tpi = (pdata->capabilities & USBASP_CAP_TPI) && (p->flags & AVRPART_HAS_TPI);
   // query support for 3 MHz SCK in UsbAsp-flash firmware
   // https://github.com/nofeletru/UsbAsp-flash
   pdata->sck_3mhz = ((pdata->capabilities & USBASP_CAP_3MHZ) != 0) ? 1 :0;
@@ -636,16 +692,6 @@ static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p)
 
     /* connect */
     usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_CONNECT, temp, res, sizeof(res));
-    
-    /* change interface */
-    pgm->program_enable = usbasp_tpi_program_enable;
-    pgm->chip_erase     = usbasp_tpi_chip_erase;
-    pgm->cmd            = usbasp_tpi_cmd;
-    pgm->read_byte      = usbasp_tpi_read_byte;
-    pgm->write_byte     = usbasp_tpi_write_byte;
-    pgm->paged_write    = usbasp_tpi_paged_write;
-    pgm->paged_load     = usbasp_tpi_paged_load;
-    pgm->set_sck_period	= usbasp_tpi_set_sck_period;
   }
   else
   {
@@ -654,16 +700,6 @@ static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p)
 
     /* connect to target device */
     usbasp_transmit(pgm, 1, USBASP_FUNC_CONNECT, temp, res, sizeof(res));
-
-    /* change interface */
-    pgm->program_enable = usbasp_spi_program_enable;
-    pgm->chip_erase     = usbasp_spi_chip_erase;
-    pgm->cmd            = usbasp_spi_cmd;
-    pgm->read_byte      = avr_read_byte_default;
-    pgm->write_byte     = avr_write_byte_default;
-    pgm->paged_write    = usbasp_spi_paged_write;
-    pgm->paged_load     = usbasp_spi_paged_load;
-    pgm->set_sck_period	= usbasp_spi_set_sck_period;
   }
 
   /* wait, so device is ready to receive commands */
@@ -673,7 +709,7 @@ static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p)
 }
 
 /* SPI specific functions */
-static int usbasp_spi_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
+static int usbasp_spi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd,
                    unsigned char *res)
 {
   avrdude_message(MSG_DEBUG, "%s: usbasp_spi_cmd(0x%02x, 0x%02x, 0x%02x, 0x%02x)%s",
@@ -698,8 +734,7 @@ static int usbasp_spi_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
   return 0;
 }
 
-static int usbasp_spi_program_enable(PROGRAMMER * pgm, AVRPART * p)
-{
+static int usbasp_spi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char res[4];
   unsigned char cmd[4];
   memset(cmd, 0, sizeof(cmd));
@@ -722,8 +757,7 @@ static int usbasp_spi_program_enable(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static int usbasp_spi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+static int usbasp_spi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char cmd[4];
   unsigned char res[4];
 
@@ -746,10 +780,9 @@ static int usbasp_spi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static int usbasp_spi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-                                 unsigned int page_size,
-                                 unsigned int address, unsigned int n_bytes)
-{
+static int usbasp_spi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
+  unsigned int page_size, unsigned int address, unsigned int n_bytes) {
+
   int n;
   unsigned char cmd[4];
   int wbytes = n_bytes;
@@ -813,10 +846,9 @@ static int usbasp_spi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return n_bytes;
 }
 
-static int usbasp_spi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-                                  unsigned int page_size,
-                                  unsigned int address, unsigned int n_bytes)
-{
+static int usbasp_spi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
+  unsigned int page_size, unsigned int address, unsigned int n_bytes) {
+
   int n;
   unsigned char cmd[4];
   int wbytes = n_bytes;
@@ -907,8 +939,7 @@ static struct sckoptions_t usbaspSCKoptions[] = {
  * Set sck period (in seconds)
  * Find next possible sck period and write it to the programmer.
  */
-static int usbasp_spi_set_sck_period(PROGRAMMER *pgm, double sckperiod)
-{
+static int usbasp_spi_set_sck_period(const PROGRAMMER *pgm, double sckperiod) {
   char clockoption = USBASP_ISP_SCK_AUTO;
   unsigned char res[4];
   unsigned char cmd[4];
@@ -980,8 +1011,7 @@ static int usbasp_spi_set_sck_period(PROGRAMMER *pgm, double sckperiod)
 }
 
 /* TPI specific functions */
-static void usbasp_tpi_send_byte(PROGRAMMER * pgm, uint8_t b)
-{
+static void usbasp_tpi_send_byte(const PROGRAMMER *pgm, uint8_t b) {
   unsigned char temp[4];
   memset(temp, 0, sizeof(temp));
 
@@ -991,8 +1021,7 @@ static void usbasp_tpi_send_byte(PROGRAMMER * pgm, uint8_t b)
 }
 
 
-static int usbasp_tpi_recv_byte(PROGRAMMER * pgm)
-{
+static int usbasp_tpi_recv_byte(const PROGRAMMER *pgm) {
   unsigned char temp[4];
   memset(temp, 0, sizeof(temp));
 
@@ -1006,8 +1035,7 @@ static int usbasp_tpi_recv_byte(PROGRAMMER * pgm)
 }
 
 
-static int usbasp_tpi_nvm_waitbusy(PROGRAMMER * pgm)
-{
+static int usbasp_tpi_nvm_waitbusy(const PROGRAMMER *pgm) {
   int retry;
 
   avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_nvm_waitbusy() ...", progname);
@@ -1028,14 +1056,12 @@ static int usbasp_tpi_nvm_waitbusy(PROGRAMMER * pgm)
   return -1;
 }
 
-static int usbasp_tpi_cmd(PROGRAMMER * pgm, const unsigned char *cmd, unsigned char *res)
-{
+static int usbasp_tpi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) {
   avrdude_message(MSG_INFO, "%s: error: spi_cmd used in TPI mode: not allowed\n", progname);
   return -1;
 }
 
-static int usbasp_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p)
-{
+static int usbasp_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
   int retry;
 
   avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_program_enable()\n", progname);
@@ -1075,8 +1101,7 @@ static int usbasp_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static int usbasp_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+static int usbasp_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
   int pr_0;
   int pr_1;
   int nvm_cmd;
@@ -1117,10 +1142,9 @@ static int usbasp_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static int usbasp_tpi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-                                 unsigned int page_size,
-                                 unsigned int addr, unsigned int n_bytes)
-{
+static int usbasp_tpi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
+  unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
+
   unsigned char cmd[4];
   unsigned char* dptr;
   int readed, clen, n;
@@ -1160,10 +1184,9 @@ static int usbasp_tpi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return n_bytes;
 }
 
-static int usbasp_tpi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-                                  unsigned int page_size,
-                                  unsigned int addr, unsigned int n_bytes)
-{
+static int usbasp_tpi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
+  unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
+
   unsigned char cmd[4];
   unsigned char* sptr;
   int writed, clen, n;
@@ -1227,12 +1250,11 @@ static int usbasp_tpi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return n_bytes;
 }
 
-static int usbasp_tpi_set_sck_period(PROGRAMMER *pgm, double sckperiod)
-{
+static int usbasp_tpi_set_sck_period(const PROGRAMMER *pgm, double sckperiod) {
   return 0;
 }
-static int usbasp_tpi_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr, unsigned char * value)
-{
+
+static int usbasp_tpi_read_byte(const PROGRAMMER * pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char *value) {
   unsigned char cmd[4];
   int n;
   uint16_t pr;
@@ -1257,15 +1279,15 @@ static int usbasp_tpi_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsig
   return 0;
 }
 
-static int usbasp_tpi_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr, unsigned char data)
-{
+static int usbasp_tpi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
+  unsigned long addr, unsigned char data) { // FIXME: use avr_write_byte_cache() when implemented
+
   avrdude_message(MSG_INFO, "%s: error: usbasp_write_byte in TPI mode: all writes have to be done at page level\n", progname);
   return -1;
 }
 
 
-void usbasp_initpgm(PROGRAMMER * pgm)
-{
+void usbasp_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "usbasp");
 
   /*
@@ -1276,23 +1298,23 @@ void usbasp_initpgm(PROGRAMMER * pgm)
   pgm->display        = usbasp_display;
   pgm->enable         = usbasp_enable;
   pgm->disable        = usbasp_disable;
-  pgm->program_enable = usbasp_spi_program_enable;
-  pgm->chip_erase     = usbasp_spi_chip_erase;
-  pgm->cmd            = usbasp_spi_cmd;
+  pgm->program_enable = usbasp_program_enable;
+  pgm->chip_erase     = usbasp_chip_erase;
+  pgm->cmd            = usbasp_cmd;
   pgm->open           = usbasp_open;
   pgm->close          = usbasp_close;
-  pgm->read_byte      = avr_read_byte_default;
-  pgm->write_byte     = avr_write_byte_default;
+  pgm->read_byte      = usbasp_read_byte;
+  pgm->write_byte     = usbasp_write_byte;
 
   /*
    * optional functions
    */
 
-  pgm->paged_write    = usbasp_spi_paged_write;
-  pgm->paged_load     = usbasp_spi_paged_load;
+  pgm->paged_write    = usbasp_paged_write;
+  pgm->paged_load     = usbasp_paged_load;
   pgm->setup          = usbasp_setup;
   pgm->teardown       = usbasp_teardown;
-  pgm->set_sck_period = usbasp_spi_set_sck_period;
+  pgm->set_sck_period = usbasp_set_sck_period;
   pgm->parseextparams = usbasp_parseextparms;
 
 }
@@ -1300,16 +1322,14 @@ void usbasp_initpgm(PROGRAMMER * pgm)
 
 #else /* HAVE_LIBUSB */
 
-static int usbasp_nousb_open (struct programmer_t *pgm, char * name)
-{
+static int usbasp_nousb_open(PROGRAMMER *pgm, const char *name) {
   avrdude_message(MSG_INFO, "%s: error: no usb support. please compile again with libusb installed.\n",
 	  progname);
 
   return -1;
 }
 
-void usbasp_initpgm(PROGRAMMER * pgm)
-{
+void usbasp_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "usbasp");
 
   pgm->open           = usbasp_nousb_open;
diff --git a/src/usbasp.h b/src/usbasp.h
index 11f98293..b91aeaaf 100644
--- a/src/usbasp.h
+++ b/src/usbasp.h
@@ -130,7 +130,7 @@ extern "C" {
 #endif
 
 extern const char usbasp_desc[];
-void usbasp_initpgm (PROGRAMMER * pgm);
+void usbasp_initpgm(PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/usbtiny.c b/src/usbtiny.c
index 75c88be6..5cdaad4a 100644
--- a/src/usbtiny.c
+++ b/src/usbtiny.c
@@ -61,9 +61,6 @@ typedef	unsigned int	uint_t;
 typedef	unsigned long	ulong_t;
 #endif
 
-extern int avr_write_byte_default ( PROGRAMMER* pgm, AVRPART* p,
-				    AVRMEM* mem, ulong_t addr,
-				    unsigned char data );
 /*
  * Private data for this programmer.
  */
@@ -95,7 +92,7 @@ static void usbtiny_teardown(PROGRAMMER * pgm)
 }
 
 // Wrapper for simple usb_control_msg messages
-static int usb_control (PROGRAMMER * pgm,
+static int usb_control (const PROGRAMMER *pgm,
 			unsigned int requestid, unsigned int val, unsigned int index )
 {
   int nbytes;
@@ -114,7 +111,7 @@ static int usb_control (PROGRAMMER * pgm,
 }
 
 // Wrapper for simple usb_control_msg messages to receive data from programmer
-static int usb_in (PROGRAMMER * pgm,
+static int usb_in (const PROGRAMMER *pgm,
 		   unsigned int requestid, unsigned int val, unsigned int index,
 		   unsigned char* buffer, int buflen, int bitclk )
 {
@@ -144,8 +141,7 @@ static int usb_in (PROGRAMMER * pgm,
 }
 
 // Report the number of retries, and reset the counter.
-static void check_retries (PROGRAMMER * pgm, const char* operation)
-{
+static void check_retries (const PROGRAMMER *pgm, const char *operation) {
   if (PDATA(pgm)->retries > 0 && quell_progress < 2) {
     avrdude_message(MSG_INFO, "%s: %d retries during %s\n", progname,
            PDATA(pgm)->retries, operation);
@@ -154,7 +150,7 @@ static void check_retries (PROGRAMMER * pgm, const char* operation)
 }
 
 // Wrapper for simple usb_control_msg messages to send data to programmer
-static int usb_out (PROGRAMMER * pgm,
+static int usb_out (const PROGRAMMER *pgm,
 		    unsigned int requestid, unsigned int val, unsigned int index,
 		    unsigned char* buffer, int buflen, int bitclk )
 {
@@ -221,8 +217,7 @@ static unsigned short tpi_frame(unsigned char b) {
 
 /* Transmit a single byte encapsulated in a 32-bit transfer. Unused
    bits are padded with 1s. */
-static int usbtiny_tpi_tx(PROGRAMMER *pgm, unsigned char b0)
-{
+static int usbtiny_tpi_tx(const PROGRAMMER *pgm, unsigned char b0) {
   unsigned char res[4];
 
   if (usb_in(pgm, USBTINY_SPI, tpi_frame(b0), 0xffff,
@@ -235,7 +230,7 @@ static int usbtiny_tpi_tx(PROGRAMMER *pgm, unsigned char b0)
 
 /* Transmit a two bytes encapsulated in a 32-bit transfer. Unused
    bits are padded with 1s. */
-static int usbtiny_tpi_txtx(PROGRAMMER *pgm,
+static int usbtiny_tpi_txtx(const PROGRAMMER *pgm,
 			    unsigned char b0, unsigned char b1)
 {
   unsigned char res[4];
@@ -253,8 +248,7 @@ static int usbtiny_tpi_txtx(PROGRAMMER *pgm,
    the start bit of the byte being received arrives within at most 2
    TPICLKs.  We ensure this by calling avr_tpi_program_enable() with
    delay==TPIPCR_GT_0b.  */
-static int usbtiny_tpi_txrx(PROGRAMMER *pgm, unsigned char b0)
-{
+static int usbtiny_tpi_txrx(const PROGRAMMER *pgm, unsigned char b0) {
   unsigned char res[4], r;
   short w;
 
@@ -287,7 +281,7 @@ static int usbtiny_tpi_txrx(PROGRAMMER *pgm, unsigned char b0)
 // a function. Here we wrap this request for an operation so that we
 // can just specify the part and operation and it'll do the right stuff
 // to get the information from AvrDude and send to the USBtiny
-static int usbtiny_avr_op (PROGRAMMER * pgm, AVRPART * p,
+static int usbtiny_avr_op (const PROGRAMMER *pgm, const AVRPART *p,
 			   int op,
 			   unsigned char *res)
 {
@@ -307,11 +301,10 @@ static int usbtiny_avr_op (PROGRAMMER * pgm, AVRPART * p,
 
 /* Find a device with the correct VID/PID match for USBtiny */
 
-static	int	usbtiny_open(PROGRAMMER* pgm, char* name)
-{
+static int usbtiny_open(PROGRAMMER *pgm, const char *name) {
   struct usb_bus      *bus;
   struct usb_device   *dev = 0;
-  char *bus_name = NULL;
+  const char *bus_name = NULL;
   char *dev_name = NULL;
   int vid, pid;
 
@@ -402,8 +395,7 @@ static	void usbtiny_close ( PROGRAMMER* pgm )
 
 /* A simple calculator function determines the maximum size of data we can
    shove through a USB connection without getting errors */
-static void usbtiny_set_chunk_size (PROGRAMMER * pgm, int period)
-{
+static void usbtiny_set_chunk_size (const PROGRAMMER *pgm, int period) {
   PDATA(pgm)->chunk_size = CHUNK_SIZE;       // start with the maximum (default)
   while	(PDATA(pgm)->chunk_size > 8 && period > 16) {
     // Reduce the chunk size for a slow SCK to reduce
@@ -415,8 +407,7 @@ static void usbtiny_set_chunk_size (PROGRAMMER * pgm, int period)
 
 /* Given a SCK bit-clock speed (in useconds) we verify its an OK speed and tell the
    USBtiny to update itself to the new frequency */
-static int usbtiny_set_sck_period (PROGRAMMER *pgm, double v)
-{
+static int usbtiny_set_sck_period (const PROGRAMMER *pgm, double v) {
   PDATA(pgm)->sck_period = (int)(v * 1e6 + 0.5);   // convert from us to 'int', the 0.5 is for rounding up
 
   // Make sure its not 0, as that will confuse the usbtiny
@@ -441,8 +432,7 @@ static int usbtiny_set_sck_period (PROGRAMMER *pgm, double v)
 }
 
 
-static int usbtiny_initialize (PROGRAMMER *pgm, AVRPART *p )
-{
+static int usbtiny_initialize (const PROGRAMMER *pgm, const AVRPART *p ) {
   unsigned char res[4];        // store the response from usbtinyisp
   int tries;
 
@@ -511,8 +501,7 @@ static int usbtiny_initialize (PROGRAMMER *pgm, AVRPART *p )
   return 0;
 }
 
-static int usbtiny_setpin(struct programmer_t * pgm, int pinfunc, int value)
-{
+static int usbtiny_setpin(const PROGRAMMER *pgm, int pinfunc, int value) {
   /* USBtiny is not a bit bang device, but it can set RESET */
   if(pinfunc == PIN_AVR_RESET) {
     if (usb_control(pgm, USBTINY_POWERUP,
@@ -526,8 +515,7 @@ static int usbtiny_setpin(struct programmer_t * pgm, int pinfunc, int value)
 }
 
 /* Tell the USBtiny to release the output pins, etc */
-static void usbtiny_powerdown(PROGRAMMER * pgm)
-{
+static void usbtiny_powerdown(const PROGRAMMER *pgm) {
   if (!PDATA(pgm)->usb_handle) {
     return;                 // wasn't connected in the first place
   }
@@ -536,8 +524,7 @@ static void usbtiny_powerdown(PROGRAMMER * pgm)
 
 /* Send a 4-byte SPI command to the USBtinyISP for execution
    This procedure is used by higher-level Avrdude procedures */
-static int usbtiny_cmd(PROGRAMMER * pgm, const unsigned char *cmd, unsigned char *res)
-{
+static int usbtiny_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) {
   int nbytes;
 
   // Make sure its empty so we don't read previous calls if it fails
@@ -558,7 +545,7 @@ static int usbtiny_cmd(PROGRAMMER * pgm, const unsigned char *cmd, unsigned char
 	  res[2] == cmd[1]);              // AVR's do a delayed-echo thing
 }
 
-int usbtiny_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd,
+int usbtiny_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd,
 			int cmd_len, unsigned char *res, int res_len)
 {
   unsigned char b0, b1;
@@ -594,8 +581,7 @@ int usbtiny_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd,
   return 0;
 }
 
-static int usbtiny_spi(struct programmer_t * pgm, const unsigned char *cmd, unsigned char *res, int count)
-{
+static int usbtiny_spi(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res, int count) {
   int i;
 
   // Clear the receive buffer so we don't read old data in case of failure
@@ -616,8 +602,7 @@ static int usbtiny_spi(struct programmer_t * pgm, const unsigned char *cmd, unsi
 }
 
 /* Send the chip-erase command */
-static int usbtiny_chip_erase(PROGRAMMER * pgm, AVRPART * p)
-{
+static int usbtiny_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char res[4];
 
   if (p->flags & AVRPART_HAS_TPI)
@@ -642,9 +627,11 @@ static int usbtiny_chip_erase(PROGRAMMER * pgm, AVRPART * p)
 }
 
 // These are required functions but don't actually do anything
-static	void	usbtiny_enable ( PROGRAMMER* pgm ) {}
+static void usbtiny_enable(PROGRAMMER *pgm, const AVRPART *p) {
+}
 
-static void usbtiny_disable ( PROGRAMMER* pgm ) {}
+static void usbtiny_disable(const PROGRAMMER *pgm) {
+}
 
 
 /* To speed up programming and reading, we do a 'chunked' read.
@@ -652,7 +639,7 @@ static void usbtiny_disable ( PROGRAMMER* pgm ) {}
  *  given to read in the data. Much faster than sending a 4-byte SPI request
  *  per byte
 */
-static int usbtiny_paged_load (PROGRAMMER * pgm, AVRPART * p, AVRMEM* m,
+static int usbtiny_paged_load (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                unsigned int page_size,
                                unsigned int addr, unsigned int n_bytes)
 {
@@ -722,7 +709,7 @@ static int usbtiny_paged_load (PROGRAMMER * pgm, AVRPART * p, AVRMEM* m,
  *  given to write the data. Much faster than sending a 4-byte SPI request
  *  per byte.
 */
-static int usbtiny_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+static int usbtiny_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
                                unsigned int page_size,
                                unsigned int addr, unsigned int n_bytes)
 {
@@ -783,8 +770,7 @@ static int usbtiny_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return n_bytes;
 }
 
-static int usbtiny_program_enable(PROGRAMMER *pgm, AVRPART *p)
-{
+static int usbtiny_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
   unsigned char buf[4];
 
   if (p->flags & AVRPART_HAS_TPI)
@@ -793,8 +779,7 @@ static int usbtiny_program_enable(PROGRAMMER *pgm, AVRPART *p)
     return usbtiny_avr_op(pgm, p, AVR_OP_PGM_ENABLE, buf);
 }
 
-void usbtiny_initpgm ( PROGRAMMER* pgm )
-{
+void usbtiny_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "USBtiny");
 
   /* Mandatory Functions */
@@ -826,16 +811,14 @@ void usbtiny_initpgm ( PROGRAMMER* pgm )
 
 // Give a proper error if we were not compiled with libusb
 
-static int usbtiny_nousb_open(struct programmer_t *pgm, char * name)
-{
+static int usbtiny_nousb_open(PROGRAMMER *pgm, const char *name) {
   avrdude_message(MSG_INFO, "%s: error: no usb support. Please compile again with libusb installed.\n",
 	  progname);
 
   return -1;
 }
 
-void usbtiny_initpgm(PROGRAMMER * pgm)
-{
+void usbtiny_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "usbtiny");
 
   pgm->open = usbtiny_nousb_open;
diff --git a/src/usbtiny.h b/src/usbtiny.h
index b663ced1..153d75c4 100644
--- a/src/usbtiny.h
+++ b/src/usbtiny.h
@@ -59,7 +59,7 @@ extern "C" {
 #endif
 
 extern const char usbtiny_desc[];
-void usbtiny_initpgm (PROGRAMMER * pgm);
+void usbtiny_initpgm(PROGRAMMER *pgm);
 
 #ifdef __cplusplus
 }
diff --git a/src/wiring.c b/src/wiring.c
index c0a68055..204bde5c 100644
--- a/src/wiring.c
+++ b/src/wiring.c
@@ -109,8 +109,7 @@ static void wiring_teardown(PROGRAMMER * pgm)
   stk500v2_teardown(pgm);
 }
 
-static int wiring_parseextparms(PROGRAMMER * pgm, LISTID extparms)
-{
+static int wiring_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
   LNODEID ln;
   const char *extended_param;
   int rv = 0;
@@ -143,8 +142,7 @@ static int wiring_parseextparms(PROGRAMMER * pgm, LISTID extparms)
   return rv;
 }
 
-static int wiring_open(PROGRAMMER * pgm, char * port)
-{
+static int wiring_open(PROGRAMMER *pgm, const char *port) {
   int timetosnooze;
   void *mycookie = STK500V2PDATA(pgm)->chained_pdata;
   union pinfo pinfo;
@@ -205,8 +203,7 @@ static void wiring_close(PROGRAMMER * pgm)
 
 const char wiring_desc[] = "http://wiring.org.co/, Basically STK500v2 protocol, with some glue to trigger the bootloader.";
 
-void wiring_initpgm(PROGRAMMER * pgm)
-{
+void wiring_initpgm(PROGRAMMER *pgm) {
   /* The Wiring bootloader uses a near-complete STK500v2 protocol. */
 
   stk500v2_initpgm(pgm);
diff --git a/src/wiring.h b/src/wiring.h
index ed1362de..dbe42b8b 100644
--- a/src/wiring.h
+++ b/src/wiring.h
@@ -22,7 +22,7 @@
 #define wiring_h__
 
 extern const char wiring_desc[];
-void wiring_initpgm(PROGRAMMER * pgm);
+void wiring_initpgm(PROGRAMMER *pgm);
 
 #endif
 
diff --git a/src/xbee.c b/src/xbee.c
index 1f974e55..dbc0f511 100644
--- a/src/xbee.c
+++ b/src/xbee.c
@@ -30,12 +30,12 @@
 
 #include "ac_cfg.h"
 
-#include <sys/time.h> /* gettimeofday() */
+#include <sys/time.h>
 
-#include <stdio.h> /* sscanf() */
-#include <stdlib.h> /* malloc() */
-#include <string.h> /* memmove() etc. */
-#include <unistd.h> /* usleep() */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
 #include "avrdude.h"
 #include "libavrdude.h"
@@ -43,27 +43,6 @@
 #include "stk500.h"
 #include "xbee.h"
 
-/*
- * For non-direct mode (Over-The-Air) we need to issue XBee commands
- * to the remote XBee in order to reset the AVR CPU and initiate the
- * XBeeBoot bootloader.
- *
- * XBee IO port 3 is a somewhat-arbitrarily chosen pin that can be
- * connected directly to the AVR reset pin.
- *
- * Note that port 7 was not used because it is the only pin that can
- * be used as a CTS flow control output.  Port 6 is the only pin that
- * can be used as an RTS flow control input.
- *
- * Some off-the-shelf Arduino shields select a different pin.  For
- * example this one uses XBee IO port 7.
- *
- * https://wiki.dfrobot.com/Xbee_Shield_For_Arduino__no_Xbee___SKU_DFR0015_
- */
-#ifndef XBEE_DEFAULT_RESET_PIN
-#define XBEE_DEFAULT_RESET_PIN 3
-#endif
-
 /*
  * After eight seconds the AVR bootloader watchdog will kick in.  But
  * to allow for the possibility of eight seconds upstream and another
@@ -125,8 +104,7 @@
  * Read signature bytes - Direct copy of the Arduino behaviour to
  * satisfy Optiboot.
  */
-static int xbee_read_sig_bytes(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m)
-{
+static int xbee_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m) {
   unsigned char buf[32];
 
   /* Signature byte reads are always 3 bytes. */
@@ -318,7 +296,7 @@ static void XBeeBootSessionInit(struct XBeeBootSession *xbs) {
 
 #define xbeebootsession(fdp) (struct XBeeBootSession*)((fdp)->pfd)
 
-static void xbeedev_setresetpin(union filedescriptor *fdp, int xbeeResetPin)
+static void xbeedev_setresetpin(const union filedescriptor *fdp, int xbeeResetPin)
 {
   struct XBeeBootSession *xbs = xbeebootsession(fdp);
   xbs->xbeeResetPin = xbeeResetPin;
@@ -1106,7 +1084,7 @@ static void xbeedev_close(union filedescriptor *fdp)
   xbeedev_free(xbs);
 }
 
-static int xbeedev_open(char *port, union pinfo pinfo,
+static int xbeedev_open(const char *port, union pinfo pinfo,
                         union filedescriptor *fdp)
 {
   /*
@@ -1329,7 +1307,7 @@ static int xbeedev_open(char *port, union pinfo pinfo,
   return 0;
 }
 
-static int xbeedev_send(union filedescriptor *fdp,
+static int xbeedev_send(const union filedescriptor *fdp,
                         const unsigned char *buf, size_t buflen)
 {
   struct XBeeBootSession *xbs = xbeebootsession(fdp);
@@ -1453,7 +1431,7 @@ static int xbeedev_send(union filedescriptor *fdp,
   return 0;
 }
 
-static int xbeedev_recv(union filedescriptor *fdp,
+static int xbeedev_recv(const union filedescriptor *fdp,
                         unsigned char *buf, size_t buflen)
 {
   struct XBeeBootSession *xbs = xbeebootsession(fdp);
@@ -1528,7 +1506,7 @@ static int xbeedev_recv(union filedescriptor *fdp,
   return -1;
 }
 
-static int xbeedev_drain(union filedescriptor *fdp, int display)
+static int xbeedev_drain(const union filedescriptor *fdp, int display)
 {
   struct XBeeBootSession *xbs = xbeebootsession(fdp);
 
@@ -1547,7 +1525,7 @@ static int xbeedev_drain(union filedescriptor *fdp, int display)
   return 0;
 }
 
-static int xbeedev_set_dtr_rts(union filedescriptor *fdp, int is_on)
+static int xbeedev_set_dtr_rts(const union filedescriptor *fdp, int is_on)
 {
   struct XBeeBootSession *xbs = xbeebootsession(fdp);
 
@@ -1587,8 +1565,7 @@ static struct serial_device xbee_serdev_frame = {
   .flags = SERDEV_FL_NONE,
 };
 
-static int xbee_getsync(PROGRAMMER *pgm)
-{
+static int xbee_getsync(const PROGRAMMER *pgm) {
   unsigned char buf[2], resp[2];
 
   /*
@@ -1637,8 +1614,7 @@ static int xbee_getsync(PROGRAMMER *pgm)
   return 0;
 }
 
-static int xbee_open(PROGRAMMER *pgm, char *port)
-{
+static int xbee_open(PROGRAMMER *pgm, const char *port) {
   union pinfo pinfo;
   strcpy(pgm->port, port);
   pinfo.serialinfo.baud = pgm->baudrate;
@@ -1653,13 +1629,7 @@ static int xbee_open(PROGRAMMER *pgm, char *port)
     return -1;
   }
 
-  /*
-   * NB: Because we are making use of the STK500 programmer
-   * implementation, we can't readily use pgm->cookie ourselves.  We
-   * can use the private "flag" field in the PROGRAMMER though, as
-   * it's unused by stk500.c.
-   */
-  xbeedev_setresetpin(&pgm->fd, pgm->flag);
+  xbeedev_setresetpin(&pgm->fd, PDATA(pgm)->xbeeResetPin);
 
   /* Clear DTR and RTS */
   serial_set_dtr_rts(&pgm->fd, 0);
@@ -1723,8 +1693,7 @@ static void xbee_close(PROGRAMMER *pgm)
   pgm->fd.pfd = NULL;
 }
 
-static int xbee_parseextparms(PROGRAMMER *pgm, LISTID extparms)
-{
+static int xbee_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
   LNODEID ln;
   const char *extended_param;
   int rc = 0;
@@ -1744,7 +1713,7 @@ static int xbee_parseextparms(PROGRAMMER *pgm, LISTID extparms)
         continue;
       }
 
-      pgm->flag = resetpin;
+      PDATA(pgm)->xbeeResetPin = resetpin;
       continue;
     }
 
@@ -1759,12 +1728,11 @@ static int xbee_parseextparms(PROGRAMMER *pgm, LISTID extparms)
 
 const char xbee_desc[] = "XBee Series 2 Over-The-Air (XBeeBoot)";
 
-void xbee_initpgm(PROGRAMMER *pgm)
-{
+void xbee_initpgm(PROGRAMMER *pgm) {
   /*
    * This behaves like an Arduino, but with packet encapsulation of
    * the serial streams, XBee device management, and XBee GPIO for the
-   * Auto-Reset feature.
+   * Auto-Reset feature. stk500.c sets PDATA(pgm)->xbeeResetPin
    */
   stk500_initpgm(pgm);
 
@@ -1773,13 +1741,5 @@ void xbee_initpgm(PROGRAMMER *pgm)
   pgm->open = xbee_open;
   pgm->close = xbee_close;
 
-  /*
-   * NB: Because we are making use of the STK500 programmer
-   * implementation, we can't readily use pgm->cookie ourselves, nor
-   * can we override setup() and teardown().  We can use the private
-   * "flag" field in the PROGRAMMER though, as it's unused by
-   * stk500.c.
-   */
   pgm->parseextparams = xbee_parseextparms;
-  pgm->flag = XBEE_DEFAULT_RESET_PIN;
 }
diff --git a/src/xbee.h b/src/xbee.h
index 9830d853..00a1682b 100644
--- a/src/xbee.h
+++ b/src/xbee.h
@@ -22,6 +22,27 @@
 #define xbee_h__
 
 extern const char xbee_desc[];
-void xbee_initpgm (PROGRAMMER * pgm);
+void xbee_initpgm(PROGRAMMER *pgm);
+
+/*
+ * For non-direct mode (Over-The-Air) we need to issue XBee commands
+ * to the remote XBee in order to reset the AVR CPU and initiate the
+ * XBeeBoot bootloader.
+ *
+ * XBee IO port 3 is a somewhat-arbitrarily chosen pin that can be
+ * connected directly to the AVR reset pin.
+ *
+ * Note that port 7 was not used because it is the only pin that can
+ * be used as a CTS flow control output.  Port 6 is the only pin that
+ * can be used as an RTS flow control input.
+ *
+ * Some off-the-shelf Arduino shields select a different pin.  For
+ * example this one uses XBee IO port 7.
+ *
+ * https://wiki.dfrobot.com/Xbee_Shield_For_Arduino__no_Xbee___SKU_DFR0015_
+ */
+#ifndef XBEE_DEFAULT_RESET_PIN
+#define XBEE_DEFAULT_RESET_PIN 3
+#endif
 
 #endif