Here is a first draft of a userland program for loading
EZUSB "firmware" automatically through the hotplugging system.
This should not only fix the copyright problems, but will also
make the kernel a bit smaller and make it easier to but EZUSB device
devlopment.
I do not have any EZUSB device on which to try it, so
I have no idea if it works, and I have not converted the keyspan*fw.h
files to data files for it yet. However, any input, experimentation
or comments are welcome.
Adam J. Richter __ ______________ 4880 Stevens Creek Blvd, Suite 104
[EMAIL PROTECTED] \ / San Jose, California 95129-1034
+1 408 261-6630 | g g d r a s i l United States of America
fax +1 408 261-6631 "Free Software For The Rest Of Us."
/*****************************************************************************/
/*
* ezusb_load.c -- Loads software into an 8051-based "ezusb" device.
*
* ezusb_load.c is derived from:
*
* lspci.c by Thomas Sailer,
* linux-2.4.0-test10/include/linux/usb.h probably by Randy Dunlap
* linux-2.4.3/drivers/usb/usbserial.c by Greg Kroah-Hartman
* pcimodules.c by Adam J. Richter
*
* The code in usbmodules not derived from elsewhere was written by
* Adam J. Richter and is copyright Yggdrasil Computing, Inc.
*
* Copyright (C) 2000, 2001 Yggdrasil Computing, Inc.
* Copyright (C) 1999, 2000 Greg Kroah-Hartman ([EMAIL PROTECTED])
* Copyright (C) 1999 Thomas Sailer ([EMAIL PROTECTED])
* Copyright (c) 2000 Randy Dunlap <[EMAIL PROTECTED]>
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
/* Read a list of EZUSB upload records from standard input.
The format of these records is as follows:
command address length data1 data2 data3....up to a maximum of data16
command is either 0xa0 or 0xa3. It is passed in the USB control command.
Its exact meaning is unclear.
for example:
0xa0 0x1234 3 0x52 0x38 0x96
will load:
0x52 into address 0x1234 of the EZ-USB device
0x38 into address 0x1235 of the EZ-USB device
0x96 into address 0x1236 of the EZ-USB device
Input lines begining with "#" and blank lines are ignored.
The sequence should begin by using command 0xA0 to poke a 1 into the reset
register at 0x7F92, with a line like:
0xA0 0x7F92 1 0x01
and the data should end with a sequence that clears the reset register,
with a line like:
0xA0 0x7F92 1 0x00
Clearing the reset register apparently causes the a USB reset. The
device will appear to be unplugged and then plugged back in with a new
USB product ID, according to what the firmware loaded. At that point,
the appropriate kernel module should recognize it and take it from there.
To make this work, you should include something in /etc/usb/policy
along the lines of:
if [ "$ACTION" = "add" ] ; then
file=''
IFS=/
set $PRODUCT/junk
file=/usr/lib/ezusb/$(printf "0x%0x4x $1").$(printf "0x%0x4x
$2").firmware
IFS=
if [ -f "$file" ] ; then
ezusb_firmware $DEVICE <
/usr/lib/ezusb/${file}.firmware
fi
fi
*/
/*****************************************************************************/
#include <sys/types.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/param.h>
#include <linux/usbdevice_fs.h> /* for USBDEVFS_CONTROL */
#define CTRL_RETRIES 50
#define CTRL_TIMEOUT 100 /* milliseconds */
#define USB_DT_CS_DEVICE 0x21
#define USB_DT_CS_CONFIG 0x22
#define USB_DT_CS_STRING 0x23
#define USB_DT_CS_INTERFACE 0x24
#define USB_DT_CS_ENDPOINT 0x25
static int usb_control_msg(int fd,
u_int8_t requesttype,
u_int8_t request,
u_int16_t value,
u_int16_t index,
unsigned int size,
void *data)
{
int result;
int try;
struct usbdevfs_ctrltransfer ctrl;
ctrl.requesttype = requesttype;
ctrl.request = request;
ctrl.value = value;
ctrl.index = index;
ctrl.length = size;
ctrl.data = data;
ctrl.timeout = CTRL_TIMEOUT;
/* At least on UHCI controllers, this ioctl gets a lot of
ETIMEDOUT errors which can often be retried with success
one is persistent enough. So, we try 100 times, which work
on one machine, but not on my notebook computer.
--Adam J. Richter ([EMAIL PROTECTED]) 2000 November 03. */
try = 0;
do {
result = ioctl(fd, USBDEVFS_CONTROL, &ctrl);
try++;
} while (try < CTRL_RETRIES && result == -1 && errno == ETIMEDOUT);
return result;
}
#define MAXDATA 16
int
main(int argc, char **argv)
{
int fd;
unsigned int i;
char line[500];
int result;
int dataints[MAXDATA];
unsigned char databytes[MAXDATA];
int length;
int address;
int bRequest;
if ((fd = open(argv[1], O_RDWR)) == -1) {
perror(argv[1]);
return 2;
}
while (fgets(line, sizeof(line), stdin) != NULL) {
if (line[0] == '#')
continue;
result = sscanf(line, "0x%x 0x%x %d 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x
0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
&bRequest,
&address, &length,
&dataints[0],
&dataints[1],
&dataints[2],
&dataints[3],
&dataints[4],
&dataints[5],
&dataints[6],
&dataints[7],
&dataints[8],
&dataints[9],
&dataints[10],
&dataints[11],
&dataints[12],
&dataints[13],
&dataints[14],
&dataints[15]);
if (result >= 3 && result == length + 3) {
for (i = 0; i < length; i++)
databytes[i] = dataints[i];
if (usb_control_msg(fd,
0x40,
bRequest,
address, /* value */
0, /* index */
length,
databytes)<0) {
perror("usb_control_msg");
return 1;
}
}
}
close(fd);
return 0;
}
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
http://lists.sourceforge.net/lists/listinfo/linux-usb-devel