123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- /*
- * Copyright (C) 2008 dhewg, #wiidev efnet
- *
- * this file is part of wiifuse
- * http://wiibrew.org/index.php?title=Wiifuse
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <errno.h>
- #ifndef __WIN32__
- #include <termios.h>
- #else
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #endif
- #include "gecko.h"
- #ifndef O_SYNC
- #define O_SYNC 0
- #endif
- #define FTDI_PACKET_SIZE 3968
- #ifndef __WIN32__
- static int fd_gecko = -1;
- #else
- static HANDLE handle_gecko = NULL;
- #endif
- #ifdef USE_LIBFTDI
- #include "ftdi.h"
- #define DEFAULT_FTDI_VID 0x0403
- #define DEFAULT_FTDI_PID 0x6001
- struct ftdi_context gFTDIContext;
- int gUsingFTDI = 0;
- #endif
- int gecko_open(const char *dev) {
- #ifdef USE_LIBFTDI
- int err;
- ftdi_init(&gFTDIContext);
- if((err = ftdi_usb_open(&gFTDIContext, DEFAULT_FTDI_VID, DEFAULT_FTDI_PID) < 0)) {
- fprintf(stderr, "ftdi_usb_open_desc failed: %d (%s)\n", err, ftdi_get_error_string(&gFTDIContext));
- fprintf(stderr, "Perhaps you need to unload the FTDI kext with e.g.\n");
- fprintf(stderr, "\tsudo kextunload -b com.FTDI.driver.FTDIUSBSerialDriver\n");
- } else {
- gUsingFTDI=1;
- fprintf(stderr, "Found libftdi device\n");
- goto done;
- }
- #endif
- #ifndef __WIN32__
- struct termios newtio;
- fd_gecko = open(dev, O_RDWR | O_NOCTTY | O_SYNC | O_NONBLOCK);
- if (fd_gecko == -1) {
- perror("gecko_open");
- return 1;
- }
- if (fcntl(fd_gecko, F_SETFL, 0)) {
- perror("F_SETFL on serial port");
- return 1;
- }
- if (tcgetattr(fd_gecko, &newtio)) {
- perror("tcgetattr");
- return 1;
- }
- cfmakeraw(&newtio);
- newtio.c_cflag |= CRTSCTS | CS8 | CLOCAL | CREAD;
- if (tcsetattr(fd_gecko, TCSANOW, &newtio)) {
- perror("tcsetattr");
- return 1;
- }
- #else
- COMMTIMEOUTS timeouts;
- handle_gecko = CreateFile(dev, GENERIC_READ | GENERIC_WRITE, 0, 0,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
- GetCommTimeouts(handle_gecko, &timeouts);
- timeouts.ReadIntervalTimeout = MAXDWORD;
- timeouts.ReadTotalTimeoutMultiplier = 0;
- timeouts.ReadTotalTimeoutConstant = 0;
- timeouts.WriteTotalTimeoutMultiplier = 0;
- timeouts.WriteTotalTimeoutConstant = 0;
- if (!SetCommTimeouts(handle_gecko, &timeouts)) {
- fprintf(stderr, "error setting timeouts on port\n");
- return 1;
- }
- if (!SetCommMask(handle_gecko, 0)) {
- fprintf(stderr, "error setting communications event mask\n");
- return 1;
- }
- #endif
- done:
- gecko_flush();
- return 0;
- }
- void gecko_close() {
- #ifdef USE_LIBFTDI
- if (gUsingFTDI) {
- ftdi_usb_close(&gFTDIContext);
- return;
- }
- #endif
- #ifndef __WIN32__
- if (fd_gecko > 0)
- close(fd_gecko);
- #else
- CloseHandle(handle_gecko);
- #endif
- }
- void gecko_flush() {
- #ifdef USE_LIBFTDI
- if (gUsingFTDI) {
- ftdi_usb_purge_buffers(&gFTDIContext);
- return;
- }
- #endif
- #ifndef __WIN32__
- tcflush(fd_gecko, TCIOFLUSH);
- #else
- PurgeComm(handle_gecko, PURGE_RXCLEAR | PURGE_TXCLEAR |
- PURGE_TXABORT | PURGE_RXABORT);
- #endif
- }
- int gecko_read(void *buf, size_t count) {
- size_t left, chunk;
- #ifndef __WIN32__
- size_t res;
- #else
- DWORD res;
- #endif
- left = count;
- while (left) {
- chunk = left;
- if (chunk > FTDI_PACKET_SIZE)
- chunk = FTDI_PACKET_SIZE;
- #ifdef USE_LIBFTDI
- if (gUsingFTDI)
- res = ftdi_read_data(&gFTDIContext, buf, chunk);
- else
- #endif
- #ifndef __WIN32__
- res = read(fd_gecko, buf, chunk);
- if (res < 1) {
- perror("gecko_read");
- return 1;
- }
- #else
- if (!ReadFile(handle_gecko, buf, chunk, &res, NULL)) {
- fprintf(stderr, "gecko_read\n");
- return 1;
- }
- #endif
- left -= res;
- buf += res;
- }
- return 0;
- }
- int gecko_write(const void *buf, size_t count) {
- size_t left, chunk;
- #ifndef __WIN32__
- size_t res;
- #else
- DWORD res;
- #endif
- left = count;
- while (left) {
- chunk = left;
- if (chunk > FTDI_PACKET_SIZE)
- chunk = FTDI_PACKET_SIZE;
- #ifdef USE_LIBFTDI
- if (gUsingFTDI)
- res = ftdi_write_data(&gFTDIContext, (unsigned char *)buf, chunk);
- else
- #endif
- #ifndef __WIN32__
- res = write(fd_gecko, buf, count);
- if (res < 1) {
- perror("gecko_write");
- return 1;
- }
- #else
- if (!WriteFile(handle_gecko, buf, chunk, &res, NULL)) {
- fprintf (stderr, "gecko_write\n");
- return 1;
- }
- #endif
- left -= res;
- buf += res;
- #if !defined(__WIN32__) && !defined(USE_LIBFTDI)
- // does this work with ftdi-sio?
- if (tcdrain(fd_gecko)) {
- perror ("gecko_drain");
- return 1;
- }
- #endif
- }
- return 0;
- }
|