root/scsi/ss_mustek.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mustek_attach
  2. mustek_set_params
  3. mustek_minphys
  4. mustek_trigger_scanner
  5. mustek_rewind_scanner
  6. mustek_read
  7. mustek_get_status
  8. mustek_compute_sizes

    1 /*      $OpenBSD: ss_mustek.c,v 1.14 2006/11/28 16:56:50 dlg Exp $      */
    2 /*      $NetBSD: ss_mustek.c,v 1.4 1996/05/05 19:52:57 christos Exp $   */
    3 
    4 /*
    5  * Copyright (c) 1995 Joachim Koenig-Baltes.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed by Joachim Koenig-Baltes.
   18  * 4. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 /*
   34  * special driver for MUSTEK flatbed scanners MFS 06000CX and MFS 12000CX
   35  * these scanners come with their own scsi card, containing an NCR53C400
   36  * SCSI controller chip. I'm in the progress of writing a driver for this
   37  * card to work under NetBSD-current. I've hooked it up to a Seagate ST01
   38  * hostadapter in the meantime, giving 350KB/sec for higher resolutions!
   39  *
   40  * I tried to connect it to my Adaptec 1542B, but with no success. It seems,
   41  * it does not like synchronous negotiation between Hostadapter and other
   42  * targets, but I could not turn this off for the 1542B.
   43  *
   44  * There is also an other reason why you would not like to connect it to your
   45  * favourite SCSI host adapter: The Mustek DOES NOT DISCONNECT. It will block
   46  * other traffic from the bus while a transfer is active.
   47  */
   48 
   49 #include <sys/types.h>
   50 #include <sys/param.h>
   51 #include <sys/kernel.h>
   52 #include <sys/systm.h>
   53 #include <sys/fcntl.h>
   54 #include <sys/errno.h>
   55 #include <sys/ioctl.h>
   56 #include <sys/malloc.h>
   57 #include <sys/buf.h>
   58 #include <sys/proc.h>
   59 #include <sys/user.h>
   60 #include <sys/device.h>
   61 #include <sys/conf.h>           /* for cdevsw */
   62 #include <sys/scanio.h>
   63 
   64 #include <scsi/scsi_all.h>
   65 #include <scsi/scsi_scanner.h>
   66 #include <scsi/scsiconf.h>
   67 #include <scsi/ssvar.h>
   68 #include <scsi/ss_mustek.h>
   69 
   70 #define MUSTEK_RETRIES 4
   71 
   72 int mustek_set_params(struct ss_softc *, struct scan_io *);
   73 int mustek_trigger_scanner(struct ss_softc *);
   74 void mustek_minphys(struct ss_softc *, struct buf *);
   75 int mustek_read(struct ss_softc *, struct buf *);
   76 int mustek_rewind_scanner(struct ss_softc *);
   77 
   78 /* only used internally */
   79 int mustek_get_status(struct ss_softc *, int, int);
   80 void mustek_compute_sizes(struct ss_softc *);
   81 
   82 /*
   83  * structure for the special handlers
   84  */
   85 struct ss_special mustek_special = {
   86         mustek_set_params,
   87         mustek_trigger_scanner,
   88         NULL,
   89         mustek_minphys,
   90         mustek_read,
   91         mustek_rewind_scanner,
   92         NULL,                   /* no adf support right now */
   93         NULL                    /* no adf support right now */
   94 };
   95 
   96 /*
   97  * mustek_attach: attach special functions to ss
   98  */
   99 void
  100 mustek_attach(ss, sa)
  101         struct ss_softc *ss;
  102         struct scsi_attach_args *sa;
  103 {
  104 #ifdef SCSIDEBUG
  105         struct scsi_link *sc_link = sa->sa_sc_link;
  106 #endif
  107 
  108         SC_DEBUG(sc_link, SDEV_DB1, ("mustek_attach: start\n"));
  109         ss->sio.scan_scanner_type = 0;
  110 
  111         printf("\n%s: ", ss->sc_dev.dv_xname);
  112 
  113         /* first, check the model which determines resolutions */
  114         if (!bcmp(sa->sa_inqbuf->product, "MFS-06000CX", 11)) {
  115                 ss->sio.scan_scanner_type = MUSTEK_06000CX;
  116                 printf("Mustek 6000CX Flatbed 3-pass color scanner, 3 - 600 dpi\n");
  117         }
  118         if (!bcmp(sa->sa_inqbuf->product, "MFS-12000CX", 11)) {
  119                 ss->sio.scan_scanner_type = MUSTEK_12000CX;
  120                 printf("Mustek 12000CX Flatbed 3-pass color scanner, 6 - 1200 dpi\n");
  121         }
  122 
  123         SC_DEBUG(sc_link, SDEV_DB1, ("mustek_attach: scanner_type = %d\n",
  124             ss->sio.scan_scanner_type));
  125 
  126         /* install special handlers */
  127         ss->special = mustek_special;
  128 
  129         mustek_compute_sizes(ss);
  130 }
  131 
  132 /*
  133  * check the parameters if the mustek is capable of fulfilling it
  134  * but don't send the command to the scanner in case the user wants
  135  * to change parameters by more than one call
  136  */
  137 int
  138 mustek_set_params(ss, sio)
  139         struct ss_softc *ss;
  140         struct scan_io *sio;
  141 {
  142         int error;
  143 
  144         /*
  145          * if the scanner is triggered, then rewind it
  146          */
  147         if (ss->flags & SSF_TRIGGERED) {
  148                 error = mustek_rewind_scanner(ss);
  149                 if (error)
  150                         return (error);
  151         }
  152 
  153         /* size constraints: 8.5" horizontally and 14" vertically */
  154 #ifdef MUSTEK_INCH_SPEC
  155         /* sizes must be a multiple of 1/8" */
  156         sio->scan_x_origin -= sio->scan_x_origin % 150;
  157         sio->scan_y_origin -= sio->scan_y_origin % 150;
  158         sio->scan_width -= sio->scan_width % 150;
  159         sio->scan_height -= sio->scan_height % 150;
  160 #endif
  161         if (sio->scan_width == 0 ||
  162             sio->scan_x_origin + sio->scan_width > 10200 ||
  163             sio->scan_height == 0 ||
  164             sio->scan_y_origin + sio->scan_height > 16800)
  165                 return (EINVAL);
  166 
  167         /*
  168          * for now, only realize the values for the MUSTEK_06000CX
  169          * in the future, values for the MUSTEK_12000CX will be implemented
  170          */
  171 
  172         /*
  173          * resolution (dpi) must be <= 300 and a multiple of 3 or
  174          * between 300 and 600 and a multiple of 30
  175          */
  176         sio->scan_x_resolution -= sio->scan_x_resolution <= 300 ?
  177             sio->scan_x_resolution % 3 : sio->scan_x_resolution % 30;
  178         sio->scan_y_resolution -= sio->scan_y_resolution <= 300 ?
  179             sio->scan_y_resolution % 3 : sio->scan_y_resolution % 30;
  180         if (sio->scan_x_resolution < 3 || sio->scan_x_resolution > 600 ||
  181             sio->scan_x_resolution != sio->scan_y_resolution)
  182                 return (EINVAL);
  183 
  184         /* assume brightness values are between 64 and 136 in steps of 3 */
  185         sio->scan_brightness -= (sio->scan_brightness - 64) % 3;
  186         if (sio->scan_brightness < 64 || sio->scan_brightness > 136)
  187                 return (EINVAL);
  188 
  189         /* contrast values must be between 16 and 184 in steps of 7 */
  190         sio->scan_contrast -= (sio->scan_contrast - 16) % 7;
  191         if (sio->scan_contrast < 16 || sio->scan_contrast > 184)
  192                 return (EINVAL);
  193 
  194         /*
  195          * velocity: between 0 (fast) and 4 (slow) which will be mapped
  196          * to 100% = 4, 80% = 3, 60% = 2, 40% = 1, 20% = 0
  197          * must be a multiple of 20
  198          */
  199         sio->scan_quality -= sio->scan_quality % 20;
  200         if (sio->scan_quality < 20 || sio->scan_quality > 100)
  201                 return (EINVAL);
  202 
  203         switch (sio->scan_image_mode) {
  204         case SIM_BINARY_MONOCHROME:
  205         case SIM_DITHERED_MONOCHROME:
  206         case SIM_GRAYSCALE:
  207         case SIM_RED:
  208         case SIM_GREEN:
  209         case SIM_BLUE:
  210                 break;
  211         default:
  212                 return (EINVAL);
  213         }
  214 
  215         /* change ss_softc to the new values, but save ro-variables */
  216         sio->scan_scanner_type = ss->sio.scan_scanner_type;
  217         bcopy(sio, &ss->sio, sizeof(struct scan_io));
  218 
  219         mustek_compute_sizes(ss);
  220 
  221         return (0);
  222 }
  223 
  224 /*
  225  * trim the requested transfer to a multiple of the line size
  226  * this is called only from ssread() which guarantees, scanner is triggered
  227  * In the future, it will trim the transfer to not read to much at a time
  228  * because the mustek cannot disconnect. It will be calculated by the
  229  * resolution, the velocity and the number of bytes per line.
  230  */
  231 void
  232 mustek_minphys(ss, bp)
  233         struct ss_softc *ss;
  234         struct buf *bp;
  235 {
  236 #ifdef SCSIDEBUG
  237         struct scsi_link *sc_link = ss->sc_link;
  238 #endif
  239 
  240         SC_DEBUG(sc_link, SDEV_DB1, ("mustek_minphys: before: %ld\n",
  241             bp->b_bcount));
  242         bp->b_bcount -= bp->b_bcount %
  243             ((ss->sio.scan_pixels_per_line * ss->sio.scan_bits_per_pixel) / 8);
  244         SC_DEBUG(sc_link, SDEV_DB1, ("mustek_minphys: after:  %ld\n",
  245             bp->b_bcount));
  246 }
  247 
  248 /*
  249  * trigger the scanner to start a scan operation
  250  * this includes sending the mode- and window-data, starting the scanner
  251  * and getting the image size info
  252  */
  253 int
  254 mustek_trigger_scanner(ss)
  255         struct ss_softc *ss;
  256 {
  257         struct mustek_mode_select_cmd mode_cmd;
  258         struct mustek_mode_select_data mode_data;
  259         struct mustek_set_window_cmd window_cmd;
  260         struct mustek_set_window_data window_data;
  261         struct mustek_start_scan_cmd start_scan_cmd;
  262         struct scsi_link *sc_link = ss->sc_link;
  263         int pixel_tlx, pixel_tly, pixel_brx, pixel_bry, paperlength;
  264         int error;
  265 
  266         mustek_compute_sizes(ss);
  267 
  268         SC_DEBUG(sc_link, SDEV_DB1, ("mustek_trigger_scanner\n"));
  269 
  270         /*
  271          * set the window params and send the scsi command
  272          */
  273         bzero(&window_cmd, sizeof(window_cmd));
  274         window_cmd.opcode = MUSTEK_SET_WINDOW;
  275         window_cmd.length = sizeof(window_data);
  276 
  277         bzero(&window_data, sizeof(window_data));
  278         window_data.frame.header = MUSTEK_LINEART_BACKGROUND | MUSTEK_UNIT_SPEC;
  279 #ifdef MUSTEK_INCH_SPEC
  280         /* the positional values are all 1 byte because 256 / 8 = 32" */
  281         pixel_tlx = ss->sio.scan_x_origin / 150;
  282         pixel_tly = ss->sio.scan_y_origin / 150;
  283         pixel_brx = pixel_tlx + ss->sio.scan_width / 150;
  284         pixel_bry = pixel_tly + ss->sio.scan_height / 150;
  285 #else
  286         pixel_tlx = (ss->sio.scan_x_origin * ss->sio.scan_x_resolution) / 1200;
  287         pixel_tly = (ss->sio.scan_y_origin * ss->sio.scan_y_resolution) / 1200;
  288         pixel_brx = pixel_tlx +
  289             (ss->sio.scan_width * ss->sio.scan_x_resolution) / 1200;
  290         pixel_bry = pixel_tly +
  291             (ss->sio.scan_height * ss->sio.scan_y_resolution) / 1200;
  292 #endif
  293         _lto2l(pixel_tlx, window_data.frame.tl_x);
  294         _lto2l(pixel_tly, window_data.frame.tl_y);
  295         _lto2l(pixel_brx, window_data.frame.br_x);
  296         _lto2l(pixel_bry, window_data.frame.br_y);
  297 
  298 #if MUSTEK_WINDOWS >= 1
  299         window_data.window1 = window_data.frame;
  300         window_data.window1.header = MUSTEK_WINDOW_MASK | MUSTEK_UNIT_SPEC;
  301 #endif
  302 
  303         /* send the set window command to the scanner */
  304         SC_DEBUG(sc_link, SDEV_DB1, ("mustek_set_parms: set_window\n"));
  305         error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &window_cmd,
  306             sizeof(window_cmd), (u_char *) &window_data, sizeof(window_data),
  307             MUSTEK_RETRIES, 5000, NULL, SCSI_DATA_OUT);
  308         if (error)
  309                 return (error);
  310 
  311         /*
  312          * do what it takes to actualize the mode
  313          */
  314         bzero(&mode_cmd, sizeof(mode_cmd));
  315         mode_cmd.opcode = MUSTEK_MODE_SELECT;
  316         _lto2b(sizeof(mode_data), mode_cmd.length);
  317 
  318         bzero(&mode_data, sizeof(mode_data));
  319         mode_data.mode =
  320             MUSTEK_MODE_MASK | MUSTEK_HT_PATTERN_BUILTIN | MUSTEK_UNIT_SPEC;
  321         if (ss->sio.scan_x_resolution <= 300) {
  322                 mode_data.resolution = ss->sio.scan_x_resolution / 3;
  323         } else {
  324                 /*
  325                  * the resolution values is computed by modulo 100, but not
  326                  * for 600dpi, where the value is 100 (a bit tricky, but ...)
  327                  */
  328                 mode_data.resolution =
  329                     ((ss->sio.scan_x_resolution - 1) % 100) + 1;
  330         }
  331         mode_data.brightness = (ss->sio.scan_brightness - 64) / 3;
  332         mode_data.contrast = (ss->sio.scan_contrast - 16) / 7;
  333         mode_data.grain = 0;
  334         mode_data.velocity = ss->sio.scan_quality / 20 - 1;
  335 #ifdef MUSTEK_INCH_SPEC
  336         paperlength = 14 * 8;   /* 14" */
  337 #else
  338         paperlength = 14 * ss->sio.scan_y_resolution;   /* 14" */
  339 #endif
  340         _lto2l(paperlength, mode_data.paperlength);
  341 
  342         SC_DEBUG(sc_link, SDEV_DB1, ("mustek_trigger_scanner: mode_select\n"));
  343         /* send the command to the scanner */
  344         error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &mode_cmd,
  345             sizeof(mode_cmd), (u_char *) &mode_data, sizeof(mode_data),
  346             MUSTEK_RETRIES, 5000, NULL, SCSI_DATA_OUT);
  347         if (error)
  348                 return (error);
  349 
  350         /*
  351          * now construct and send the start command
  352          */
  353         bzero(&start_scan_cmd,sizeof(start_scan_cmd));
  354         start_scan_cmd.opcode = MUSTEK_START_STOP;
  355         start_scan_cmd.mode = MUSTEK_SCAN_START;
  356         if (ss->sio.scan_x_resolution <= 300)
  357                 start_scan_cmd.mode |= MUSTEK_RES_STEP_1;
  358         else
  359                 start_scan_cmd.mode |= MUSTEK_RES_STEP_10;
  360         switch (ss->sio.scan_image_mode) {
  361         case SIM_BINARY_MONOCHROME:
  362         case SIM_DITHERED_MONOCHROME:
  363                 start_scan_cmd.mode |= MUSTEK_BIT_MODE | MUSTEK_GRAY_FILTER;
  364                 break;
  365         case SIM_GRAYSCALE:
  366                 start_scan_cmd.mode |= MUSTEK_GRAY_MODE | MUSTEK_GRAY_FILTER;
  367                 break;
  368         case SIM_RED:
  369                 start_scan_cmd.mode |= MUSTEK_GRAY_MODE | MUSTEK_RED_FILTER;
  370                 break;
  371         case SIM_GREEN:
  372                 start_scan_cmd.mode |= MUSTEK_GRAY_MODE | MUSTEK_GREEN_FILTER;
  373                 break;
  374         case SIM_BLUE:
  375                 start_scan_cmd.mode |= MUSTEK_GRAY_MODE | MUSTEK_BLUE_FILTER;
  376                 break;
  377         }
  378 
  379         /* send the command to the scanner */
  380         SC_DEBUG(sc_link, SDEV_DB1, ("mustek_trigger_scanner: start_scan\n"));
  381         error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &start_scan_cmd,
  382             sizeof(start_scan_cmd), NULL, 0,
  383             MUSTEK_RETRIES, 5000, NULL, 0);
  384         if (error)
  385                 return (error);
  386 
  387         /*
  388          * now check if scanner ready this time with update of size info
  389          * we wait here so that if the user issues a read directly afterwards,
  390          * the scanner will respond directly (otherwise we had to sleep with
  391          * a buffer locked in memory)
  392          */
  393         SC_DEBUG(sc_link, SDEV_DB1, ("mustek_trigger_scanner: get_status\n"));
  394         error = mustek_get_status(ss, 60, 1);
  395         if (error)
  396                 return (error);
  397 
  398         return (0);
  399 }
  400 
  401 /*
  402  * stop a scan operation in progress
  403  */
  404 int
  405 mustek_rewind_scanner(ss)
  406         struct ss_softc *ss;
  407 {
  408         struct mustek_start_scan_cmd cmd;
  409         struct scsi_link *sc_link = ss->sc_link;
  410         int error;
  411 
  412         if (ss->sio.scan_window_size != 0) {
  413                 /*
  414                  * only if not all data has been read, the scanner has to be
  415                  * stopped
  416                  */
  417                 bzero(&cmd, sizeof(cmd));
  418                 cmd.opcode = MUSTEK_START_STOP;
  419                 cmd.mode = MUSTEK_SCAN_STOP;
  420 
  421                 /* send the command to the scanner */
  422                 SC_DEBUG(sc_link, SDEV_DB1,
  423                     ("mustek_rewind_scanner: stop_scan\n"));
  424                 error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd,
  425                     sizeof(cmd), NULL, 0, MUSTEK_RETRIES, 5000, NULL, 0);
  426                 if (error)
  427                         return (error);
  428         }
  429 
  430         SC_DEBUG(sc_link, SDEV_DB1, ("mustek_rewind_scanner: end\n"));
  431 
  432         return (0);
  433 }
  434 
  435 /*
  436  * read the requested number of bytes/lines from the scanner
  437  */
  438 int
  439 mustek_read(ss, bp)
  440         struct ss_softc *ss;
  441         struct buf *bp;
  442 {
  443         struct mustek_read_cmd cmd;
  444         struct scsi_link *sc_link = ss->sc_link;
  445         u_long lines_to_read;
  446 
  447         SC_DEBUG(sc_link, SDEV_DB1, ("mustek_read: start\n"));
  448 
  449         bzero(&cmd, sizeof(cmd));
  450         cmd.opcode = MUSTEK_READ;
  451 
  452         /* instead of the bytes, the mustek wants the number of lines */
  453         lines_to_read = bp->b_bcount /
  454             ((ss->sio.scan_pixels_per_line * ss->sio.scan_bits_per_pixel) / 8);
  455         SC_DEBUG(sc_link, SDEV_DB1, ("mustek_read: read %ld lines\n",
  456             lines_to_read));
  457         _lto3b(lines_to_read, cmd.length);
  458 
  459         /*
  460          * go ask the adapter to do all this for us
  461          */
  462         if (scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd, sizeof(cmd),
  463             (u_char *) bp->b_data, bp->b_bcount, MUSTEK_RETRIES, 10000, bp,
  464             SCSI_NOSLEEP | SCSI_DATA_IN) != SUCCESSFULLY_QUEUED)
  465                 printf("%s: not queued\n", ss->sc_dev.dv_xname);
  466         else {
  467                 ss->sio.scan_lines -= lines_to_read;
  468                 ss->sio.scan_window_size -= bp->b_bcount;
  469         }
  470 
  471         return (0);
  472 }
  473 
  474 /*
  475  * check if the scanner is ready to take commands
  476  *   wait timeout seconds and try only every second
  477  *   if update, then update picture size info
  478  *
  479  *   returns EBUSY if scanner not ready
  480  */
  481 int
  482 mustek_get_status(ss, timeout, update)
  483         struct ss_softc *ss;
  484         int timeout, update;
  485 {
  486         struct mustek_get_status_cmd cmd;
  487         struct mustek_get_status_data data;
  488         struct scsi_link *sc_link = ss->sc_link;
  489         int error, lines, bytes_per_line;
  490 
  491         bzero(&cmd, sizeof(cmd));
  492         cmd.opcode = MUSTEK_GET_STATUS;
  493         cmd.length = sizeof(data);
  494 
  495         while (1) {
  496                 SC_DEBUG(sc_link, SDEV_DB1, ("mustek_get_status: stat_cmd\n"));
  497                 error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd,
  498                     sizeof(cmd), (u_char *) &data, sizeof(data), MUSTEK_RETRIES,
  499                     5000, NULL, SCSI_DATA_IN);
  500                 if (error)
  501                         return (error);
  502                 if ((data.ready_busy == MUSTEK_READY) ||
  503                     (timeout-- <= 0))
  504                         break;
  505                 /* please wait a second */
  506                 tsleep((caddr_t)mustek_get_status, PRIBIO + 1, "mtkrdy", hz);
  507         }
  508 
  509         if (update) {
  510                 bytes_per_line = _2ltol(data.bytes_per_line);
  511                 lines = _3ltol(data.lines);
  512                 if (lines != ss->sio.scan_lines) {
  513                         printf("mustek: lines actual(%d) != computed(%ld)\n",
  514                             lines, ss->sio.scan_lines);
  515                         return (EIO);
  516                 }
  517                 if (bytes_per_line * lines != ss->sio.scan_window_size) {
  518                         printf("mustek: win-size actual(%d) != computed(%ld)\n",
  519                             bytes_per_line * lines, ss->sio.scan_window_size);
  520                     return (EIO);
  521                 }
  522 
  523                 SC_DEBUG(sc_link, SDEV_DB1,
  524                     ("mustek_get_size: bpl=%ld, lines=%ld\n",
  525                     (ss->sio.scan_pixels_per_line * ss->sio.scan_bits_per_pixel) / 8,
  526                     ss->sio.scan_lines));
  527                 SC_DEBUG(sc_link, SDEV_DB1, ("window size = %ld\n",
  528                     ss->sio.scan_window_size));
  529         }
  530 
  531         SC_DEBUG(sc_link, SDEV_DB1, ("mustek_get_status: end\n"));
  532         if (data.ready_busy == MUSTEK_READY)
  533                 return (0);
  534         else
  535                 return (EBUSY);
  536 }
  537 
  538 /*
  539  * mustek_compute_sizes: compute window_size and lines for the picture
  540  *   this function is called from different places in the code
  541  */
  542 void
  543 mustek_compute_sizes(ss)
  544         struct ss_softc *ss;
  545 {
  546 
  547         switch (ss->sio.scan_image_mode) {
  548         case SIM_BINARY_MONOCHROME:
  549         case SIM_DITHERED_MONOCHROME:
  550                 ss->sio.scan_bits_per_pixel = 1;
  551                 break;
  552         case SIM_GRAYSCALE:
  553         case SIM_RED:
  554         case SIM_GREEN:
  555         case SIM_BLUE:
  556                 ss->sio.scan_bits_per_pixel = 8;
  557                 break;
  558         }
  559 
  560         /*
  561          * horizontal number of bytes is always a multiple of 2,
  562          * in 8-bit mode at least
  563          */
  564         ss->sio.scan_pixels_per_line =
  565             (ss->sio.scan_width * ss->sio.scan_x_resolution) / 1200;
  566         if (ss->sio.scan_bits_per_pixel == 1)
  567                 /* make it a multiple of 16, and thus of 2 bytes */
  568                 ss->sio.scan_pixels_per_line =
  569                     (ss->sio.scan_pixels_per_line + 15) & 0xfffffff0;
  570         else
  571                 ss->sio.scan_pixels_per_line =
  572                     (ss->sio.scan_pixels_per_line + 1) & 0xfffffffe;
  573 
  574         ss->sio.scan_lines =
  575             (ss->sio.scan_height * ss->sio.scan_y_resolution) / 1200;
  576         ss->sio.scan_window_size = ss->sio.scan_lines *
  577             ((ss->sio.scan_pixels_per_line * ss->sio.scan_bits_per_pixel) / 8);
  578 }

/* [<][>][^][v][top][bottom][index][help] */