[sane-devel] [PATCH 1/4] canon: Fix sense_handler
Ondrej Zary
linux at rainbow-software.org
Fri Aug 10 13:35:25 UTC 2012
sense_handler() crashes with Canon IX-4015 after the scanner is powered on because
scanner returns "unit attention - power on reset" sense status as a reply to the
"Test Unit Ready" command after power on - and dev is still NULL at that time.
The non-NULL dev is needed only to check if the device is a scsi2 device. But all devices
supported by this backend have the is_scsi2 flag set so it's useless.
So remove the flag and all its usage. Also change the return value for "power on
reset" check condition to SANE_STATUS_GOOD to allow IX-4015 to work.
diff --git a/backend/canon.c b/backend/canon.c
index eba677f..f7d3fe1 100644
--- a/backend/canon.c
+++ b/backend/canon.c
@@ -325,7 +325,6 @@ static SANE_Status
sense_handler (int scsi_fd, u_char * result, void *arg)
{
static char me[] = "canon_sense_handler";
- CANON_Device *dev = (CANON_Device *) arg;
u_char sense;
int asc;
char *sense_str = NULL;
@@ -342,210 +341,198 @@ sense_handler (int scsi_fd, u_char * result, void *arg)
status = SANE_STATUS_GOOD;
- /* If the sense handler is invoked before the scanner has been
- identified, pretend that nothing has happened. */
- if (strncmp(dev->sane.vendor, "CANON", 5) != 0) return (status);
+ DBG(11, "sense data interpretation for SCSI-2 devices\n");
+ sense = result[2] & 0x0f; /* extract the sense key */
+ if (result[7] > 3) /* additional sense code available? */
+ {
+ asc = (result[12] << 8) + result[13]; /* 12: additional sense code */
+ } /* 13: a.s.c. qualifier */
+ else
+ asc = 0xffff;
- if (dev && dev->info.is_scsi2)
+ switch (sense)
{
- DBG(11, "sense data interpretation for SCSI-2 devices\n");
- sense = result[2] & 0x0f; /* extract the sense key */
- if (result[7] > 3) /* additional sense code available? */
- {
- asc = (result[12] << 8) + result[13]; /* 12: additional sense code */
- } /* 13: a.s.c. qualifier */
- else
- asc = 0xffff;
+ case 0x00:
+ DBG(11, "sense category: no error\n");
+ status = SANE_STATUS_GOOD;
+ break;
- switch (sense)
- {
- case 0x00:
- DBG(11, "sense category: no error\n");
- status = SANE_STATUS_GOOD;
- break;
-
- case 0x01:
- DBG(11, "sense category: recovered error\n");
- switch (asc)
- {
- case 0x3700:
- sense_str = SANE_I18N("rounded parameter");
- break;
- default:
- sense_str = SANE_I18N("unknown");
- }
- status = SANE_STATUS_GOOD;
- break;
+ case 0x01:
+ DBG(11, "sense category: recovered error\n");
+ switch (asc)
+ {
+ case 0x3700:
+ sense_str = SANE_I18N("rounded parameter");
+ break;
+ default:
+ sense_str = SANE_I18N("unknown");
+ }
+ status = SANE_STATUS_GOOD;
+ break;
- case 0x03:
- DBG(11, "sense category: medium error\n");
- switch (asc)
- {
- case 0x8000:
- sense_str = SANE_I18N("ADF jam");
- break;
- case 0x8001:
- sense_str = SANE_I18N("ADF cover open");
- break;
- default:
- sense_str = SANE_I18N("unknown");
- }
- status = SANE_STATUS_IO_ERROR;
- break;
+ case 0x03:
+ DBG(11, "sense category: medium error\n");
+ switch (asc)
+ {
+ case 0x8000:
+ sense_str = SANE_I18N("ADF jam");
+ break;
+ case 0x8001:
+ sense_str = SANE_I18N("ADF cover open");
+ break;
+ default:
+ sense_str = SANE_I18N("unknown");
+ }
+ status = SANE_STATUS_IO_ERROR;
+ break;
- case 0x04:
- DBG(11, "sense category: hardware error\n");
- switch (asc)
- {
- case 0x6000:
- sense_str = SANE_I18N("lamp failure");
- break;
- case 0x6200:
- sense_str = SANE_I18N("scan head positioning error");
- break;
- case 0x8001:
- sense_str = SANE_I18N("CPU check error");
- break;
- case 0x8002:
- sense_str = SANE_I18N("RAM check error");
- break;
- case 0x8003:
- sense_str = SANE_I18N("ROM check error");
- break;
- case 0x8004:
- sense_str = SANE_I18N("hardware check error");
- break;
- case 0x8005:
- sense_str = SANE_I18N("transparency unit lamp failure");
- break;
- case 0x8006:
- sense_str = SANE_I18N("transparency unit scan head "
- "positioning failure");
- break;
- default:
- sense_str = SANE_I18N("unknown");
- }
- status = SANE_STATUS_IO_ERROR;
- break;
+ case 0x04:
+ DBG(11, "sense category: hardware error\n");
+ switch (asc)
+ {
+ case 0x6000:
+ sense_str = SANE_I18N("lamp failure");
+ break;
+ case 0x6200:
+ sense_str = SANE_I18N("scan head positioning error");
+ break;
+ case 0x8001:
+ sense_str = SANE_I18N("CPU check error");
+ break;
+ case 0x8002:
+ sense_str = SANE_I18N("RAM check error");
+ break;
+ case 0x8003:
+ sense_str = SANE_I18N("ROM check error");
+ break;
+ case 0x8004:
+ sense_str = SANE_I18N("hardware check error");
+ break;
+ case 0x8005:
+ sense_str = SANE_I18N("transparency unit lamp failure");
+ break;
+ case 0x8006:
+ sense_str = SANE_I18N("transparency unit scan head "
+ "positioning failure");
+ break;
+ default:
+ sense_str = SANE_I18N("unknown");
+ }
+ status = SANE_STATUS_IO_ERROR;
+ break;
- case 0x05:
- DBG(11, "sense category: illegal request\n");
- switch (asc)
- {
- case 0x1a00:
- sense_str = SANE_I18N("parameter list length error");
- status = SANE_STATUS_IO_ERROR;
- break;
- case 0x2000:
- sense_str = SANE_I18N("invalid command operation code");
- status = SANE_STATUS_UNSUPPORTED;
- break;
- case 0x2400:
- sense_str = SANE_I18N("invalid field in CDB");
- status = SANE_STATUS_IO_ERROR;
- break;
- case 0x2500:
- sense_str = SANE_I18N("unsupported LUN");
- status = SANE_STATUS_UNSUPPORTED;
- break;
- case 0x2600:
- sense_str = SANE_I18N("invalid field in parameter list");
- status = SANE_STATUS_UNSUPPORTED;
- break;
- case 0x2c00:
- sense_str = SANE_I18N("command sequence error");
- status = SANE_STATUS_UNSUPPORTED;
- break;
- case 0x2c01:
- sense_str = SANE_I18N("too many windows specified");
- status = SANE_STATUS_UNSUPPORTED;
- break;
- case 0x3a00:
- sense_str = SANE_I18N("medium not present");
- status = SANE_STATUS_IO_ERROR;
- break;
- case 0x3d00:
- sense_str = SANE_I18N("invalid bit IDENTIFY message");
- status = SANE_STATUS_UNSUPPORTED;
- break;
- case 0x8002:
- sense_str = SANE_I18N("option not connect");
- status = SANE_STATUS_UNSUPPORTED;
- break;
- default:
- sense_str = SANE_I18N("unknown");
- status = SANE_STATUS_UNSUPPORTED;
- }
- break;
+ case 0x05:
+ DBG(11, "sense category: illegal request\n");
+ switch (asc)
+ {
+ case 0x1a00:
+ sense_str = SANE_I18N("parameter list length error");
+ status = SANE_STATUS_IO_ERROR;
+ break;
+ case 0x2000:
+ sense_str = SANE_I18N("invalid command operation code");
+ status = SANE_STATUS_UNSUPPORTED;
+ break;
+ case 0x2400:
+ sense_str = SANE_I18N("invalid field in CDB");
+ status = SANE_STATUS_IO_ERROR;
+ break;
+ case 0x2500:
+ sense_str = SANE_I18N("unsupported LUN");
+ status = SANE_STATUS_UNSUPPORTED;
+ break;
+ case 0x2600:
+ sense_str = SANE_I18N("invalid field in parameter list");
+ status = SANE_STATUS_UNSUPPORTED;
+ break;
+ case 0x2c00:
+ sense_str = SANE_I18N("command sequence error");
+ status = SANE_STATUS_UNSUPPORTED;
+ break;
+ case 0x2c01:
+ sense_str = SANE_I18N("too many windows specified");
+ status = SANE_STATUS_UNSUPPORTED;
+ break;
+ case 0x3a00:
+ sense_str = SANE_I18N("medium not present");
+ status = SANE_STATUS_IO_ERROR;
+ break;
+ case 0x3d00:
+ sense_str = SANE_I18N("invalid bit IDENTIFY message");
+ status = SANE_STATUS_UNSUPPORTED;
+ break;
+ case 0x8002:
+ sense_str = SANE_I18N("option not connect");
+ status = SANE_STATUS_UNSUPPORTED;
+ break;
+ default:
+ sense_str = SANE_I18N("unknown");
+ status = SANE_STATUS_UNSUPPORTED;
+ }
+ break;
- case 0x06:
- DBG(11, "sense category: unit attention\n");
- switch (asc)
- {
- case 0x2900:
- sense_str = SANE_I18N("power on reset / bus device reset");
- status = SANE_STATUS_IO_ERROR;
- break;
- case 0x2a00:
- sense_str = SANE_I18N("parameter changed by another initiator");
- status = SANE_STATUS_IO_ERROR;
- break;
- default:
- sense_str = SANE_I18N("unknown");
- status = SANE_STATUS_IO_ERROR;
- }
- break;
+ case 0x06:
+ DBG(11, "sense category: unit attention\n");
+ switch (asc)
+ {
+ case 0x2900:
+ sense_str = SANE_I18N("power on reset / bus device reset");
+ status = SANE_STATUS_GOOD;
+ break;
+ case 0x2a00:
+ sense_str = SANE_I18N("parameter changed by another initiator");
+ status = SANE_STATUS_IO_ERROR;
+ break;
+ default:
+ sense_str = SANE_I18N("unknown");
+ status = SANE_STATUS_IO_ERROR;
+ }
+ break;
- case 0x0b:
- DBG(11, "sense category: non-standard\n");
- switch (asc)
- {
- case 0x0000:
- sense_str = SANE_I18N("no additional sense information");
- status = SANE_STATUS_IO_ERROR;
- break;
- case 0x4500:
- sense_str = SANE_I18N("reselect failure");
- status = SANE_STATUS_IO_ERROR;
- break;
- case 0x4700:
- sense_str = SANE_I18N("SCSI parity error");
- status = SANE_STATUS_IO_ERROR;
- break;
- case 0x4800:
- sense_str = SANE_I18N("initiator detected error message "
- "received");
- status = SANE_STATUS_IO_ERROR;
- break;
- case 0x4900:
- sense_str = SANE_I18N("invalid message error");
- status = SANE_STATUS_UNSUPPORTED;
- break;
- case 0x8000:
- sense_str = SANE_I18N("timeout error");
- status = SANE_STATUS_IO_ERROR;
- break;
- case 0x8001:
- sense_str = SANE_I18N("transparency unit shading error");
- status = SANE_STATUS_IO_ERROR;
- break;
- case 0x8003:
- sense_str = SANE_I18N("lamp not stabilized");
- status = SANE_STATUS_IO_ERROR;
- break;
- default:
- sense_str = SANE_I18N("unknown");
- status = SANE_STATUS_IO_ERROR;
- }
- break;
- default:
- DBG(11, "sense category: else\n");
- }
- }
- else
- {
- sense_str = SANE_I18N("problem not analyzed (unknown SCSI class)");
- status = SANE_STATUS_IO_ERROR;
+ case 0x0b:
+ DBG(11, "sense category: non-standard\n");
+ switch (asc)
+ {
+ case 0x0000:
+ sense_str = SANE_I18N("no additional sense information");
+ status = SANE_STATUS_IO_ERROR;
+ break;
+ case 0x4500:
+ sense_str = SANE_I18N("reselect failure");
+ status = SANE_STATUS_IO_ERROR;
+ break;
+ case 0x4700:
+ sense_str = SANE_I18N("SCSI parity error");
+ status = SANE_STATUS_IO_ERROR;
+ break;
+ case 0x4800:
+ sense_str = SANE_I18N("initiator detected error message "
+ "received");
+ status = SANE_STATUS_IO_ERROR;
+ break;
+ case 0x4900:
+ sense_str = SANE_I18N("invalid message error");
+ status = SANE_STATUS_UNSUPPORTED;
+ break;
+ case 0x8000:
+ sense_str = SANE_I18N("timeout error");
+ status = SANE_STATUS_IO_ERROR;
+ break;
+ case 0x8001:
+ sense_str = SANE_I18N("transparency unit shading error");
+ status = SANE_STATUS_IO_ERROR;
+ break;
+ case 0x8003:
+ sense_str = SANE_I18N("lamp not stabilized");
+ status = SANE_STATUS_IO_ERROR;
+ break;
+ default:
+ sense_str = SANE_I18N("unknown");
+ status = SANE_STATUS_IO_ERROR;
+ }
+ break;
+ default:
+ DBG(11, "sense category: else\n");
}
DBG (11, "sense message: %s\n", sense_str);
#if 0 /* superfluous? [U.D.] */
@@ -855,7 +842,6 @@ attach (const char *devnam, CANON_Device ** devp)
- whether it can calibrate itself
- whether it can eject the media
- whether it can mirror the scanned data
- - whether it is an SCSI-2 device (gives status information by "sense key")
- whether it is a film scanner (or can be used as one)
- whether it has fixed, hardware-set scan resolutions only
*/
@@ -870,7 +856,6 @@ attach (const char *devnam, CANON_Device ** devp)
dev->info.can_calibrate = SANE_FALSE;
dev->info.can_eject = SANE_TRUE;
dev->info.can_mirror = SANE_TRUE;
- dev->info.is_scsi2 = SANE_TRUE;
dev->info.is_filmscanner = SANE_TRUE;
dev->info.has_fixed_resolutions = SANE_TRUE;
}
@@ -885,7 +870,6 @@ attach (const char *devnam, CANON_Device ** devp)
dev->info.can_calibrate = SANE_FALSE;
dev->info.can_eject = SANE_TRUE;
dev->info.can_mirror = SANE_TRUE;
- dev->info.is_scsi2 = SANE_TRUE;
dev->info.is_filmscanner = SANE_TRUE;
dev->info.has_fixed_resolutions = SANE_TRUE;
}
@@ -900,7 +884,6 @@ attach (const char *devnam, CANON_Device ** devp)
dev->info.can_calibrate = SANE_TRUE;
dev->info.can_eject = SANE_FALSE;
dev->info.can_mirror = SANE_FALSE;
- dev->info.is_scsi2 = SANE_TRUE;
dev->info.is_filmscanner = SANE_FALSE;
dev->info.has_fixed_resolutions = SANE_TRUE;
}
@@ -915,7 +898,6 @@ attach (const char *devnam, CANON_Device ** devp)
dev->info.can_calibrate = SANE_FALSE;
dev->info.can_eject = SANE_FALSE;
dev->info.can_mirror = SANE_FALSE;
- dev->info.is_scsi2 = SANE_TRUE;
dev->info.is_filmscanner = SANE_FALSE;
dev->info.has_fixed_resolutions = SANE_TRUE;
}
@@ -930,7 +912,6 @@ attach (const char *devnam, CANON_Device ** devp)
dev->info.can_calibrate = SANE_FALSE;
dev->info.can_eject = SANE_FALSE;
dev->info.can_mirror = SANE_TRUE;
- dev->info.is_scsi2 = SANE_TRUE;
dev->info.is_filmscanner = SANE_FALSE;
dev->info.has_fixed_resolutions = SANE_FALSE;
}
diff --git a/backend/canon.h b/backend/canon.h
index b61823d..a3ad7ae 100644
--- a/backend/canon.h
+++ b/backend/canon.h
@@ -247,7 +247,6 @@ typedef struct CANON_Info
SANE_Bool can_calibrate; /* has got calibration control */
SANE_Bool can_eject; /* can eject medium */
SANE_Bool can_mirror; /* can mirror image by hardware */
- SANE_Bool is_scsi2; /* is an SCSI-2 device */
SANE_Bool is_filmscanner;
SANE_Bool has_fixed_resolutions; /* only a finite number possible */
}
--
Ondrej Zary
More information about the sane-devel
mailing list