I have the same problem, with other device model.

If do not touch control endpoint for interrupt and bulk endpoints search (i.e. open /dev/ugen0.1 and /dev/igen0.2 immediately), then there is no problems.

For example, this test will be passed:

#include <sys/types.h>
#include <sys/ioctl.h>
#include <dev/usb/usb.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#include <stdio.h>
#include <err.h>
#include <assert.h>

#define OUT_BULK_DEV "/dev/ugen0.2"
#define IN_INTR_DEV "/dev/ugen0.1"
#define IN_BULK_DEV "/dev/ugen0.3"

struct packet {
    u_int8_t packet_type;
    u_int8_t reserved1[3];
    u_int16_t packet_id;
    u_int8_t reserved2[2];
    u_int32_t data_size;
};

#define USB_PROTOCOL_LAYER 0
#define APPLICATION_LAYER 20

#define PID_DATA_AVAILABLE 2
#define PID_START_SESSION 5
#define PID_SESSION_STARTED 6

#define PID_PROTOCOL_ARRAY 253
#define PID_PRODUCT_RQST 254
#define PID_PRODUCT_DATA 255

static u_int8_t const START_SESSION_REQ[] =
{ USB_PROTOCOL_LAYER, 0, 0, 0, PID_START_SESSION, 0, 0, 0, 0, 0, 0, 0 };

static u_int8_t const A000_REQ[] =
    { APPLICATION_LAYER, 0, 0, 0, PID_PRODUCT_RQST, 0, 0, 0, 0, 0, 0, 0 };

#define BUF_SIZE 1024

static int out, in_intr, in_bulk;

static void dump (u_int8_t buf[], u_int32_t len)
{
    u_int32_t i;

    if (len == 0) {
        printf("EMPTY\n");
    } else {
        for (i = 0; i < len; i++) {
            printf("%2x", buf[i]);
            if (i % 16 == 15)
                printf("\n");
            else
                printf(" ");
        }
        if (len % 16 != 0)
            printf("\n");
    }
}

static void send_req (u_int8_t const req[], int len)
{
    size_t done;

    done = write(out, req, len);
    if (done == -1)
        err(1, NULL);
    printf("write: %d\n", done);
    assert(done == len);
}

static int response_received (u_int8_t packet_type, u_int16_t packet_id, u_int8_t data[], int len)
{
    switch (packet_type) {
    case USB_PROTOCOL_LAYER:
        switch (packet_id) {
        case PID_DATA_AVAILABLE:
            printf("data available\n");
            errx(1, "not implemented"); /* TODO: switch input to in_bulk */
            break;
        case PID_SESSION_STARTED:
            printf("session started\n");
            send_req(A000_REQ, sizeof(A000_REQ));
            break;
        default:
            errx(1, "invalid packet id");
        }
        break;
    case APPLICATION_LAYER:
        switch (packet_id) {
        case PID_PRODUCT_DATA:
            break;
        case PID_PROTOCOL_ARRAY:
            return 1;
            break;
        default:
            errx(1, "invalid packet id");
        }
        break;
    default:
        errx(1, "invalid packet type");
    }
    return 0;
}

static size_t read1 (int in, void *buf, int len)
{
    int done, d;

    done = 0;
    while (done < len) {
        d = read(in, buf, len - done);
        printf("read1: %d\n", d);
        done += d;
    };

    return done;
}

static void start_loop ()
{
    int terminate = 0;
    size_t done;
    struct packet packet;
    u_int8_t buf[BUF_SIZE];

    do {
        done = read1(in_intr, buf, sizeof(packet));
        if (done == -1)
            err(1, NULL);
        printf("intr read: %d\n", done);
        assert(done == sizeof(packet));
        dump(buf, done);

        memcpy(&packet, buf, done);

        if ((packet.reserved1[0] != 0) || (packet.reserved1[1] != 0)
            || (packet.reserved1[2] != 0) || (packet.reserved2[0] != 0)
            || (packet.reserved2[1] != 0)) {
                errx(1, "inalid packet");
        }

        done = read1(in_intr, buf, packet.data_size);
        if (done == -1)
            err(1, NULL);
printf("intr expected: %d, intr read: %d\n", packet.data_size, done);
        assert(done == packet.data_size);
        dump(buf, done);

terminate = response_received(packet.packet_type, packet.packet_id, buf, packet.data_size);
    } while (!terminate);
}

int main ()
{
    out = open(OUT_BULK_DEV, O_WRONLY);
    if (out == -1)
        err(1, OUT_BULK_DEV);

    in_intr = open(IN_INTR_DEV, O_RDONLY);
    if (in_intr == -1)
        err(1, IN_INTR_DEV);

    in_bulk = open(IN_BULK_DEV, O_RDONLY);
    if (in_bulk == -1)
        err(1, IN_BULK_DEV);

    send_req(START_SESSION_REQ, sizeof(START_SESSION_REQ));

    start_loop();

    printf("all done\n");

    return 0;
}


Best regards, Alexander.
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to