Why do I have to disconnect and reconnect the Microchip ICD3 after every programming?
I haven't really solved the problem, but I've found a rather ugly workaround that is just barely better than nothing.

I've written the following python-script to reset the USB-port. This gets the ICD 3 working again when it stops working, without having to unplug and plug it again.

import os
import sys
import fcntl
import re
lsusb=os.popen("lsusb -d 04d8:9009").read().strip()
if not lsusb:
    print "No ICD3 seems to be connected."
    sys.exit(0)
bus,busid,device,deviceid=re.split(r'[\t :]',lsusb)[:4]
if bus.lower()!="bus" or device.lower()!="device": raise Exception("Unexpected output from lsusb command. Maybe it doesn't work as is expected by this program, any longer")
dev="/dev/bus/usb/%s/%s"%(busid,deviceid)
print "Resetting USB ICD3 device at",dev
fd=os.open(dev,os.O_WRONLY)
USBDEVFS_RESET = ord('U') &lt;&lt; (4*2) | 20 
fcntl.ioctl(fd,USBDEVFS_RESET,0)
os.close(fd)


Stackexchange isn't the optimum format to deliver python-programs, but I believe copy-pasting the above to a file called fixicd3.py, and then runnig it using:

python fixicd3.py


will work.
This is for linux only, and may not work with USB-hubs (I haven't tried). Also, the program is a complete and utter hack.

Adding the above script as a "Run after build" command in MPLabX works almost ok for programming the board. However, for debugging, it doesn't solve the problem, since when connection is lost during a debugging session, resetting the USB device does no good (you can't continue with the same debugging session then).