port upload code
This commit is contained in:
parent
e67e726743
commit
a518ff1e1e
@ -96,6 +96,7 @@ endif
|
|||||||
OBJECTS=ucon64.o ucon64_dat.o ucon64_misc.o ucon64_opts.o \
|
OBJECTS=ucon64.o ucon64_dat.o ucon64_misc.o ucon64_opts.o \
|
||||||
misc/chksum.o misc/file.o misc/getopt.o misc/getopt2.o \
|
misc/chksum.o misc/file.o misc/getopt.o misc/getopt2.o \
|
||||||
misc/misc.o misc/parallel.o misc/property.o misc/string.o \
|
misc/misc.o misc/parallel.o misc/property.o misc/string.o \
|
||||||
|
misc/opendevice.o \
|
||||||
patch/aps.o patch/bsl.o patch/gg.o patch/ips.o patch/pal4u.o \
|
patch/aps.o patch/bsl.o patch/gg.o patch/ips.o patch/pal4u.o \
|
||||||
patch/ppf.o patch/xps.o \
|
patch/ppf.o patch/xps.o \
|
||||||
console/dc.o console/gb.o console/gba.o console/genesis.o \
|
console/dc.o console/gb.o console/gba.o console/genesis.o \
|
||||||
|
|||||||
@ -25,6 +25,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <usb.h>
|
||||||
#include "misc/misc.h"
|
#include "misc/misc.h"
|
||||||
#include "misc/itypes.h"
|
#include "misc/itypes.h"
|
||||||
#ifdef USE_ZLIB
|
#ifdef USE_ZLIB
|
||||||
@ -38,6 +39,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|||||||
#include "smc.h"
|
#include "smc.h"
|
||||||
#include "snesram.h"
|
#include "snesram.h"
|
||||||
|
|
||||||
|
#include "../misc/opendevice.h"
|
||||||
|
|
||||||
const st_getopt2_t snesram_usage[] =
|
const st_getopt2_t snesram_usage[] =
|
||||||
{
|
{
|
||||||
@ -59,120 +61,127 @@ const st_getopt2_t snesram_usage[] =
|
|||||||
|
|
||||||
#ifdef USE_USB
|
#ifdef USE_USB
|
||||||
|
|
||||||
#define BUFFERSIZE 8192
|
#define READ_BUFFER_SIZE (1024 * 32)
|
||||||
|
#define SEND_BUFFER_SIZE 128
|
||||||
|
#define BANK_SIZE (1<<15)
|
||||||
|
#define BANK_SIZE_SHIFT 15
|
||||||
|
|
||||||
int
|
int
|
||||||
snesram_write_rom (const char *filename)
|
snesram_write_rom (const char *filename)
|
||||||
{
|
{
|
||||||
FILE *file;
|
FILE *file;
|
||||||
unsigned char *buffer;
|
int bytesread, bytessend, size;
|
||||||
int bytesread, bytessend, size, offset, n_blocks1, n_blocks2, n_blocks3, n;
|
|
||||||
time_t starttime;
|
time_t starttime;
|
||||||
|
usb_dev_handle *handle = NULL;
|
||||||
|
const unsigned char rawVid[2] = { USB_CFG_VENDOR_ID }, rawPid[2] = { USB_CFG_DEVICE_ID};
|
||||||
|
char vendor[] = { USB_CFG_VENDOR_NAME, 0 }, product[] = { USB_CFG_DEVICE_NAME, 0};
|
||||||
|
int cnt, vid, pid;
|
||||||
|
uint8_t *read_buffer;
|
||||||
|
uint32_t addr = 0;
|
||||||
|
uint16_t addr_lo = 0;
|
||||||
|
uint16_t addr_hi = 0;
|
||||||
|
uint16_t step = 0;
|
||||||
|
uint8_t bank = 0;
|
||||||
|
uint8_t bank_cnt = 0;
|
||||||
|
|
||||||
|
usb_init();
|
||||||
|
vid = rawVid[1] * 256 + rawVid[0];
|
||||||
|
pid = rawPid[1] * 256 + rawPid[0];
|
||||||
|
if (usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) != 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n",
|
||||||
|
product, vid, pid);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("Open USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid,pid);
|
||||||
|
|
||||||
if ((file = fopen (filename, "rb")) == NULL)
|
if ((file = fopen (filename, "rb")) == NULL)
|
||||||
{
|
{
|
||||||
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
|
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
|
|
||||||
|
if ((read_buffer = (unsigned char *) malloc (READ_BUFFER_SIZE)) == NULL)
|
||||||
{
|
{
|
||||||
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
|
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], READ_BUFFER_SIZE);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fread (buffer, 1, SMC_HEADER_LEN, file);
|
fseek (file, 0, SEEK_END);
|
||||||
|
size = ftell (file);
|
||||||
|
fseek (file, SMC_HEADER_LEN, SEEK_SET);
|
||||||
|
size -= SMC_HEADER_LEN;
|
||||||
|
bank_cnt = size / BANK_SIZE;
|
||||||
|
|
||||||
|
|
||||||
size = (n_blocks1 + n_blocks2 + n_blocks3) * 8 * 1024 + 8 +
|
|
||||||
(buffer[0] & SMC_TRAINER ? 512 : 0);
|
|
||||||
printf ("Send: %d Bytes (%.4f Mb)\n", size, (float) size / MBIT);
|
printf ("Send: %d Bytes (%.4f Mb)\n", size, (float) size / MBIT);
|
||||||
|
bytessend = 0;
|
||||||
ffe_send_block (0x5020, buffer, 8); // send "file control block"
|
|
||||||
bytessend = 8;
|
|
||||||
|
|
||||||
if (buffer[1] >> 5 > 4)
|
|
||||||
offset = 12;
|
|
||||||
else
|
|
||||||
offset = 0;
|
|
||||||
|
|
||||||
if (buffer[0] & SMC_TRAINER) // send trainer if present
|
|
||||||
{
|
|
||||||
fread (buffer, 1, 512, file);
|
|
||||||
ffe_send_block (0x600, buffer, 512);
|
|
||||||
bytessend += 512;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf ("Press q to abort\n\n");
|
printf ("Press q to abort\n\n");
|
||||||
starttime = time (NULL);
|
starttime = time (NULL);
|
||||||
|
|
||||||
for (n = 0; n < n_blocks1; n++)
|
|
||||||
{
|
|
||||||
ffe_send_command0 (0x4507, (unsigned char) (n + offset));
|
|
||||||
if ((bytesread = fread (buffer, 1, BUFFERSIZE, file)) == 0)
|
|
||||||
break;
|
|
||||||
ffe_send_block (0x6000, buffer, bytesread);
|
|
||||||
|
|
||||||
bytessend += bytesread;
|
cnt = usb_control_msg(handle,
|
||||||
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
|
||||||
|
USB_BULK_UPLOAD_INIT, BANK_SIZE_SHIFT , bank_cnt, NULL, 0, 5000);
|
||||||
|
|
||||||
|
|
||||||
|
while ((bytesread = fread(read_buffer, READ_BUFFER_SIZE, 1, file)) > 0) {
|
||||||
|
for (step = 0; step < READ_BUFFER_SIZE; step += SEND_BUFFER_SIZE) {
|
||||||
|
|
||||||
|
addr_lo = addr & 0xffff;
|
||||||
|
addr_hi = (addr >> 16) & 0x00ff;
|
||||||
|
|
||||||
|
if (addr == 0){
|
||||||
|
cnt = usb_control_msg(handle,
|
||||||
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
|
||||||
|
USB_ENDPOINT_OUT, USB_BULK_UPLOAD_ADDR, addr_hi,
|
||||||
|
addr_lo, (char *) read_buffer + step,
|
||||||
|
SEND_BUFFER_SIZE, 5000);
|
||||||
|
} else {
|
||||||
|
cnt = usb_control_msg(handle,
|
||||||
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
|
||||||
|
USB_ENDPOINT_OUT, USB_BULK_UPLOAD_NEXT, addr_hi,
|
||||||
|
addr_lo, (char *) read_buffer + step,
|
||||||
|
SEND_BUFFER_SIZE, 5000);
|
||||||
|
}
|
||||||
|
if (cnt < 0) {
|
||||||
|
fprintf(stderr, "USB error: %s\n", usb_strerror());
|
||||||
|
usb_close(handle);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bytessend += SEND_BUFFER_SIZE;
|
||||||
ucon64_gauge (starttime, bytessend, size);
|
ucon64_gauge (starttime, bytessend, size);
|
||||||
ffe_checkabort (2);
|
|
||||||
|
addr += SEND_BUFFER_SIZE;
|
||||||
|
if ( addr % 0x8000 == 0) {
|
||||||
|
bank++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (n = 0; n < n_blocks2; n++)
|
|
||||||
{
|
|
||||||
ffe_send_command0 (0x4507, (unsigned char) (n + 32));
|
|
||||||
if ((bytesread = fread (buffer, 1, BUFFERSIZE, file)) == 0)
|
|
||||||
break;
|
|
||||||
ffe_send_block (0x6000, buffer, bytesread);
|
|
||||||
|
|
||||||
bytessend += bytesread;
|
|
||||||
ucon64_gauge (starttime, bytessend, size);
|
|
||||||
ffe_checkabort (2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ffe_send_command0 (0x2001, 0);
|
|
||||||
|
|
||||||
for (n = 0; n < n_blocks3; n++)
|
|
||||||
{
|
|
||||||
if (n == 0)
|
|
||||||
{
|
|
||||||
ffe_send_command0 (0x4500, 0x22);
|
|
||||||
ffe_send_command0 (0x42ff, 0x30);
|
|
||||||
if ((bytesread = fread (buffer, 1, BUFFERSIZE, file)) == 0)
|
|
||||||
break;
|
|
||||||
ffe_send_block (0x6000, buffer, bytesread);
|
|
||||||
}
|
}
|
||||||
else
|
cnt = usb_control_msg(handle,
|
||||||
{
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
|
||||||
int m;
|
USB_ENDPOINT_OUT, USB_BULK_UPLOAD_END, 0, 0, NULL,
|
||||||
|
0, 5000);
|
||||||
|
|
||||||
ffe_send_command0 (0x4500, 7);
|
#if 0
|
||||||
for (m = 0; m < 8; m++)
|
bank = 0;
|
||||||
ffe_send_command0 ((unsigned short) (0x4510 + m), (unsigned char) (n * 8 + m));
|
fseek(fp, 0, SEEK_SET);
|
||||||
if ((bytesread = fread (buffer, 1, BUFFERSIZE, file)) == 0)
|
while ((cnt = fread(read_buffer, READ_BUFFER_SIZE, 1, fp)) > 0) {
|
||||||
break;
|
printf ("bank=0x%02x crc=0x%04x\n", bank++,
|
||||||
ffe_send_block2 (0, buffer, bytesread);
|
do_crc(read_buffer, READ_BUFFER_SIZE));
|
||||||
}
|
}
|
||||||
|
fclose(fp);
|
||||||
|
#endif
|
||||||
|
cnt = usb_control_msg(handle,
|
||||||
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
|
||||||
|
USB_ENDPOINT_OUT, USB_SNES_BOOT, 0, 0, NULL,
|
||||||
|
0, 5000);
|
||||||
|
|
||||||
bytessend += bytesread;
|
|
||||||
ucon64_gauge (starttime, bytessend, size);
|
|
||||||
ffe_checkabort (2);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (n = 0x4504; n < 0x4508; n++)
|
free (read_buffer);
|
||||||
ffe_send_command0 ((unsigned short) n, 0);
|
|
||||||
for (n = 0x4510; n < 0x451c; n++)
|
|
||||||
ffe_send_command0 ((unsigned short) n, 0);
|
|
||||||
|
|
||||||
ffe_send_command (5, 1, 0);
|
|
||||||
|
|
||||||
free (buffer);
|
|
||||||
fclose (file);
|
fclose (file);
|
||||||
ffe_deinit_io ();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // USE_USB
|
#endif // USE_USB
|
||||||
|
|||||||
@ -21,6 +21,55 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|||||||
#ifndef SNESRAM_H
|
#ifndef SNESRAM_H
|
||||||
#define SNESRAM_H
|
#define SNESRAM_H
|
||||||
|
|
||||||
|
#define USB_UPLOAD_INIT 0
|
||||||
|
#define USB_UPLOAD_ADDR 1
|
||||||
|
|
||||||
|
#define USB_DOWNLOAD_INIT 2
|
||||||
|
#define USB_DOWNLOAD_ADDR 3
|
||||||
|
|
||||||
|
#define USB_CRC 4
|
||||||
|
#define USB_CRC_ADDR 5
|
||||||
|
|
||||||
|
#define USB_BULK_UPLOAD_INIT 6
|
||||||
|
#define USB_BULK_UPLOAD_ADDR 7
|
||||||
|
#define USB_BULK_UPLOAD_NEXT 8
|
||||||
|
#define USB_BULK_UPLOAD_END 9
|
||||||
|
#define USB_SNES_BOOT 10
|
||||||
|
|
||||||
|
/* -------------------------- Device Description --------------------------- */
|
||||||
|
|
||||||
|
#define USB_CFG_VENDOR_ID 0xc0, 0x16
|
||||||
|
/* USB vendor ID for the device, low byte first. If you have registered your
|
||||||
|
* own Vendor ID, define it here. Otherwise you use one of obdev's free shared
|
||||||
|
* VID/PID pairs. Be sure to read USBID-License.txt for rules!
|
||||||
|
*/
|
||||||
|
#define USB_CFG_DEVICE_ID 0xdd, 0x05
|
||||||
|
/* This is the ID of the product, low byte first. It is interpreted in the
|
||||||
|
* scope of the vendor ID. If you have registered your own VID with usb.org
|
||||||
|
* or if you have licensed a PID from somebody else, define it here. Otherwise
|
||||||
|
* you use obdev's free shared VID/PID pair. Be sure to read the rules in
|
||||||
|
* USBID-License.txt!
|
||||||
|
*/
|
||||||
|
#define USB_CFG_DEVICE_VERSION 0x00, 0x01
|
||||||
|
/* Version number of the device: Minor number first, then major number.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_VENDOR_NAME 'o', 'p', 't', 'i', 'x', 'x', '.', 'o', 'r', 'g'
|
||||||
|
#define USB_CFG_VENDOR_NAME_LEN 10
|
||||||
|
/* These two values define the vendor name returned by the USB device. The name
|
||||||
|
* must be given as a list of characters under single quotes. The characters
|
||||||
|
* are interpreted as Unicode (UTF-16) entities.
|
||||||
|
* If you don't want a vendor name string, undefine these macros.
|
||||||
|
* ALWAYS define a vendor name containing your Internet domain name if you use
|
||||||
|
* obdev's free shared VID/PID pair. See the file USBID-License.txt for
|
||||||
|
* details.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_DEVICE_NAME 'S', 'N', 'E', 'S', 'R', 'A', 'M'
|
||||||
|
#define USB_CFG_DEVICE_NAME_LEN 7
|
||||||
|
/* Same as above for the device name. If you don't want a device name, undefine
|
||||||
|
* the macros. See the file USBID-License.txt before you assign a name if you
|
||||||
|
* use a shared VID/PID.
|
||||||
|
*/
|
||||||
|
|
||||||
extern const st_getopt2_t snesram_usage[];
|
extern const st_getopt2_t snesram_usage[];
|
||||||
|
|
||||||
#ifdef USE_USB
|
#ifdef USE_USB
|
||||||
|
|||||||
286
tools/ucon64/2.0/src/misc/opendevice.c
Normal file
286
tools/ucon64/2.0/src/misc/opendevice.c
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
/*
|
||||||
|
* Name: opendevice.c Project: V-USB host-side library Author: Christian
|
||||||
|
* Starkjohann Creation Date: 2008-04-10 Tabsize: 4 Copyright: (c) 2008 by
|
||||||
|
* OBJECTIVE DEVELOPMENT Software GmbH License: GNU GPL v2 (see License.txt),
|
||||||
|
* GNU GPL v3 or proprietary (CommercialLicense.txt) This Revision: $Id:
|
||||||
|
* opendevice.c 740 2009-04-13 18:23:31Z cs $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* General Description: The functions in this module can be used to find and
|
||||||
|
* open a device based on libusb or libusb-win32.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "opendevice.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MATCH_SUCCESS 1
|
||||||
|
#define MATCH_FAILED 0
|
||||||
|
#define MATCH_ABORT -1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* private interface: match text and p, return MATCH_SUCCESS, MATCH_FAILED, or
|
||||||
|
* MATCH_ABORT.
|
||||||
|
*/
|
||||||
|
static int _shellStyleMatch(char *text, char *p)
|
||||||
|
{
|
||||||
|
int last,
|
||||||
|
matched,
|
||||||
|
reverse;
|
||||||
|
|
||||||
|
for (; *p; text++, p++) {
|
||||||
|
if (*text == 0 && *p != '*')
|
||||||
|
return MATCH_ABORT;
|
||||||
|
switch (*p) {
|
||||||
|
case '\\':
|
||||||
|
/*
|
||||||
|
* Literal match with following character.
|
||||||
|
*/
|
||||||
|
p++;
|
||||||
|
/*
|
||||||
|
* FALLTHROUGH
|
||||||
|
*/
|
||||||
|
default:
|
||||||
|
if (*text != *p)
|
||||||
|
return MATCH_FAILED;
|
||||||
|
continue;
|
||||||
|
case '?':
|
||||||
|
/*
|
||||||
|
* Match anything.
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
|
case '*':
|
||||||
|
while (*++p == '*')
|
||||||
|
/*
|
||||||
|
* Consecutive stars act just like one.
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
|
if (*p == 0)
|
||||||
|
/*
|
||||||
|
* Trailing star matches everything.
|
||||||
|
*/
|
||||||
|
return MATCH_SUCCESS;
|
||||||
|
while (*text)
|
||||||
|
if ((matched = _shellStyleMatch(text++, p)) != MATCH_FAILED)
|
||||||
|
return matched;
|
||||||
|
return MATCH_ABORT;
|
||||||
|
case '[':
|
||||||
|
reverse = p[1] == '^';
|
||||||
|
if (reverse) /* Inverted character class. */
|
||||||
|
p++;
|
||||||
|
matched = MATCH_FAILED;
|
||||||
|
if (p[1] == ']' || p[1] == '-')
|
||||||
|
if (*++p == *text)
|
||||||
|
matched = MATCH_SUCCESS;
|
||||||
|
for (last = *p; *++p && *p != ']'; last = *p)
|
||||||
|
if (*p == '-' && p[1] != ']' ? *text <= *++p
|
||||||
|
&& *text >= last : *text == *p)
|
||||||
|
matched = MATCH_SUCCESS;
|
||||||
|
if (matched == reverse)
|
||||||
|
return MATCH_FAILED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *text == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* public interface for shell style matching: returns 0 if fails, 1 if matches
|
||||||
|
*/
|
||||||
|
static int shellStyleMatch(char *text, char *pattern)
|
||||||
|
{
|
||||||
|
if (pattern == NULL) /* NULL pattern is synonymous to "*" */
|
||||||
|
return 1;
|
||||||
|
return _shellStyleMatch(text, pattern) == MATCH_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
int usbGetStringAscii(usb_dev_handle * dev, int index, char *buf, int buflen)
|
||||||
|
{
|
||||||
|
char buffer[256];
|
||||||
|
int rval,
|
||||||
|
i;
|
||||||
|
|
||||||
|
if ((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use
|
||||||
|
* libusb
|
||||||
|
* version
|
||||||
|
* if
|
||||||
|
* it
|
||||||
|
* works
|
||||||
|
*/
|
||||||
|
return rval;
|
||||||
|
if ((rval =
|
||||||
|
usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR,
|
||||||
|
(USB_DT_STRING << 8) + index, 0x0409, buffer,
|
||||||
|
sizeof(buffer), 5000)) < 0)
|
||||||
|
return rval;
|
||||||
|
if (buffer[1] != USB_DT_STRING) {
|
||||||
|
*buf = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((unsigned char) buffer[0] < rval)
|
||||||
|
rval = (unsigned char) buffer[0];
|
||||||
|
rval /= 2;
|
||||||
|
/*
|
||||||
|
* lossy conversion to ISO Latin1:
|
||||||
|
*/
|
||||||
|
for (i = 1; i < rval; i++) {
|
||||||
|
if (i > buflen) /* destination buffer overflow */
|
||||||
|
break;
|
||||||
|
buf[i - 1] = buffer[2 * i];
|
||||||
|
if (buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */
|
||||||
|
buf[i - 1] = '?';
|
||||||
|
}
|
||||||
|
buf[i - 1] = 0;
|
||||||
|
return i - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
int usbOpenDevice(usb_dev_handle ** device, int vendorID,
|
||||||
|
char *vendorNamePattern, int productID,
|
||||||
|
char *productNamePattern, char *serialNamePattern,
|
||||||
|
FILE * printMatchingDevicesFp, FILE * warningsFp)
|
||||||
|
{
|
||||||
|
struct usb_bus *bus;
|
||||||
|
struct usb_device *dev;
|
||||||
|
usb_dev_handle *handle = NULL;
|
||||||
|
int errorCode = USBOPEN_ERR_NOTFOUND;
|
||||||
|
|
||||||
|
usb_find_busses();
|
||||||
|
usb_find_devices();
|
||||||
|
for (bus = usb_get_busses(); bus; bus = bus->next) {
|
||||||
|
for (dev = bus->devices; dev; dev = dev->next) { /* iterate over
|
||||||
|
* all devices
|
||||||
|
* on all
|
||||||
|
* busses */
|
||||||
|
if ((vendorID == 0 || dev->descriptor.idVendor == vendorID)
|
||||||
|
&& (productID == 0 || dev->descriptor.idProduct == productID)) {
|
||||||
|
char vendor[256],
|
||||||
|
product[256],
|
||||||
|
serial[256];
|
||||||
|
int len;
|
||||||
|
handle = usb_open(dev); /* we need to open the device in order
|
||||||
|
* to query strings */
|
||||||
|
if (!handle) {
|
||||||
|
errorCode = USBOPEN_ERR_ACCESS;
|
||||||
|
if (warningsFp != NULL)
|
||||||
|
fprintf(warningsFp,
|
||||||
|
"Warning: cannot open VID=0x%04x PID=0x%04x: %s\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct, usb_strerror());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* now check whether the names match:
|
||||||
|
*/
|
||||||
|
len = vendor[0] = 0;
|
||||||
|
if (dev->descriptor.iManufacturer > 0) {
|
||||||
|
len =
|
||||||
|
usbGetStringAscii(handle, dev->descriptor.iManufacturer,
|
||||||
|
vendor, sizeof(vendor));
|
||||||
|
}
|
||||||
|
if (len < 0) {
|
||||||
|
errorCode = USBOPEN_ERR_ACCESS;
|
||||||
|
if (warningsFp != NULL)
|
||||||
|
fprintf(warningsFp,
|
||||||
|
"Warning: cannot query manufacturer for VID=0x%04x PID=0x%04x: %s\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct, usb_strerror());
|
||||||
|
} else {
|
||||||
|
errorCode = USBOPEN_ERR_NOTFOUND;
|
||||||
|
/*
|
||||||
|
* printf("seen device from vendor ->%s<-\n", vendor);
|
||||||
|
*/
|
||||||
|
if (shellStyleMatch(vendor, vendorNamePattern)) {
|
||||||
|
len = product[0] = 0;
|
||||||
|
if (dev->descriptor.iProduct > 0) {
|
||||||
|
len =
|
||||||
|
usbGetStringAscii(handle,
|
||||||
|
dev->descriptor.iProduct,
|
||||||
|
product, sizeof(product));
|
||||||
|
}
|
||||||
|
if (len < 0) {
|
||||||
|
errorCode = USBOPEN_ERR_ACCESS;
|
||||||
|
if (warningsFp != NULL)
|
||||||
|
fprintf(warningsFp,
|
||||||
|
"Warning: cannot query product for VID=0x%04x PID=0x%04x: %s\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct,
|
||||||
|
usb_strerror());
|
||||||
|
} else {
|
||||||
|
errorCode = USBOPEN_ERR_NOTFOUND;
|
||||||
|
/*
|
||||||
|
* printf("seen product ->%s<-\n", product);
|
||||||
|
*/
|
||||||
|
if (shellStyleMatch(product, productNamePattern)) {
|
||||||
|
len = serial[0] = 0;
|
||||||
|
if (dev->descriptor.iSerialNumber > 0) {
|
||||||
|
len =
|
||||||
|
usbGetStringAscii(handle,
|
||||||
|
dev->descriptor.
|
||||||
|
iSerialNumber, serial,
|
||||||
|
sizeof(serial));
|
||||||
|
}
|
||||||
|
if (len < 0) {
|
||||||
|
errorCode = USBOPEN_ERR_ACCESS;
|
||||||
|
if (warningsFp != NULL)
|
||||||
|
fprintf(warningsFp,
|
||||||
|
"Warning: cannot query serial for VID=0x%04x PID=0x%04x: %s\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct,
|
||||||
|
usb_strerror());
|
||||||
|
}
|
||||||
|
if (shellStyleMatch(serial, serialNamePattern)) {
|
||||||
|
if (printMatchingDevicesFp != NULL) {
|
||||||
|
if (serial[0] == 0) {
|
||||||
|
fprintf(printMatchingDevicesFp,
|
||||||
|
"VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\"\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct,
|
||||||
|
vendor, product);
|
||||||
|
} else {
|
||||||
|
fprintf(printMatchingDevicesFp,
|
||||||
|
"VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\" serial=\"%s\"\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct,
|
||||||
|
vendor, product, serial);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usb_close(handle);
|
||||||
|
handle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (handle) /* we have found a deice */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (handle != NULL) {
|
||||||
|
errorCode = 0;
|
||||||
|
*device = handle;
|
||||||
|
}
|
||||||
|
if (printMatchingDevicesFp != NULL) /* never return an error for listing
|
||||||
|
* only */
|
||||||
|
errorCode = 0;
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
77
tools/ucon64/2.0/src/misc/opendevice.h
Normal file
77
tools/ucon64/2.0/src/misc/opendevice.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/* Name: opendevice.h
|
||||||
|
* Project: V-USB host-side library
|
||||||
|
* Author: Christian Starkjohann
|
||||||
|
* Creation Date: 2008-04-10
|
||||||
|
* Tabsize: 4
|
||||||
|
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: opendevice.h 740 2009-04-13 18:23:31Z cs $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
General Description:
|
||||||
|
This module offers additional functionality for host side drivers based on
|
||||||
|
libusb or libusb-win32. It includes a function to find and open a device
|
||||||
|
based on numeric IDs and textual description. It also includes a function to
|
||||||
|
obtain textual descriptions from a device.
|
||||||
|
|
||||||
|
To use this functionality, simply copy opendevice.c and opendevice.h into your
|
||||||
|
project and add them to your Makefile. You may modify and redistribute these
|
||||||
|
files according to the GNU General Public License (GPL) version 2 or 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __OPENDEVICE_H_INCLUDED__
|
||||||
|
#define __OPENDEVICE_H_INCLUDED__
|
||||||
|
|
||||||
|
#include <usb.h> /* this is libusb, see http://libusb.sourceforge.net/ */
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen);
|
||||||
|
/* This function gets a string descriptor from the device. 'index' is the
|
||||||
|
* string descriptor index. The string is returned in ISO Latin 1 encoding in
|
||||||
|
* 'buf' and it is terminated with a 0-character. The buffer size must be
|
||||||
|
* passed in 'buflen' to prevent buffer overflows. A libusb device handle
|
||||||
|
* must be given in 'dev'.
|
||||||
|
* Returns: The length of the string (excluding the terminating 0) or
|
||||||
|
* a negative number in case of an error. If there was an error, use
|
||||||
|
* usb_strerror() to obtain the error message.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int usbOpenDevice(usb_dev_handle **device, int vendorID, char *vendorNamePattern, int productID, char *productNamePattern, char *serialNamePattern, FILE *printMatchingDevicesFp, FILE *warningsFp);
|
||||||
|
/* This function iterates over all devices on all USB busses and searches for
|
||||||
|
* a device. Matching is done first by means of Vendor- and Product-ID (passed
|
||||||
|
* in 'vendorID' and 'productID'. An ID of 0 matches any numeric ID (wildcard).
|
||||||
|
* When a device matches by its IDs, matching by names is performed. Name
|
||||||
|
* matching can be done on textual vendor name ('vendorNamePattern'), product
|
||||||
|
* name ('productNamePattern') and serial number ('serialNamePattern'). A
|
||||||
|
* device matches only if all non-null pattern match. If you don't care about
|
||||||
|
* a string, pass NULL for the pattern. Patterns are Unix shell style pattern:
|
||||||
|
* '*' stands for 0 or more characters, '?' for one single character, a list
|
||||||
|
* of characters in square brackets for a single character from the list
|
||||||
|
* (dashes are allowed to specify a range) and if the lis of characters begins
|
||||||
|
* with a caret ('^'), it matches one character which is NOT in the list.
|
||||||
|
* Other parameters to the function: If 'warningsFp' is not NULL, warning
|
||||||
|
* messages are printed to this file descriptor with fprintf(). If
|
||||||
|
* 'printMatchingDevicesFp' is not NULL, no device is opened but matching
|
||||||
|
* devices are printed to the given file descriptor with fprintf().
|
||||||
|
* If a device is opened, the resulting USB handle is stored in '*device'. A
|
||||||
|
* pointer to a "usb_dev_handle *" type variable must be passed here.
|
||||||
|
* Returns: 0 on success, an error code (see defines below) on failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* usbOpenDevice() error codes: */
|
||||||
|
#define USBOPEN_SUCCESS 0 /* no error */
|
||||||
|
#define USBOPEN_ERR_ACCESS 1 /* not enough permissions to open device */
|
||||||
|
#define USBOPEN_ERR_IO 2 /* I/O error */
|
||||||
|
#define USBOPEN_ERR_NOTFOUND 3 /* device not found */
|
||||||
|
|
||||||
|
|
||||||
|
/* Obdev's free USB IDs, see USBID-License.txt for details */
|
||||||
|
|
||||||
|
#define USB_VID_OBDEV_SHARED 5824 /* obdev's shared vendor ID */
|
||||||
|
#define USB_PID_OBDEV_SHARED_CUSTOM 1500 /* shared PID for custom class devices */
|
||||||
|
#define USB_PID_OBDEV_SHARED_HID 1503 /* shared PID for HIDs except mice & keyboards */
|
||||||
|
#define USB_PID_OBDEV_SHARED_CDCACM 1505 /* shared PID for CDC Modem devices */
|
||||||
|
#define USB_PID_OBDEV_SHARED_MIDI 1508 /* shared PID for MIDI class devices */
|
||||||
|
|
||||||
|
#endif /* __OPENDEVICE_H_INCLUDED__ */
|
||||||
Loading…
x
Reference in New Issue
Block a user