diff -urN puppy_1.14/Changelog puppy_1.14p/Changelog --- puppy_1.14/Changelog 1970-01-01 01:00:00.000000000 +0100 +++ puppy_1.14p/Changelog 2011-03-19 01:51:10.000000000 +0000 @@ -0,0 +1,50 @@ +2011-03-19 Gordon Lack + * Version 1.14p + * puppy.c: + Set PUPPY_RELEASE to "1.14p" + Set -d description based on NEW_DEV_SCAN setting + * Makefile: + Changed to allow specification of where libusb is, to + force its location into the RPATH (for dynamic loading) + and to allow static linking of it. + [STATIC, LIBUSBLOC, FORCELIBUSBLOC] + * usb_io.c and usb_io.h: + Changed to rename usb_bulk_read and usb_bulk_write to + MY_usb_bulk_read and MY_usb_bulk_write respectively to + avoid any symbol clashes with libusb. + * usb_io.h: + Changed to add __may_alias__ as an attribute to struct + typefile to avoid warnings with gcc4.4. + +2008-08-26 Gordon Lack + * Version 1.14o + Call usb_claim_interface() in find_toppy as we usb_open() it. + Remove ioctl calls to claim/reset/set the device in puppy.c + (This removes warnings about not claiming interface before + use on 2.6.x(?) kernels.) + Only changed for the NEW_DEV_SCAN build. + +2008-12-13 Gordon Lack + * Version 1.14n + [Corresponding changes in ftpd-topfield-0.7.7n] + * puppy.c, + Use libusb to scan bus for devices by: + o use first found (default) + o use Nth (count from 0) + o use mmm/nnn as Bus mmm Dev nnn + o use Toppy with given serial number + Done by adding new file - find_toppy.c + * Remove /tmp/puppy lock. Claiming USB device is exclusive and + a single lock file doesn't work for multiple devices. + * For libusb scan mode, claim the interface before resetting + it. + * usb_io.c: + Don't crc check packets with a crc of 0. + This makes it work with R2-D2's USB accelerator patches + without needing to be told by a command-line option. + * Added this Changelog file. + * Build options now: + make + => New bus scan + make OLD_DEV_SCAN=1 + => Old reading of /proc/bus/usb/devices diff -urN puppy_1.14/Makefile puppy_1.14p/Makefile --- puppy_1.14/Makefile 2008-04-10 06:44:21.000000000 +0100 +++ puppy_1.14p/Makefile 2011-03-20 17:18:41.000000000 +0000 @@ -38,7 +38,30 @@ CFLAGS+=-std=gnu99 -Wall -W -Wshadow -Wstrict-prototypes -pedantic -fexpensive-optimizations -fomit-frame-pointer -frename-registers -O2 -puppy: puppy.o crc16.o mjd.o tf_bytes.o usb_io.o +ifndef OLD_DEV_SCAN + CFLAGS += -DNEW_DEV_SCAN + ifdef LIBUSBLOC + CFLAGS += -I$(LIBUSBLOC)/include + LDFLAGS += -L$(LIBUSBLOC)/lib + endif +# !!! These need to get added at the *END* of the compile line!!!! + ifdef STATIC + ifdef LIBUSBLOC + LDLIBS += $(LIBUSBLOC)/lib/libusb.a + else +# New gcc (gcc4?) allows this syntax for .a by dir searching + LDLIBS += -l:libusb.a + endif + else + LDLIBS += -lusb + endif + ifdef FORCELIBUSBLOC + LDFLAGS += -Wl,-rpath,$(LIBUSBLOC)/lib + endif + XTRAO := find_toppy.o +endif + +puppy: puppy.o crc16.o mjd.o tf_bytes.o usb_io.o $(XTRAO) strip: puppy ${STRIP} puppy diff -urN puppy_1.14/find_toppy.c puppy_1.14p/find_toppy.c --- puppy_1.14/find_toppy.c 1970-01-01 01:00:00.000000000 +0100 +++ puppy_1.14p/find_toppy.c 2011-03-17 20:39:58.000000000 +0000 @@ -0,0 +1,143 @@ +/* $Id: usbutil.c,v 1.4 2006/01/05 04:25:10 msteveb Exp $ */ + +/* + Copyright (c) 2008 Gordon Lack + + puppy 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 puppy; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include + +#include + +/* The intention with libusb is to hide all of the internals, but to + * fit in with the rest of the puppy code we'll reach in and fish + * out the fd element here. + * This description is not complete by any means - it is *JUST* there + * to access fd (which happens to be the first element). + */ +struct usb_dev_handle { + int fd; +}; + +#define TOPFIELD_VENDOR_ID 0x11DB +#define TOPFIELD_5000PVRT_ID 0x1000 + +/* Return a toppy device open unit. Return -1 on failure */ + +int find_toppy(char *device) { + int err = 0; + int found = 0; + int count = 0; + struct usb_dev_handle *devh = NULL; + struct usb_device *usb_dev = NULL; + struct usb_bus *bus = NULL; + char serial[64]; + char bus_buf[4], dev_buf[4]; + char *want_bus, *want_dev; + int want_nth; + int vendor_id = TOPFIELD_VENDOR_ID; + int product_id = TOPFIELD_5000PVRT_ID; + + want_bus = bus_buf; + want_dev = dev_buf; + + usb_init(); + usb_find_busses(); + usb_find_devices(); + +/* If device is NULL, we just get the first toppy. + * If it is a single digit, we get the (N+1)th toppy (historic) [i.e. + * 0 is the first up to 9 being the tenth. + * If it matches xxx/yyy we look for Bus xxx, Device yyy + * Otherwise we look for a Toppy with the given Serial number + */ + if (device) { + if ((strlen(device) == 1) && + (*device >= '0' && *device <= '9')) { + want_nth = *device - '0'; + want_bus = NULL; + want_dev = NULL; + } + else { + if (2 == sscanf(device, "%3s/%3s", want_bus, want_dev)) { + want_nth = -1; /* OK */ + } + else { + want_nth = -1; + want_bus = NULL; + want_dev = NULL; + } + } + } + else { + want_nth = 0; + want_bus = NULL; + want_dev = NULL; + } + +/* Loop through busses and devices to find the device with + * a matching vendor and product id + */ + + for (bus = usb_busses; bus; bus = bus->next) { + for (usb_dev = bus->devices; usb_dev; usb_dev = usb_dev->next) { + if ((usb_dev->descriptor.idVendor == vendor_id) && + (usb_dev->descriptor.idProduct == product_id)) { + if (want_nth == count++) { + found = 1; + goto got_it; + } + if (want_bus && + (0 == strcmp(want_bus, bus->dirname) && + 0 == strcmp(want_dev, usb_dev->filename))) { + found = 1; + goto got_it; + } + devh = usb_open(usb_dev); + if (devh) { + usb_get_string_simple(devh, usb_dev->descriptor.iSerialNumber, serial, sizeof(serial)); + if (0 == strcmp(serial, device)) { + found = 1; + goto got_it; + } + else { + usb_close(devh); + } + } + } + } + } +got_it: + + if (!found) { + fprintf(stderr, "No Toppy device: %s\n", device); + return -1; + } + + devh = usb_open(usb_dev); + + if (!devh) { + fprintf(stderr, "usb_open returned failure\n"); + return -1; + } + +/* Now claim the interface here too */ + + if((err = usb_claim_interface(devh, 0))) { + fprintf(stderr, "usb_claim_interface returned an error (%d)\n", err); + usb_close(devh); + return -1; + } + + return devh->fd; +} diff -urN puppy_1.14/puppy.c puppy_1.14p/puppy.c --- puppy_1.14/puppy.c 2008-04-10 06:48:02.000000000 +0100 +++ puppy_1.14p/puppy.c 2011-03-19 01:48:37.000000000 +0000 @@ -27,7 +27,7 @@ */ -#define PUPPY_RELEASE "1.14" +#define PUPPY_RELEASE "1.14p" #define _LARGEFILE64_SOURCE @@ -55,7 +55,12 @@ extern time_t timezone; +#ifdef NEW_DEV_SCAN +int newscan_fd; +int find_toppy(char *device); +#else int lockFd = -1; +#endif int quiet = 0; char *devPath = NULL; __u32 cmd = 0; @@ -95,13 +100,16 @@ int main(int argc, char *argv[]) { +#ifndef NEW_DEV_SCAN struct usb_device_descriptor devDesc; +#endif int fd = -1; int r; /* Initialise timezone handling. */ tzset(); +#ifndef NEW_DEV_SCAN lockFd = open("/tmp/puppy", O_CREAT, S_IRUSR | S_IWUSR); if(lockFd < 0) { @@ -109,13 +117,16 @@ strerror(errno)); return E_LOCK_FILE; } - +#endif r = parseArgs(argc, argv); if(r != 0) { return E_INVALID_ARGS; } +#ifdef NEW_DEV_SCAN + fd = newscan_fd; +#else /* Create a lock, so that other instances of puppy can detect this one. */ if(0 != flock(lockFd, LOCK_SH | LOCK_NB)) { @@ -155,9 +166,24 @@ close(fd); return E_NOT_TF5000PVR; } +#endif trace(1, fprintf(stderr, "Found a Topfield TF5000PVRt\n")); +/* We called usb_claim_interface() in find_toppy() + * We don't need to claim/reset/set here. + * If we do then kernel 2.6.30 (on a Plug Computer) reports: + * + Aug 19 23:18:12 ubuntu kernel: usb 1-1.1: + reset high speed USB device using orion-ehci and address 5 + Aug 19 23:18:13 ubuntu kernel: usb 1-1.1: + usbfs: process 3833 (puppy) did not claim interface 0 before use + * + * Just using usb_claim_interface(), as ftpd-topfield does, removes these + * messages, and works. + * Only changed for the NEW_DEV_SCAN code path + */ +#ifndef NEW_DEV_SCAN trace(2, fprintf(stderr, "USBDEVFS_RESET\n")); r = ioctl(fd, USBDEVFS_RESET, NULL); if(r < 0) @@ -181,6 +207,15 @@ } } + trace(2, fprintf(stderr, "USBDEVFS_RESET\n")); + r = ioctl(fd, USBDEVFS_RESET, NULL); + if(r < 0) + { + fprintf(stderr, "ERROR: Can not reset device: %s\n", strerror(errno)); + close(fd); + return E_RESET_DEVICE; + } + { struct usbdevfs_setinterface interface0 = { 0, 0 }; @@ -194,7 +229,7 @@ return E_SET_INTERFACE; } } - +#endif switch (cmd) { case CANCEL: @@ -961,8 +996,14 @@ " -P - full packet dump output to stderr\n" " -q - quiet transfers - no progress updates\n" " -v - verbose output to stderr\n" +#ifdef NEW_DEV_SCAN + " -d - 0, 1, 2nd ... 9th Toppy found or\n" + " item 00b/00d on USB bus or\n" + " USB product serial number\n" +#else " -d - USB device (must be usbfs)\n" " for example /proc/bus/usb/001/003\n" +#endif " -c - one of size, dir, get, put, rename, delete, mkdir, reboot, cancel, turbo\n" " args - optional arguments, as required by each command\n\n" "Version: " PUPPY_RELEASE ", Compiled: " __DATE__ "\n"; @@ -1044,6 +1085,15 @@ return -1; } +#ifdef NEW_DEV_SCAN + newscan_fd = find_toppy(devPath); + if (newscan_fd < 0) { + return -1; + } +/* Call routine to return an open fd using USB bus scanning here + * and set newscan_fd to it. + */ +#else /* Search for a Toppy if the device is not specified */ if(devPath == NULL) { @@ -1054,6 +1104,7 @@ { return -1; } +#endif if(cmd == CMD_HDD_DIR) { @@ -1140,6 +1191,7 @@ return 0; } +#ifndef NEW_DEV_SCAN int isToppy(struct usb_device_descriptor *desc) { return (desc->idVendor == 0x11db) && (desc->idProduct == 0x1000); @@ -1223,3 +1275,4 @@ return NULL; } } +#endif diff -urN puppy_1.14/usb_io.c puppy_1.14p/usb_io.c --- puppy_1.14/usb_io.c 2008-04-10 06:48:02.000000000 +0100 +++ puppy_1.14p/usb_io.c 2011-02-04 00:44:52.000000000 +0000 @@ -106,14 +106,14 @@ { trace(2, fprintf(stderr, "%s\n", __func__)); - return usb_bulk_write(fd, 0x01, cancel_packet, 8, TF_PROTOCOL_TIMEOUT); + return MY_usb_bulk_write(fd, 0x01, cancel_packet, 8, TF_PROTOCOL_TIMEOUT); } ssize_t send_success(int fd) { trace(2, fprintf(stderr, "%s\n", __func__)); - return usb_bulk_write(fd, 0x01, success_packet, 8, TF_PROTOCOL_TIMEOUT); + return MY_usb_bulk_write(fd, 0x01, success_packet, 8, TF_PROTOCOL_TIMEOUT); } ssize_t send_cmd_ready(int fd) @@ -341,7 +341,7 @@ put_u16(&packet->crc, get_crc(packet)); print_packet(packet, "OUT>"); swap_out_packet(packet); - return usb_bulk_write(fd, 0x01, (__u8 *) packet, byte_count, + return MY_usb_bulk_write(fd, 0x01, (__u8 *) packet, byte_count, TF_PROTOCOL_TIMEOUT); } @@ -356,7 +356,7 @@ trace(3, fprintf(stderr, "get_tf_packet\n")); - r = usb_bulk_read(fd, 0x82, buf, MAXIMUM_PACKET_SIZE, + r = MY_usb_bulk_read(fd, 0x82, buf, MAXIMUM_PACKET_SIZE, TF_PROTOCOL_TIMEOUT); if(r < 0) { @@ -387,12 +387,25 @@ } /* Ignore CRC - support for USB accellerator patch. */ +/* Only check the CRC if it is non-zero. + * Then, if the USB Accelerator patch is applied to the Toppy, we don't + * do the check on the packets it sends with no checksum (some do still + * have checksums though). + * If the user wants/requests (well - they haven't said not to...) + * checksums, the non-zero ones will be checked. + */ if(!ignore_crc) { __u16 crc; __u16 calc_crc; crc = get_u16(&packet->crc); - calc_crc = get_crc(packet); +/* calc_crc = get_crc(packet); */ + if (crc) { + calc_crc = get_crc(packet); + } + else { + calc_crc = 0; + } /* Complain about CRC mismatch */ if(crc != calc_crc) @@ -414,7 +427,7 @@ #define MAX_WRITE 4096 /* This function is adapted from libusb */ -ssize_t usb_bulk_write(const int fd, const int ep, const __u8 * bytes, +ssize_t MY_usb_bulk_write(const int fd, const int ep, const __u8 * bytes, const ssize_t length, const int timeout) { struct usbdevfs_bulktransfer bulk; @@ -471,7 +484,7 @@ } /* This function is adapted from libusb */ -ssize_t usb_bulk_read(const int fd, const int ep, const __u8 * bytes, +ssize_t MY_usb_bulk_read(const int fd, const int ep, const __u8 * bytes, const ssize_t size, const int timeout) { struct usbdevfs_bulktransfer bulk; diff -urN puppy_1.14/usb_io.h puppy_1.14p/usb_io.h --- puppy_1.14/usb_io.h 2008-04-10 06:48:02.000000000 +0100 +++ puppy_1.14p/usb_io.h 2011-02-04 00:52:41.000000000 +0000 @@ -111,7 +111,7 @@ __u8 name[95]; __u8 unused; __u32 attrib; -} __attribute__ ((packed)); +} __attribute__ ((packed, __may_alias__)); ssize_t send_success(const int fd); @@ -131,9 +131,9 @@ ssize_t get_tf_packet(const int fd, struct tf_packet *packet); ssize_t send_tf_packet(const int fd, struct tf_packet *packet); -ssize_t usb_bulk_read(const int fd, const int ep, const __u8 * bytes, +ssize_t MY_usb_bulk_read(const int fd, const int ep, const __u8 * bytes, const ssize_t size, const int timeout); -ssize_t usb_bulk_write(const int fd, const int ep, const __u8 * bytes, +ssize_t MY_usb_bulk_write(const int fd, const int ep, const __u8 * bytes, const ssize_t length, const int timeout); ssize_t read_device_descriptor(const int fd,