From 7a8ae928626a2ccecc5dd40dd4564c47d8dcb9a4 Mon Sep 17 00:00:00 2001 From: Stanislav Yuzvinsky Date: Wed, 8 May 2019 11:03:15 +0300 Subject: [PATCH] ricoh2: Rearrange init/deinit code of ricoh2 to correctly support "code flow" The backend worked incorrectly when scanning process was interrupted before the current page was scanned completely. For example, scanimage tool could not scan the next page if the previous one was interrupted. Now this issue is fixed. See also "4.4. Code Flow" in SANE API specification v.1.06. Also debug levels was changed to have better control over what should be logged. --- backend/ricoh2.c | 172 ++++++++++++++++++++++------------------ backend/ricoh2_buffer.c | 16 ++-- 2 files changed, 102 insertions(+), 86 deletions(-) diff --git a/backend/ricoh2.c b/backend/ricoh2.c index 6c7403a77..8aa938e63 100644 --- a/backend/ricoh2.c +++ b/backend/ricoh2.c @@ -90,11 +90,11 @@ typedef struct Ricoh2_Device { SANE_Device sane; SANE_Bool active; - // options + /* options */ SANE_Option_Descriptor opt[NUM_OPTIONS]; Option_Value val[NUM_OPTIONS]; - // acquiring session + /* acquiring session */ SANE_Int dn; SANE_Bool cancelled; Scan_Mode mode; @@ -186,7 +186,7 @@ attach (SANE_String_Const devname) return SANE_STATUS_NO_MEM; } - DBG (2, "attach %s\n", devname); + DBG (8, "attach %s\n", devname); status = sanei_usb_open (devname, &dn); if (status != SANE_STATUS_GOOD) { @@ -227,7 +227,7 @@ init_options(Ricoh2_Device *dev) { SANE_Option_Descriptor *od; - DBG (2, "init_options: dev = %p\n", (void *) dev); + DBG (8, "init_options: dev = %p\n", (void *) dev); /* number of options */ od = &(dev->opt[OPT_NUM_OPTS]); @@ -281,7 +281,7 @@ sane_init (SANE_Int *vc, SANE_Auth_Callback __sane_unused__ cb) DBG_INIT (); - DBG(2, "sane_init\n"); + DBG(8, ">sane_init\n"); sanei_usb_init (); sanei_usb_set_timeout (USB_TIMEOUT_MS); @@ -295,7 +295,7 @@ sane_init (SANE_Int *vc, SANE_Auth_Callback __sane_unused__ cb) if (vc) *vc = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, V_MINOR, 0); - DBG(2, "sane_init: end\n"); + DBG(8, "sane_get_devices\n"); num_devices = 0; sanei_usb_find_devices (0x5ca, 0x042c, attach); @@ -331,7 +331,10 @@ sane_get_devices (const SANE_Device ***dl, sane_devices[i] = NULL; *dl = sane_devices; + DBG(2, "found %i devices\n", i); + DBG(8, "sane_open: devicename=\"%s\", handle=%p\n", name, (void *) handle); CHECK_IF (initialized); @@ -363,7 +366,7 @@ sane_open (SANE_String_Const name, SANE_Handle *handle) if (!device) { - DBG (2, "sane_open: Not a Ricoh device\n"); + DBG (1, "sane_open: Not a Ricoh device\n"); return SANE_STATUS_INVAL; } @@ -371,7 +374,7 @@ sane_open (SANE_String_Const name, SANE_Handle *handle) if (status != SANE_STATUS_GOOD) return status; - DBG (2, "sane_open: end\n"); + DBG (8, "opt[option].name) { - DBG (100, "sane_get_option_descriptor: name=%s\n", + DBG (8, ">sane_get_option_descriptor: name=%s\n", device->opt[option].name); } @@ -413,8 +416,8 @@ sane_control_option (SANE_Handle handle, Ricoh2_Device *device; SANE_Status status; - DBG (2, - "sane_control_option: handle=%p, opt=%d, act=%d, val=%p, info=%p\n", + DBG (8, + ">sane_control_option: handle=%p, opt=%d, act=%d, val=%p, info=%p\n", (void *) handle, option, action, (void *) value, (void *) info); CHECK_IF (initialized); @@ -433,16 +436,16 @@ sane_control_option (SANE_Handle handle, switch (option) { case OPT_RESOLUTION: - DBG (100, - "Setting value to default value of %d for option %s\n", + DBG (2, + "Setting value to default value of '%d' for option '%s'\n", default_resolution, device->opt[option].name); device->val[option].w = default_resolution; break; case OPT_MODE: - DBG (100, - "Setting value to default value of %s for option %s\n", + DBG (2, + "Setting value to default value of '%s' for option '%s'\n", (SANE_String_Const) default_mode, device->opt[option].name); strcpy (device->val[option].s, default_mode); @@ -472,16 +475,16 @@ sane_control_option (SANE_Handle handle, switch (option) { case OPT_RESOLUTION: - DBG (100, - "Setting value to %d for option %s\n", + DBG (2, + "Setting value to '%d' for option '%s'\n", *(SANE_Word *) value, device->opt[option].name); device->val[option].w = *(SANE_Word *) value; break; case OPT_MODE: - DBG (100, - "Setting value to %s for option %s\n", + DBG (2, + "Setting value to '%s' for option '%s'\n", (SANE_String_Const)value, device->opt[option].name); strcpy (device->val[option].s, value); @@ -499,7 +502,7 @@ sane_control_option (SANE_Handle handle, case OPT_NUM_OPTS: case OPT_RESOLUTION: *(SANE_Word *) value = device->val[option].w; - DBG (100, "Option value = %d (%s)\n", *(SANE_Word *) value, + DBG (2, "Option value = %d (%s)\n", *(SANE_Word *) value, device->opt[option].name); break; case OPT_MODE: @@ -514,6 +517,7 @@ sane_control_option (SANE_Handle handle, return SANE_STATUS_INVAL; } + DBG (8, "bytes_per_line *= 3; } - DBG (2, "sane_get_parametrs: format = %s bytes_per_line = %d " + DBG (8, ">sane_get_parameters: format = %s bytes_per_line = %d " "depth = %d " "pixels_per_line = %d " "lines = %d\n", @@ -606,7 +610,7 @@ send_receive (SANE_Int dn, Send_Receive_Pair *transfer) /* send a command */ io_size = MAX_COMMAND_SIZE; - DBG (255, "sending a packet of size %lu\n", io_size); + DBG (128, "sending a packet of size %lu\n", io_size); memcpy (send_buffer, transfer->send_buffer, transfer->to_send); status = sanei_usb_write_bulk (dn, send_buffer, &io_size); if (status != SANE_STATUS_GOOD) @@ -617,7 +621,7 @@ send_receive (SANE_Int dn, Send_Receive_Pair *transfer) /* receive a result */ io_size = transfer->to_receive; - DBG (255, "receiving a packet of size %lu\n", io_size); + DBG (128, "receiving a packet of size %lu\n", io_size); if (io_size) { status = sanei_usb_read_bulk (dn, transfer->receive_buffer, &io_size); @@ -641,7 +645,7 @@ static SANE_Status init_scan(SANE_Int dn, Scan_Mode mode, SANE_Int resolution) { SANE_Status status = SANE_STATUS_GOOD; - SANE_Byte dummy_buffer[11]; // the longest expected reply + SANE_Byte dummy_buffer[11]; /* the longest expected reply */ size_t i; SANE_Byte urb_init[] = { 0x03, 0x09, 0x01 }; @@ -673,13 +677,35 @@ init_scan(SANE_Int dn, Scan_Mode mode, SANE_Int resolution) && (status == SANE_STATUS_GOOD); ++i) { - DBG (255, "sending initialization packet %zi\n", i); + DBG (128, "sending initialization packet %zi\n", i); status = send_receive (dn, transfer + i); } return status; } +void +teardown_scan(SANE_Int dn) +{ + SANE_Byte cancel_command[] = { 0x03, 0x0a }; + SANE_Byte end_command[] = { 0x03, 0x09, 0x01 }; + SANE_Byte dummy_buffer; + Send_Receive_Pair transfer; + + DBG (128, "Sending cancel command\n"); + transfer.send_buffer = cancel_command; + transfer.to_send = sizeof (cancel_command); + transfer.receive_buffer = &dummy_buffer; + transfer.to_receive = 0; + send_receive (dn, &transfer); + + transfer.send_buffer = end_command; + transfer.to_send = sizeof (end_command); + transfer.receive_buffer = &dummy_buffer; + transfer.to_receive = 1; + send_receive (dn, &transfer); +} + SANE_Status sane_start (SANE_Handle handle) { @@ -688,7 +714,7 @@ sane_start (SANE_Handle handle) SANE_Int pixels_per_line; SANE_Int resolution_factor = 1; - DBG (2, "sane_start: handle=%p\n", (void *) handle); + DBG (8, ">sane_start: handle=%p\n", (void *) handle); CHECK_IF (initialized); device = lookup_handle (handle); @@ -757,7 +783,7 @@ sane_start (SANE_Handle handle) INFO_SIZE * resolution_factor, device->mode == SCAN_MODE_COLOR); - DBG (2, "sane_start: to read %lu\n", device->bytes_to_read); + DBG (8, "bytes_to_read); return SANE_STATUS_GOOD; } @@ -769,15 +795,12 @@ sane_read (SANE_Handle handle, SANE_Int *length) { SANE_Byte read_next_command[] = { 0x03, 0x0E, 0x04, 0, 0, 0, 0, 240 }; - SANE_Byte cancel_command[] = { 0x03, 0x0a }; - SANE_Byte end_command[] = { 0x03, 0x09, 0x01 }; Ricoh2_Device *device; SANE_Status status; Send_Receive_Pair transfer; - SANE_Byte dummy_buf; - DBG (2, "sane_read: handle=%p, data=%p, maxlen = %d, length=%p\n", + DBG (16, ">sane_read: handle=%p, data=%p, maxlen = %d, length=%p\n", (void *) handle, (void *) data, maxlen, (void *) length); CHECK_IF (initialized); @@ -786,8 +809,10 @@ sane_read (SANE_Handle handle, CHECK_IF (length); CHECK_IF (maxlen); - // EOF has already been reached before or acquisition process hasn't - // been initiated at all + /* + EOF has already been reached before or acquisition process hasn't + been initiated at all + */ if (device->bytes_to_read <= 0) { return SANE_STATUS_EOF; @@ -802,13 +827,12 @@ sane_read (SANE_Handle handle, transfer.to_receive = MAX_LINE_SIZE; read_next_command[7] = transfer.to_receive / 256; - DBG (2, "Receiving data of size %zi\n", transfer.to_receive); + DBG (128, "Receiving data of size %zi\n", transfer.to_receive); status = send_receive (device->dn, &transfer); if (status != SANE_STATUS_GOOD) { device->bytes_to_read = 0; - device->cancelled = SANE_TRUE; return status; } } @@ -819,49 +843,25 @@ sane_read (SANE_Handle handle, device->bytes_to_read -= *length; - DBG (2, + DBG (128, "Read length %d, left to read %lu\n", *length, device->bytes_to_read); - DBG (2, + DBG (128, "%d bytes remain in the buffer\n", ricoh2_buffer_get_bytes_remain(device->buffer)); - // either we've just reached expected data size - // or the user has cancelled the process - if ((device->bytes_to_read <= 0) || (device->cancelled)) - { - DBG (2, "Sending cancel command\n"); - transfer.send_buffer = cancel_command; - transfer.to_send = sizeof (cancel_command); - transfer.receive_buffer = &dummy_buf; - transfer.to_receive = 0; - send_receive(device->dn, &transfer); - - transfer.send_buffer = end_command; - transfer.to_send = sizeof (end_command); - transfer.receive_buffer = &dummy_buf; - transfer.to_receive = 1; - send_receive(device->dn, &transfer); - - sanei_usb_close(device->dn); - - ricoh2_buffer_dispose(device->buffer); - device->buffer = NULL; - } - - if (device->cancelled) - { - device->cancelled = SANE_FALSE; - return SANE_STATUS_CANCELLED; - } - + /* we've just reached expected data size */ if (device->bytes_to_read <= 0) { + ricoh2_buffer_dispose(device->buffer); + device->buffer = NULL; return SANE_STATUS_EOF; } + DBG (16, "sane_cancel: handle = %p\n", (void *) handle); if (!initialized) return; - if (!(device = lookup_handle(handle))) + if (!(device = lookup_handle (handle))) return; + if (device->cancelled) + return; + device->cancelled = SANE_TRUE; + + teardown_scan (device->dn); + if (device->buffer) + { + ricoh2_buffer_dispose (device->buffer); + device->buffer = NULL; + } + + sanei_usb_close(device->dn); + + DBG (8, "sane_close\n"); + DBG (8, ">sane_close\n"); if (!initialized) return; @@ -926,9 +940,9 @@ sane_close (SANE_Handle handle) if (!device) return; - sanei_usb_exit(); + /* noop */ - DBG (2, "sane_exit\n"); if (!initialized) return; @@ -952,4 +966,6 @@ sane_exit (void) sanei_usb_exit (); initialized = SANE_FALSE; + + DBG (8, "remain_in_line = pixels_per_line; - DBG (100, + DBG (192, "size = %d pixels_per_line = %d info_size = %d rgb? = %d pos = %d\n", self->size, self->pixels_per_line, @@ -121,12 +121,12 @@ static SANE_Byte * ricoh2_buffer_get_internal_buffer (ricoh2_buffer *self) { assert (self); - DBG (100, "engaging a buffer of size %d\n", self->size); + DBG (192, "engaging a buffer of size %d\n", self->size); self->current_position = 0; self->remain_in_line = self->pixels_per_line; - DBG (100, "remain in line = %d\n", self->remain_in_line); + DBG (192, "remain in line = %d\n", self->remain_in_line); return self->data; } @@ -136,7 +136,7 @@ ricoh2_buffer_get_bytes_remain (ricoh2_buffer *self) { assert (self); - DBG (100, + DBG (192, "bytes remain in the buffer %d\n", self->size - self->current_position); @@ -168,7 +168,7 @@ ricoh2_buffer_get_data (ricoh2_buffer *self, bytes_per_pixel = self->is_rgb ? 3 : 1; bytes_per_color = self->pixels_per_line + self->info_size; - DBG (2, + DBG (192, "trying to get %d bytes from the buffer, " "while %d bytes in the line\n", dest_size, @@ -181,7 +181,7 @@ ricoh2_buffer_get_data (ricoh2_buffer *self, min (dest_size / bytes_per_pixel, self->remain_in_line)) { - DBG (2, + DBG (192, "providing %d bytes to the user (until the end of the line), " "position in buffer is %d\n", pixels_to_copy * bytes_per_pixel, @@ -212,12 +212,12 @@ ricoh2_buffer_get_data (ricoh2_buffer *self, if (self->is_rgb) self->current_position += 2 * bytes_per_color; self->remain_in_line = self->pixels_per_line; - DBG (100, + DBG (192, "Line feed, new position is %d\n", self->current_position); } - DBG (100, + DBG (192, "left in the buffer: %d\n", self->size - self->current_position); }