#5 Patch for USB Support [pt 2]

open
nobody
None
5
2012-12-23
2012-03-22
Don Lopez
No

This is a cumulative patch that includes the previous USB patch. This has things working for all scan resolutions on my installation.

This adds a 2 second pause between the request for block 1 and the request for block 2. This seems to be happening already when the drivers is in network mode (maybe the network read function blocking while waiting for data?)

Discussion

  • Don Lopez
    Don Lopez
    2012-03-22

    diff -urN kodakaio-02.2/sane-backends-kodakaio-02.2/backend/kodakaio.c kodakaio-02.2-test/sane-backends-kodakaio-02.2/backend/kodakaio.c
    --- kodakaio-02.2/sane-backends-kodakaio-02.2/backend/kodakaio.c 2012-02-22 19:06:09.000000000 -0500
    +++ kodakaio-02.2-test/sane-backends-kodakaio-02.2/backend/kodakaio.c 2012-03-21 22:15:57.137007288 -0400
    @@ -42,7 +42,8 @@
    #define KODAKAIO_BUILD 1

    /* for usb. I don't know if this size will always work */
    -#define MAX_BLOCK_SIZE 65536
    +#define MAX_BLOCK_SIZE 32768
    +#define SCANNER_READ_TIMEOUT 15

    /* debugging levels:
    In terminal use: export SANE_DEBUG_KODAKAIO=40 to set the level to 40 or whatever
    @@ -738,54 +739,66 @@
    SANE_Status * status)
    {
    /* requests and receives data this function makes the split between USB and NET
    -this function called by a number of others */
    +this function called by a number of others
    +
    +In USB mode, this function will wait until data is available for a maximum of SCANNER_READ_TIMEOUT seconds.
    +*/
    ssize_t n = 0;
    char fmt_buf[25];
    - int count = 0;
    + time_t time_start;
    + time_t time_now;
    struct timespec usb_delay, usb_rem;
    usb_delay.tv_sec = 0;
    - usb_delay.tv_nsec = 200000000;
    + usb_delay.tv_nsec = 300000000;

    - /*DBG(15, "%s: request size = %ld, buf = %p\n", __func__, (long) buf_size, buf);*/
    -
    if (s->hw->connection == SANE_MAGICOLOR_NET) {
    - DBG(min(15,DBG_READ), "%s: net req size = %ld, buf = %p\n", __func__, (long) buf_size, buf);
    +
    + time(&time_start);
    + DBG(min(15,DBG_READ), "[%ld] %s: net req size = %ld, buf = %p\n", (long) time_start, __func__, (long) buf_size, buf);
    n = kodakaio_net_read(s, buf, buf_size, status);

    \} else if \(s->hw->connection == SANE\_MAGICOLOR\_USB\) \{
    

    -/*sleep(1); does not seem to help much */
    -/* neither does this nanosleep(&usb_delay, &usb_rem);
    -nanosleep(&usb_delay, &usb_rem);*/
    - while (n == 0 && count <= 1) {
    - n = buf_size; /* n gets overwritten by sanei_usb_read_bulk*/
    - if (buf_size == MAX_BLOCK_SIZE)
    -/* need to fix the case where the last block is MAX_BLOCK_SIZE */
    - n = MAX_BLOCK_SIZE + 1; /* assume more to come */
    -
    -/* I don't think this (like windows driver) can work because the sizes in libusb are type int.
    - n = (s->blocks + 1 - s->counter) * MAX_BLOCK_SIZE;
    - if (s->last_len)
    - n += s->last_len - MAX_BLOCK_SIZE;
    -*/
    - DBG(min(15,DBG_READ), "%s: usb req size = %ld, buf = %p\n", __func__, (long) n, buf);
    - *status = sanei_usb_read_bulk(s->fd, (SANE_Byte *) buf, (size_t *) & n);
    -/* add status diagnosis */
    - if(*status != SANE_STATUS_GOOD) {
    - DBG(min(15,DBG_READ), "sanei_usb_read_bulk gave %s\n", sane_strstatus(*status));
    - if(count == 0) {
    - sleep(0.3);
    - *status = SANE_STATUS_GOOD;
    + /* After first read, scanner likes to have a little rest */
    + if (s->counter == 2)
    + sleep(2);
    +
    + /* Start the clock for USB timeout */
    + time(&time_start);
    +
    + /* Loop until we have data */
    + while (n == 0) {
    + /* Make sure that the last read triggers the EOF on the device end */
    + n = buf_size;
    + if (buf_size < MAX_BLOCK_SIZE)
    + n++;
    +
    + DBG(min(15,DBG_READ), "[%ld] %s: usb req size = %ld, buf = %p\n", (long) time_start, __func__, (long) n, buf);
    + *status = sanei_usb_read_bulk(s->fd, (SANE_Byte *) buf, (size_t *) & n);
    +
    + if(*status != SANE_STATUS_GOOD) {
    +
    + DBG(min(15,DBG_READ), "sanei_usb_read_bulk gave %s\n", sane_strstatus(*status));
    +
    + if (*status == SANE_STATUS_EOF) {
    + /* If the we have EOF status, wait for more data */
    + time(&time_now);
    + if (difftime(time_now, time_start) < SCANNER_READ_TIMEOUT) {
    + nanosleep(&usb_delay, &usb_rem);
    + }
    + else {
    + /* Timeout */
    + return n;
    + }
    + }
    + else {
    + /* If we've encountered another type of error, return */
    + return n;
    + }
    }
    - }
    - ++count;
    +
    }
    }
    - /* !!! only report an error if we don't read anything at all*/

    - if (n < buf_size && n > 0) {
    - DBG(min(1,DBG_READ), "%s: expected = %lu, got = %ld\n", __func__, (u_long) buf_size, (long) n);
    - *status = SANE_STATUS_EOF; /* was SANE_STATUS_GOOD 20/2/12 */
    - }
    if (n == 8) {
    kodakaio_com_str(buf, fmt_buf);
    DBG(min(15,DBG_READ), "%s: size = %ld, got %s\n", __func__, (long int)n, fmt_buf);

     
  • Don Lopez
    Don Lopez
    2012-03-22

    (File upload not working for some reason)

     
  • Don Lopez
    Don Lopez
    2012-03-25

    usb-patch4.diff fixes USB without the hard-coded 2 second pause.

    There is a problem initializing scanner when using a 4-port bus-powered hub.

     
  • Don Lopez
    Don Lopez
    2012-03-25

    USB Patch [64K packets, no 2s delay]

     
    Attachments