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

Reply via email to