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

Reply via email to