[sane-devel] FreeBSD and Microtek Scanmaker II

abel deuring a.deuring@satzbau-gmbh.de
Fri, 20 Jun 2003 20:51:26 +0200


This is a multi-part message in MIME format.
--------------010008090309060605090400
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Henning Meier-Geinitz schrieb:

> I'm not volunteering :-) but I can at least test if any of your
> patches break Mustek scanners on FreeBSD. 

Great. I've already sent a patch to Martin, and it seems to fix the 
problems with the Microtek Scanamker II. Attached is the proposed new 
version (with Martin's fixes of my typos) of sanei_scsi_cmd2 for 
FreeBSD/CAM. It should replace the function near line 2765 in sanei_scsi.c.

Abel

--------------010008090309060605090400
Content-Type: text/plain;
 name="sanei_scsi_cmd2_freebsd"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="sanei_scsi_cmd2_freebsd"

#if USE == FREEBSD_CAM_INTERFACE
SANE_Status sanei_scsi_cmd2(int fd, 
                           const void *cmd, size_t cmd_size,
                           const void *src, size_t src_size,
			   void *dst, size_t * dst_size) {

   /* xxx obsolete size_t 		cdb_size; 
   */
   struct cam_device	*dev;
   union ccb		*ccb;
   int			rv;
   u_int32_t		ccb_flags;
   char*		data_buf;
   size_t		data_len;
   SANE_Status          status;
   
   if (fd < 0 || fd > CAM_MAXDEVS || cam_devices[fd] == NULL) {
      fprintf(stderr, "attempt to reference invalid unit %d\n", fd);
      return SANE_STATUS_INVAL;
   }

   /* xxx obsolete: cdb_size = CDB_SIZE (*(u_char *) src);
   */
   dev = cam_devices[fd];
   ccb = cam_getccb(dev);
    
   /* Build the CCB */
   bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio));
   bcopy(cmd, &ccb->csio.cdb_io.cdb_bytes, cmd_size);

   /*
    * Set the data direction flags.
    */
   if(dst_size && *dst_size) {
      /* xxx obsolete: assert (cdb_size == src_size);
      */
      ccb_flags = CAM_DIR_IN;
      data_buf = ((char*)(dst));
      data_len = *dst_size;
   }
   else if(src_size > 0) {
      ccb_flags = CAM_DIR_OUT;
      data_buf = ((char*)(src));
      data_len = src_size;
   }
   else {
      ccb_flags = CAM_DIR_NONE;
      data_buf = NULL;
      data_len = 0;
   }

   cam_fill_csio(&ccb->csio,
		 /* retries */ 1,
		 /* cbfncp */ NULL,
		 /* flags */ ccb_flags,
		 /* tag_action */ MSG_SIMPLE_Q_TAG,
		 /* data_ptr */ (u_int8_t *)data_buf,
		 /* dxfer_len */ data_len,
		 /* sense_len */ SSD_FULL_SIZE,
		 /* cdb_len */ cmd_size,
		 /* timeout */ sane_scsicmd_timeout * 1000);

   /* Run the command */
   errno = 0;
   if ((rv = cam_send_ccb(dev, ccb)) == -1) {
      cam_freeccb(ccb);
      return(SANE_STATUS_IO_ERROR);
   }
	
   if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
      SANEI_SCSI_Sense_Handler handler;

      DBG (1, "sanei_scsi_cmd: scsi returned with status %d\n", 
	   (ccb->ccb_h.status & CAM_STATUS_MASK));

      /*
      if((ccb->ccb_h.status & CAM_STATUS_MASK) 
	 == SANE_STATUS_DEVICE_BUSY)
	 return SANE_STATUS_DEVICE_BUSY;
      */

      switch (ccb->ccb_h.status & CAM_STATUS_MASK)
      {
         case CAM_BUSY:
         case CAM_SEL_TIMEOUT:
         case CAM_SCSI_BUSY:
            status = SANE_STATUS_DEVICE_BUSY;
            break;
         default:
            status = SANE_STATUS_IO_ERROR;
      }

      handler = fd_info[fd].sense_handler;
      if (handler && (ccb->ccb_h.status & CAM_AUTOSNS_VALID)) {
	 SANE_Status st = (*handler) 
	     (fd, ((u_char*)(&ccb->csio.sense_data)),
				      fd_info[fd].sense_handler_arg);
	 cam_freeccb(ccb);
	 return st;
      }
      else {
	  cam_freeccb(ccb);
	  return status;
      }
   }
   cam_freeccb(ccb);
   return SANE_STATUS_GOOD;
}

--------------010008090309060605090400--