--- uisp-20050207/src/DAPA.h 2004-10-14 16:50:36.000000000 +0200 +++ uisp-20050207-usb-bbpg/src/DAPA.h 2005-10-02 20:33:46.000000000 +0200 @@ -45,7 +45,7 @@ public: enum TPaType{ PAT_DAPA, PAT_STK200, PAT_ABB, PAT_ATDH, PAT_PARAVRISP, PAT_BSD, PAT_FBPRG, PAT_DT006, PAT_ETT, PAT_MAXI, PAT_XIL, - PAT_DASA, PAT_DASA2, PAT_DASA3, PAT_DM04 }; + PAT_DASA, PAT_DASA2, PAT_DASA3, PAT_DM04, PAT_BBPG }; private: int mosi_invert; --- uisp-20050207/src/ftdibb.h 2005-10-02 21:00:15.000000000 +0200 +++ uisp-20050207-usb-bbpg/src/ftdibb.h 2005-10-02 20:25:53.000000000 +0200 @@ -0,0 +1,50 @@ +/* ftdibb.h written by Guido Socher + * copyright GPL + * FTDI bit bang library + */ + +#ifndef __ftdibb_h__ +#define __ftdibb_h__ + +#include +// To use this library you need write access to /proc/bus/usb +// This is because we use libusb to send the urb message. +// You can write a suid program to make it usable for a normal user (chmod 4755) + +// Call sequence: +// ftdibb_open +// ftdibb_setBaudRate for baud rate 9600 (reasonable value bit bang) +// ftdibb_setBitMode with onoff=1 +// +extern usb_dev_handle *ftdibb_open(int vendor, int product, int silent); +extern int ftdibb_setBaudRate(usb_dev_handle *dev_handle,int baudrate); +// enable or disable bitbang mode. pin_bitmask defines which pins are input and which are +// output (a one is an output, all 8 pins output = 0xff). +// dev_handle is whatever you get returned when you do a ftdibb_open +// +// Pin Definitions +// FT245BM FT232BM Bit-Bang Data bit +// Data0 TXD Data0 +// Data1 RXD Data1 +// Data2 RTS Data2 +// Data3 CTS Data3 +// Data4 DTR Data4 +// Data5 DSR Data5 +// Data6 DCD Data6 +// Data7 RI Data7 +// +extern int ftdibb_setBitMode(usb_dev_handle *dev_handle,unsigned char pin_bitmask, unsigned char onoff); + +// read data via bit bang +extern unsigned char ftdibb_getBitMode(usb_dev_handle *dev_handle); +// write data via bit bang +extern int ftdibb_writeData(usb_dev_handle *dev_handle, unsigned char *buf, int size); +extern int ftdibb_writeDatabyte(usb_dev_handle *dev_handle, unsigned char byte); + +extern void ftdibb_close(usb_dev_handle *dev_handle); + +// just get the status of the one pin (e.g pin=4 for the third pin): +extern int ftdibb_getpin(usb_dev_handle *dev_handle,unsigned char pin); + +extern int ftdibb_setLatencyTimer(usb_dev_handle *dev_handle,unsigned char latency); +#endif /* __ftdibb_h__ */ --- uisp-20050207/src/ftdibb.c 2005-10-02 21:00:18.000000000 +0200 +++ uisp-20050207-usb-bbpg/src/ftdibb.c 2005-10-02 20:25:53.000000000 +0200 @@ -0,0 +1,249 @@ +/* ftdi bit bang lib written by Guido Socher (guido at linuxfocus.org) + * Copyright: GPL + * Requires: libusb , libusb writes to the files in /proc/bus/usb/00X + * root rights or suid root (chmod 4755) is therefore + * needed. + */ +#include +#include + +// open the usb devices identified by vendor and product. +// claim exlclusive access to the interface and enable bit bang mode +// return NULL on failure otherwise a valid usb_dev_handle descriptor +// +// The standard ftdi232bm vendor and product IDs are: 0x0403, 0x6001 +usb_dev_handle *ftdibb_open(int vendor, int product,int silent) +{ + usb_dev_handle *dev_handle; + struct usb_bus *busses; + struct usb_bus *bus; + struct usb_device *dev; + int founddev=0; + + usb_init(); + usb_find_busses(); + usb_find_devices(); + + busses = usb_get_busses(); + for (bus = usb_busses; bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { + if (dev->descriptor.idVendor == vendor + && dev->descriptor.idProduct == product) { + dev_handle = usb_open(dev); + if (dev_handle){ + founddev=1; + break; + }else{ + if (silent==0 || silent==1){ + fprintf(stderr,"ftdibb error: Device found but usb_open failed\n"); + } + return(NULL); // device found but open fail + } + } + } + } + if(founddev==0){ + if (silent==0){ + fprintf(stderr,"ftdibb error: Device not connected\n"); + } + return(NULL); // device not found + } + if (usb_claim_interface(dev_handle, 0) != 0) { + usb_close (dev_handle); + if (silent==0 || silent==1){ + fprintf(stderr,"ftdibb error: unable to claim exclusive access to ftdi chip. Make sure ftdi_sio is not loaded (check with lsmod) and make sure you have write access to /proc/bus/usb (root right or suid executable)\n"); + } + return(NULL); // usb_claim_interface failed + } + // now we are ready to configure the device + // the syntax to send a control urb is this: + // usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout); + + // reset it first + if (usb_control_msg(dev_handle, 0x40, 0, 0, 0, NULL, 0, 4000) != 0){ + usb_close (dev_handle); + if (silent==0 || silent==1){ + fprintf(stderr,"ftdibb error: Device communication failed during reset\n"); + } + return(NULL); // reset fail + } + return(dev_handle); +} + +// sets the baudrate to 9600, the bitbang baudrate is actually 16 times higher +// but you do not need to care about this. +// dev_handle is whatever you get returned when you do a ftdibb_open +int ftdibb_setBaudRate(usb_dev_handle *dev_handle,int baudrate) +{ + unsigned short value, index; + /* I did not quite understand how they calculate the baud rate + * therefore you can not set any baud rate at this time. Some bits + * in the bmRequest value are representing values to be added to the + * base baud rate. + * The basic formula seems to be 3000000/Value=baudrate + * For 9600 this is: 3000000/312=9615 This is approx. 9600 + * 312 is binary 100111000 + * As value we write: 01000001 00111000 = 16696 + * + * Values to use for a 48MHz FPGA (external crystal to the ft232bm is still 6MHz): + * Value Baud Rate speed + * 0x2710 300 + * 0x1388 600 + * 0x09C4 1200 + * 0x04E2 2400 + * 0x0271 4800 + * 0x4138 9600 + * 0x809C 19200 + * 0xC04E 38400 + * 0x0034 57600 + * 0x001A 115200 + * 0x000D 230400 + * 0x4006 460800 + * 0x8003 921600 + */ + int brate[]={300,600,1200,2400,4800,9600,19200,38400,57600,115200,230400,460800,921600,0}; + unsigned short brateval[]={0x2710,0x1388,0x09C4,0x04E2,0x0271,0x4138,0x809C,0xC04E,0x0034,0x001A,0x000D,0x4006,0x8003}; + int i=0; + value=16696; // default is 9600 + // select the best fitting baud rate: + while(brate[i]){ + if (baudrate<=brate[i]){ + value=brateval[i]; + break; + } + i++; + } + index=0; + if (usb_control_msg(dev_handle, 0x40, 3, value, index, NULL, 0, 4000) != 0){ + usb_close (dev_handle); + fprintf(stderr,"ftdibb error: setBaudRate failed\n"); + return(-1); + } + return(0); +} + +// enable or disable bitbang mode. pin_bitmask defines which pins are input and which are +// output (a one is an output, all 8 pins output = 0xff). +// dev_handle is whatever you get returned when you do a ftdibb_open +// +// Pin Definitions +// FT245BM FT232BM Bit-Bang Data bit +// Data0 TXD Data0 +// Data1 RXD Data1 +// Data2 RTS Data2 +// Data3 CTS Data3 +// Data4 DTR Data4 +// Data5 DSR Data5 +// Data6 DCD Data6 +// Data7 RI Data7 +// +int ftdibb_setBitMode(usb_dev_handle *dev_handle,unsigned char pin_bitmask, unsigned char onoff) +{ + unsigned short value; + + // lower 8 byte is bitmask, + //Set Bit Bang Mode + //40 -> bmRequestType + //0B -> bmRequest + //pin_bitmask -> lValue + //Enable -> hValue + // rest is zero + //This configures which pins are input and which are output during bitbang. The + //pin_bitmask byte sets the direction. A 1 means the corresponding pin is + //an output (zero means input). The Enable byte will turn the bit bang + //mode off (0) and on (1). + value=pin_bitmask & 0xff; + if (onoff){ + value|= 0x100; // enable bitbang + } + if (usb_control_msg(dev_handle, 0x40, 0x0B, value, 0, NULL, 0, 4000) != 0){ + usb_close (dev_handle); + fprintf(stderr,"ftdibb error: can not set bitbang mode. Not a ftdi BM chip??\n"); + return(-1); // bitbang init fail + } + return(0); +} + +//This function does an immediate (unbuffered) read of the 8 pins and passes back the value. +//This function will exit (terminate the program if it fails. In other words +//no error checking is neede on the user side) +unsigned char ftdibb_getBitMode(usb_dev_handle *dev_handle) +{ + unsigned short value; + //Read Data pins + //C0 -> bmRequestType + //0C -> bmRequest + // rest is zero + //This function does an immediate read of the 8 pins and passes back the + //value. This is useful to see what the pins are doing now. The normal read + //pipe will contain the same result but it has also been sampling the pins + //continuously (up until its buffers become full). Therefore the data in + //the read pipe will be old. + if (usb_control_msg(dev_handle, 0xC0, 0x0C, 0, 0, (char *)&value, 1, 200) != 1){ + usb_close (dev_handle); + fprintf(stderr,"ftdibb error: can not read data pins\n"); + exit(-1); + } + return((unsigned char)value); +} + + +// just get the status of the one pin (e.g pin=4 is thirs pin, pin=8 is fourth pin): +int ftdibb_getpin(usb_dev_handle *dev_handle,unsigned char pin) +{ + return((ftdibb_getBitMode(dev_handle) & pin)&&1); +} + +// this function will exit if there is an error. No checking on +// user side needed. +int ftdibb_writeData(usb_dev_handle *dev_handle, unsigned char *buf, int size) +{ + int total_written; + int writebuffer_chunksize = 4096; + int in_ep = 0x02; + //int out_ep = 0x81; + if (size>writebuffer_chunksize){ + fprintf(stderr,"ftdibb error: can not write more than %d bytes at a time\n",writebuffer_chunksize); + exit(-1); + } + total_written = usb_bulk_write(dev_handle, in_ep, (char *)buf, size, 200); + if (total_written < 0){ + fprintf(stderr,"ftdibb error: write data\n"); + exit(-1); + } + return(total_written); +} + +// most useful for bit bang +int ftdibb_writeDatabyte(usb_dev_handle *dev_handle, unsigned char byte) +{ + return(ftdibb_writeData(dev_handle,&byte,1)); +} + +void ftdibb_close(usb_dev_handle *dev_handle) +{ + usb_close (dev_handle); +} + +// Set buffer latency for buffers which are not completley full +// The default is 16 after a reset +int ftdibb_setLatencyTimer(usb_dev_handle *dev_handle,unsigned char latency) +{ + //40 -> bmRequestType + //09 -> bmRequest + //latency -> lValue + //0 -> hValue + // rest is zero + if (latency ==0 ){ + // only 1-255 are valid + latency=1; + } + if (usb_control_msg(dev_handle, 0x40, 0x09,(int)latency, 0, NULL, 0, 4000) != 0){ + usb_close (dev_handle); + fprintf(stderr,"ftdibb error: can not set buffer latency\n"); + return(-1); + } + return(0); +} + +// -- end of ftdibb --- uisp-20050207/src/Makefile.am 2002-10-31 00:22:07.000000000 +0100 +++ uisp-20050207-usb-bbpg/src/Makefile.am 2005-10-02 21:33:53.000000000 +0200 @@ -31,7 +31,8 @@ # Turn on all warnings and consider them errors. This kinda forces you to have # to use gcc, but I'd rather have all warnings eliminated. -AM_CXXFLAGS = -Wall -Werror +AM_CXXFLAGS = -Wall -Werror -I/usr/local/libusb/include +AM_LDFLAGS = -L/usr/local/libusb/lib bin_PROGRAMS = uisp uisp_SOURCES = \ @@ -58,4 +59,6 @@ cygwinp.h \ parport.h \ ppdev.h \ + ftdibb.h \ + ftdibb.c \ timeradd.h --- uisp-20050207/src/Main.C 2004-12-28 15:39:38.000000000 +0100 +++ uisp-20050207-usb-bbpg/src/Main.C 2005-10-03 09:31:29.000000000 +0200 @@ -83,8 +83,8 @@ "Programming Methods:\n" " -dprog=avr910 Standard Atmel Serial Programmer/Atmel Low Cost Programmer\n" " pavr http://www.avr1.org/pavr/pavr.html\n" -" stk500 Atmel STK500\n" -" avrisp Atmel AVRISP (uses stk500 protocol, but can only perform\n" +" stk500 Atmel STK500 V1\n" +" avrisp Atmel AVRISP (uses stk500 V1 protocol, but can only perform\n" " serial programming using SPI)\n" #ifndef NO_DAPA " -dprog=dapa|stk200|abb|atdh|avrisp|bsd|fbprg|dt006|maxi|xil|dasa|dasa2|dasa3\n" @@ -104,6 +104,8 @@ " dasa serial (RESET=RTS SCK=DTR MOSI=TXD MISO=CTS)\n" " dasa2 serial (RESET=!TXD SCK=RTS MOSI=DTR MISO=CTS)\n" " dasa3 serial (RESET=!DTR SCK=RTS MOSI=TXD MISO=CTS)\n" +" bbpg FTFI BitBang programmer, http://tuxgraphics.org/electronics\n" +" (used as bootstrap programmer for the avrusb500)\n" "\n" "Target Device Selection:\n" " -dpart Set target abbreviated name or number. For some programmers, if\n" --- uisp-20050207/src/Makefile.in 2005-02-07 22:48:13.000000000 +0100 +++ uisp-20050207-usb-bbpg/src/Makefile.in 2005-10-03 09:43:41.000000000 +0200 @@ -89,7 +89,7 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ +LIBS = -lusb LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ @@ -145,7 +145,8 @@ # Turn on all warnings and consider them errors. This kinda forces you to have # to use gcc, but I'd rather have all warnings eliminated. -AM_CXXFLAGS = -Wall -Werror +AM_CXXFLAGS = -Wall -Werror -I/usr/local/libusb/include +AM_LDFLAGS = -L/usr/local/libusb/lib bin_PROGRAMS = uisp uisp_SOURCES = \ @@ -172,6 +173,8 @@ cygwinp.h \ parport.h \ ppdev.h \ + ftdibb.h \ + ftdibb.c \ timeradd.h subdir = src @@ -185,7 +188,7 @@ am_uisp_OBJECTS = Avr.$(OBJEXT) AvrAtmel.$(OBJEXT) AvrDummy.$(OBJEXT) \ DAPA.$(OBJEXT) Main.$(OBJEXT) MotIntl.$(OBJEXT) \ Serial.$(OBJEXT) Stk500.$(OBJEXT) Terminal.$(OBJEXT) \ - cygwinp.$(OBJEXT) + cygwinp.$(OBJEXT) ftdibb.$(OBJEXT) uisp_OBJECTS = $(am_uisp_OBJECTS) uisp_LDADD = $(LDADD) uisp_DEPENDENCIES = @@ -215,6 +218,9 @@ all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am +ftdibb.o: ftdibb.h ftdibb.c + g++ $(AM_CXXFLAGS) -c ftdibb.c + .SUFFIXES: .SUFFIXES: .C .o .obj $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) --- uisp-20050207/src/DAPA.C 2004-12-28 15:39:38.000000000 +0100 +++ uisp-20050207-with-usb-bbpg-patch/src/DAPA.C 2005-10-10 09:01:50.000000000 +0200 @@ -36,7 +36,6 @@ */ #ifndef NO_DAPA -//#define DEBUG //#define DEBUG1 #include "config.h" @@ -45,6 +44,11 @@ #include #include #include +#include +#include + +#include "ftdibb.h" +#include #ifndef NO_DIRECT_IO @@ -318,6 +322,20 @@ #define DM04_DIN PARPORT_STATUS_PAPEROUT /* Data IN */ #define DM04_DOUT PARPORT_CONTROL_INIT /* Data OUT */ +/* bbpg -- ftdi based usb programmer from http://tuxgraphics.org/ + * It's a usb programmer which requires no other programmer to build + * this programmer. Instructions and circuit diagram are available + * for free. The programmer is very slow but its main purpose is + * to work as a boot strap programmer for the avrusb500 +*/ +#define BBPG_SCK 16 +#define BBPG_MISO 32 +#define BBPG_MOSI 64 +#define BBPG_RESET 128 +#define BBPG_VENDORID 0x0403 +#define BBPG_PRODUCTID 0x6001 +usb_dev_handle *bbpg_dev_handle; + /* Default value for minimum SCK high/low time in microseconds. */ #ifndef SCK_DELAY #define SCK_DELAY 5 @@ -394,6 +412,10 @@ void TDAPA::ParportWriteCtrl() { + if (pa_type == PAT_BBPG) { + printf("ParportWriteCtrl was called\n"); + return; + } Info(5, "Control: %x \n", par_ctrl); if (ppdev_fd != -1) par_write_ctrl(ppdev_fd, &par_ctrl); @@ -405,6 +427,10 @@ TDAPA::ParportWriteData() { Info(5, "Data: %x \n", par_data); + if (pa_type == PAT_BBPG) { + ftdibb_writeDatabyte(bbpg_dev_handle,par_data); + return; + } if (ppdev_fd != -1) par_write_data(ppdev_fd, &par_data); else @@ -414,6 +440,10 @@ void TDAPA::ParportReadStatus() { + if (pa_type == PAT_BBPG) { + par_status = ftdibb_getBitMode(bbpg_dev_handle); + return; + } if (ppdev_fd != -1) par_read_status(ppdev_fd, &par_status); else @@ -527,6 +557,11 @@ break; + case PAT_BBPG: + if (b) par_data |= BBPG_RESET; else par_data &= ~BBPG_RESET; + ParportWriteData(); + break; + } Delay_usec(b ? reset_high_time : RESET_LOW_TIME ); } @@ -615,6 +650,11 @@ SerialWriteCtrl(); #endif /* TIOCMGET */ break; + + case PAT_BBPG: + if (b) par_data &= ~BBPG_SCK; else par_data |= BBPG_SCK; + ParportWriteData(); + break; } } @@ -728,6 +768,7 @@ case PAT_DASA2: case PAT_DASA3: case PAT_DM04: + case PAT_BBPG: break; } } @@ -758,6 +799,7 @@ case PAT_DASA: case PAT_DASA2: case PAT_DASA3: + case PAT_BBPG: /* no separate enable for SCK and MOSI */ break; } @@ -866,7 +908,11 @@ #if defined(TIOCMGET) && defined(TIOCCBRK) ioctl(ppdev_fd, (!b) ? TIOCCBRK : TIOCSBRK, 0); #endif /* TIOCMGET */ + break; + case PAT_BBPG: + if (b) par_data |= BBPG_MOSI; else par_data &= ~BBPG_MOSI; + ParportWriteData(); break; } @@ -917,6 +963,10 @@ b = (ser_ctrl & TIOCM_CTS); #endif /* TIOCMGET */ break; + case PAT_BBPG: + ParportReadStatus(); + b = (par_status & BBPG_MISO); + SckDelay(); } if (miso_invert) b = !b; @@ -997,10 +1047,18 @@ case PAT_DASA2: case PAT_DASA3: break; - } - if (!pa_type_is_serial) { - ParportWriteCtrl(); + case PAT_BBPG: + /* we do not have seperate control or data. We use only data */ + par_ctrl = 0; + par_data = 0; + break; + } + // there is no real init needed for BBPG: + if (!pa_type_is_serial ) { + if (pa_type != PAT_BBPG) { + ParportWriteCtrl(); + } ParportWriteData(); SckDelay(); ParportReadStatus(); @@ -1022,6 +1080,10 @@ Info(4, "Sending: %d \n", b); for (mask = 0x80; mask; mask >>= 1) { + if(pa_type==PAT_BBPG) { + // we need delay before and after every communication via usb: + SckDelay(); + } OutData(b & mask); SckDelay(); /* MM 20020613: we used to read the bit here, but ... */ @@ -1125,6 +1187,8 @@ pa_type = PAT_DASA3; else if (val && strcmp(val, "dm04") == 0) pa_type = PAT_DM04; + else if (val && strcmp(val, "bbpg") == 0) + pa_type = PAT_BBPG; else { throw Error_Device("Direct Parallel Access not defined."); } @@ -1170,8 +1234,10 @@ #endif /* Drop privileges (if installed setuid root - NOT RECOMMENDED). */ - setgid(getgid()); - setuid(getuid()); + if (pa_type != PAT_BBPG){ + setgid(getgid()); + setuid(getuid()); + } #ifdef NO_DIRECT_IO if ((val = GetCmdParam("-dlpt")) != NULL) { @@ -1181,8 +1247,9 @@ ppdev_name = val; } #endif + - if (ppdev_name) { + if (ppdev_name && pa_type != PAT_BBPG) { if (pa_type_is_serial) { ppdev_fd = open(ppdev_name, O_RDWR | O_NOCTTY | O_NONBLOCK); if (ppdev_fd != -1) { @@ -1222,12 +1289,45 @@ throw Error_Device("Failed to claim ppdev."); } } + /* open the usb connection in case of BBPG */ + if (pa_type == PAT_BBPG ){ + if(geteuid()!=0){ + fprintf(stderr,"ERROR: this program must run with effective uid=root.\n"); + exit(1); + } + // set also the real uid to be able to run rmmod + if (setuid(0)==0){ + system("/sbin/rmmod ftdi_sio > /dev/null 2>&1"); + }else{ + fprintf(stderr,"Warning: suid root failed\n"); + } + bbpg_dev_handle = ftdibb_open(BBPG_VENDORID, BBPG_PRODUCTID,0); + if (bbpg_dev_handle==NULL){ + throw Error_Device("Failed to connect to bbpg device."); + } + if (ftdibb_setBaudRate(bbpg_dev_handle,9600)!=0){ + throw Error_Device("bbpg setBaudRate failed."); + } + if (ftdibb_setLatencyTimer(bbpg_dev_handle,8)!=0){ + throw Error_Device("bbpg setLatency failed."); + } + if (ftdibb_setBitMode(bbpg_dev_handle,BBPG_SCK|BBPG_MOSI|BBPG_RESET, 1)==0){ + printf("OK: bitbang mode on\n"); + printf("NOTE: bbpg is a bit slow. Be patient.... \n"); + } + } + t_sck = SCK_DELAY; if (pa_type_is_serial) t_sck *= 3; /* more delay for slow RS232 drivers */ + if (pa_type == PAT_BBPG ){ + t_sck *= 10; /* more delay */ + } val = GetCmdParam("-dt_sck"); if (val) t_sck = strtol(val, NULL, 0); + Info(3,"SCK Delay (t_sck): %ld\n", t_sck); + if ((val=GetCmdParam("-dinvert"))) { @@ -1270,15 +1370,21 @@ OutReset(1); OutEnaReset(0); - if (ppdev_fd != -1) { - if (pa_type_is_serial) - tcsetattr(ppdev_fd, TCSADRAIN, &saved_modes); - else - par_release(ppdev_fd); - close(ppdev_fd); - ppdev_fd = -1; - } else - (void) ioport_disable(IOBASE, IOSIZE); + if (pa_type == PAT_BBPG ){ + printf("disabling bitbang mode...\n"); + ftdibb_setBitMode(bbpg_dev_handle,0xff, 0); + ftdibb_close(bbpg_dev_handle); + }else{ + if (ppdev_fd != -1) { + if (pa_type_is_serial) + tcsetattr(ppdev_fd, TCSADRAIN, &saved_modes); + else + par_release(ppdev_fd); + close(ppdev_fd); + ppdev_fd = -1; + } else + (void) ioport_disable(IOBASE, IOSIZE); + } } #endif