The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/gsc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* gsc.c - device driver for handy scanners
    2  *
    3  * Current version supports:
    4  *
    5  *      - Genius GS-4500
    6  *
    7  * Copyright (c) 1995 Gunther Schadow.  All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. All advertising materials mentioning features or use of this software
   18  *    must display the following acknowledgement:
   19  *      This product includes software developed by Gunther Schadow.
   20  * 4. The name of the author may not be used to endorse or promote products
   21  *    derived from this software without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   33  */
   34 
   35 #include "gsc.h"
   36 #if NGSC > 0
   37 
   38 #include "opt_devfs.h"
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/conf.h>
   43 #include <sys/buf.h>
   44 #include <sys/malloc.h>
   45 #include <sys/kernel.h>
   46 #ifdef DEVFS
   47 #include <sys/devfsext.h>
   48 #endif /*DEVFS*/
   49 #include <sys/uio.h>
   50 
   51 #include <machine/gsc.h>
   52 
   53 #include <i386/isa/isa.h>
   54 #include <i386/isa/isa_device.h>
   55 #include <i386/isa/gscreg.h>
   56 
   57 /***********************************************************************
   58  *
   59  * CONSTANTS & DEFINES
   60  *
   61  ***********************************************************************/
   62 
   63 #define PROBE_FAIL    0
   64 #define PROBE_SUCCESS IO_GSCSIZE
   65 #define ATTACH_FAIL   0
   66 #define ATTACH_SUCCESS 1
   67 #define SUCCESS       0
   68 #define FAIL         -1
   69 #define INVALID       FAIL
   70 
   71 #define DMA1_READY  0x08
   72 
   73 #ifdef GSCDEBUG
   74 #define lprintf(args)                                           \
   75                 do {                                            \
   76                         if (scu->flags & FLAG_DEBUG)            \
   77                                 printf args;                    \
   78                 } while (0)
   79 #else
   80 #define lprintf(args)
   81 #endif
   82 
   83 #define MIN(a, b)       (((a) < (b)) ? (a) : (b))
   84 
   85 #define TIMEOUT (hz*15)  /* timeout while reading a buffer - default value */
   86 #define LONG    (hz/60)  /* timesteps while reading a buffer */
   87 #define GSCPRI  PRIBIO   /* priority while reading a buffer */
   88 
   89 /***********************************************************************
   90  *
   91  * LAYOUT OF THE MINOR NUMBER
   92  *
   93  ***********************************************************************/
   94 
   95 #define UNIT_MASK 0xc0    /* unit gsc0 .. gsc3 */
   96 #define UNIT(x)   (x >> 6)
   97 #define DBUG_MASK 0x20
   98 #define FRMT_MASK 0x18    /* output format */
   99 #define FRMT_RAW  0x00    /* output bits as read from scanner */
  100 #define FRMT_GRAY 0x10    /* output graymap (not implemented yet) */
  101 #define FRMT_PBM  0x08    /* output pbm format */
  102 #define FRMT_PGM  0x18
  103 
  104 /***********************************************************************
  105  *
  106  * THE GEMOMETRY TABLE
  107  *
  108  ***********************************************************************/
  109 
  110 #define GEOMTAB_SIZE 7
  111 
  112 static const struct gsc_geom {
  113   int dpi;     /* dots per inch */
  114   int dpl;     /* dots per line */
  115   int g_res;   /* get resolution value (status flag) */
  116   int s_res;   /* set resolution value (control register) */
  117 } geomtab[GEOMTAB_SIZE] = {
  118   { 100,  424, GSC_RES_100, GSC_CNT_424},
  119   { 200,  840, GSC_RES_200, GSC_CNT_840},
  120   { 300, 1264, GSC_RES_300, GSC_CNT_1264},
  121   { 400, 1648, GSC_RES_400, GSC_CNT_1648},
  122   {  -1, 1696,          -1, GSC_CNT_1696},
  123   {  -2, 2644,          -2, GSC_CNT_2544},
  124   {  -3, 3648,          -3, GSC_CNT_3648},
  125 };
  126 
  127 #define NEW_GEOM { INVALID, INVALID, INVALID, INVALID }
  128 
  129 /***********************************************************************
  130  *
  131  * THE TABLE OF UNITS
  132  *
  133  ***********************************************************************/
  134 
  135 struct _sbuf {
  136   size_t  size;
  137   size_t  poi;
  138   char   *base;
  139 };
  140 
  141 struct gsc_unit {
  142   int channel;            /* DMA channel */
  143   int data;               /* - video port */
  144   int stat;               /* - status port */
  145   int ctrl;               /* - control port */
  146   int clrp;               /* - clear port */
  147   int flags;
  148 #define ATTACHED 0x01
  149 #define OPEN     0x02
  150 #define READING  0x04
  151 #define EOF      0x08
  152 #define FLAG_DEBUG  0x10
  153 #define PBM_MODE 0x20
  154   int     geometry;       /* resolution as geomtab index */
  155   int     blen;           /* length of buffer in lines */
  156   int     btime;          /* timeout of buffer in seconds/hz */
  157   struct  _sbuf sbuf;
  158   char    ctrl_byte;      /* the byte actually written to ctrl port */
  159   int     height;         /* height, for pnm modes */
  160   size_t  bcount;         /* bytes to read, for pnm modes */
  161   struct  _sbuf hbuf;     /* buffer for pnm header data */
  162 #ifdef DEVFS
  163   void *devfs_gsc;        /* storage for devfs tokens (handles) */
  164   void *devfs_gscp;
  165   void *devfs_gscd;
  166   void *devfs_gscpd;
  167 #endif
  168 };
  169 
  170 static struct gsc_unit unittab[NGSC];
  171 
  172 /* I could not find a reasonable buffer size limit other than by
  173  * experiments. MAXPHYS is obviously too much, while DEV_BSIZE and
  174  * PAGE_SIZE are really too small. There must be something wrong
  175  * with isa_dmastart/isa_dmarangecheck HELP!!!
  176  */
  177 #define MAX_BUFSIZE 0x3000
  178 #define DEFAULT_BLEN 59
  179 
  180 /***********************************************************************
  181  *
  182  * THE PER-DRIVER RECORD FOR ISA.C
  183  *
  184  ***********************************************************************/
  185 
  186 static  int gscprobe (struct isa_device *isdp);
  187 static  int gscattach(struct isa_device *isdp);
  188 
  189 struct isa_driver gscdriver = { gscprobe, gscattach, "gsc" };
  190 
  191 static  d_open_t        gscopen;
  192 static  d_close_t       gscclose;
  193 static  d_read_t        gscread;
  194 static  d_ioctl_t       gscioctl;
  195 
  196 #define CDEV_MAJOR 47
  197 static struct cdevsw gsc_cdevsw = 
  198         { gscopen,      gscclose,       gscread,        nowrite,        /*47*/
  199           gscioctl,     nostop,         nullreset,      nodevtotty,/* gsc */
  200           seltrue,      nommap,         NULL,   "gsc",  NULL,   -1 };
  201 
  202 
  203 /***********************************************************************
  204  *
  205  * LOCALLY USED SUBROUTINES
  206  *
  207  ***********************************************************************/
  208 
  209 /***********************************************************************
  210  *
  211  * lookup_geometry -- lookup a record in the geometry table by pattern
  212  *
  213  * The caller supplies a geometry record pattern, where INVALID
  214  * matches anything. Returns the index in the table or INVALID if
  215  * lookup fails.
  216  */
  217 
  218 static int
  219 lookup_geometry(struct gsc_geom geom, const struct gsc_unit *scu)
  220 {
  221   struct gsc_geom tab;
  222   int i;
  223 
  224   for(i=0; i<GEOMTAB_SIZE; i++)
  225     {
  226       tab = geomtab[i];
  227 
  228       if ( ( ( geom.dpi   != INVALID ) && ( tab.dpi   == geom.dpi   ) ) ||
  229            ( ( geom.dpl   != INVALID ) && ( tab.dpl   == geom.dpl   ) ) ||
  230            ( ( geom.g_res != INVALID ) && ( tab.g_res == geom.g_res ) ) ||
  231            ( ( geom.s_res != INVALID ) && ( tab.s_res == geom.s_res ) ) )
  232         {
  233           lprintf(("gsc.lookup_geometry: "
  234                  "geometry lookup found: %ddpi, %ddpl\n",
  235                  tab.dpi, tab.dpl));
  236           return i;
  237         }
  238     }
  239 
  240   lprintf(("gsc.lookup_geometry: "
  241          "geometry lookup failed on {%d, %d, 0x%02x, 0x%02x}\n",
  242          geom.dpi, geom.dpl, geom.g_res, geom.s_res));
  243 
  244   return INVALID;
  245 }
  246 
  247 /***********************************************************************
  248  *
  249  * get_geometry -- read geometry from status port
  250  *
  251  * Returns the index into geometry table or INVALID if it fails to
  252  * either read the status byte or lookup the record.
  253  */
  254 
  255 static int
  256 get_geometry(const struct gsc_unit *scu)
  257 {
  258   struct gsc_geom geom = NEW_GEOM;
  259 
  260   lprintf(("gsc.get_geometry: get geometry at 0x%03x\n", scu->stat));
  261 
  262   if ( ( geom.g_res = inb(scu->stat) ) == FAIL )
  263     return INVALID;
  264 
  265   geom.g_res &= GSC_RES_MASK;
  266 
  267   return lookup_geometry(geom, scu);
  268 }
  269 
  270 /***********************************************************************
  271  *
  272  * buffer_allocate -- allocate/reallocate a buffer
  273  * Now just checks that the preallocated buffer is large enough.
  274  */
  275 
  276 static int
  277 buffer_allocate(struct gsc_unit *scu)
  278 {
  279   size_t size;
  280 
  281   size = scu->blen * geomtab[scu->geometry].dpl / 8;
  282 
  283   lprintf(("gsc.buffer_allocate: need 0x%x bytes\n", size));
  284 
  285   if ( size > MAX_BUFSIZE )
  286     {
  287       lprintf(("gsc.buffer_allocate: 0x%x bytes are too much\n", size));
  288       return ENOMEM;
  289     }
  290 
  291   scu->sbuf.size = size;
  292   scu->sbuf.poi  = size;
  293 
  294   lprintf(("gsc.buffer_allocate: ok\n"));
  295 
  296   return SUCCESS;
  297 }
  298 
  299 /***********************************************************************
  300  *
  301  * buffer_read -- scan a buffer
  302  */
  303 
  304 static int
  305 buffer_read(struct gsc_unit *scu)
  306 {
  307   int stb;
  308   int res = SUCCESS;
  309   int chan_bit;
  310   char *p;
  311   int sps;
  312   int delay;
  313 
  314   lprintf(("gsc.buffer_read: begin\n"));
  315 
  316   if (scu->ctrl_byte == INVALID)
  317     {
  318       lprintf(("gsc.buffer_read: invalid ctrl_byte\n"));
  319       return EIO;
  320     }
  321 
  322   sps=splbio();
  323 
  324   outb( scu->ctrl, scu->ctrl_byte | GSC_POWER_ON );
  325   outb( scu->clrp, 0 );
  326   stb = inb( scu->stat );
  327 
  328   isa_dmastart(B_READ, scu->sbuf.base, scu->sbuf.size, scu->channel);
  329 
  330   chan_bit = 0x01 << scu->channel;
  331 
  332   for(delay=0; !(inb(DMA1_READY) & 0x01 << scu->channel); delay += LONG)
  333     {
  334       if(delay >= scu->btime)
  335         {
  336           splx(sps);
  337           lprintf(("gsc.buffer_read: timeout\n"));
  338           res = EWOULDBLOCK;
  339           break;
  340         }
  341       res = tsleep((caddr_t)scu, GSCPRI | PCATCH, "gscread", LONG);
  342       if ( ( res == 0 ) || ( res == EWOULDBLOCK ) )
  343         res = SUCCESS;
  344       else
  345         break;
  346     }
  347   splx(sps);
  348   isa_dmadone(B_READ, scu->sbuf.base, scu->sbuf.size, scu->channel);
  349   outb( scu->clrp, 0 );
  350 
  351   if(res != SUCCESS)
  352     {
  353       lprintf(("gsc.buffer_read: aborted with %d\n", res));
  354       return res;
  355     }
  356 
  357   lprintf(("gsc.buffer_read: invert buffer\n"));
  358   for(p = scu->sbuf.base + scu->sbuf.size - 1; p >= scu->sbuf.base; p--)
  359     *p = ~*p;
  360 
  361   scu->sbuf.poi = 0;
  362   lprintf(("gsc.buffer_read: ok\n"));
  363   return SUCCESS;
  364 }
  365 
  366 /***********************************************************************
  367  *
  368  * the main functions
  369  *
  370  ***********************************************************************/
  371 
  372 /***********************************************************************
  373  *
  374  * gscprobe
  375  *
  376  * read status port and check for proper configuration:
  377  *  - if address group matches (status byte has reasonable value)
  378  *  - if DMA channel matches   (status byte has correct value)
  379  */
  380 
  381 static int
  382 gscprobe (struct isa_device *isdp)
  383 {
  384   int unit = isdp->id_unit;
  385   struct gsc_unit *scu = unittab + unit;
  386   int stb;
  387   struct gsc_geom geom = NEW_GEOM;
  388 
  389   scu->flags = FLAG_DEBUG;
  390 
  391   lprintf(("gsc%d.probe "
  392          "on iobase 0x%03x, irq %d, drq %d, addr %p, size %d\n",
  393          unit,
  394          isdp->id_iobase,
  395          isdp->id_irq,
  396          isdp->id_drq,
  397          isdp->id_maddr,
  398          isdp->id_msize));
  399 
  400   if ( isdp->id_iobase < 0 )
  401     {
  402       lprintf(("gsc%d.probe: no iobase given\n", unit));
  403       return PROBE_FAIL;
  404     }
  405 
  406   stb = inb( GSC_STAT(isdp->id_iobase) );
  407   if (stb == FAIL)
  408     {
  409       lprintf(("gsc%d.probe: get status byte failed\n", unit));
  410       return PROBE_FAIL;
  411     }
  412 
  413   scu->data = GSC_DATA(isdp->id_iobase);
  414   scu->stat = GSC_STAT(isdp->id_iobase);
  415   scu->ctrl = GSC_CTRL(isdp->id_iobase);
  416   scu->clrp = GSC_CLRP(isdp->id_iobase);
  417 
  418   outb(scu->clrp,stb);
  419   stb = inb(scu->stat);
  420 
  421   switch(stb & GSC_CNF_MASK) {
  422   case GSC_CNF_DMA1:
  423     lprintf(("gsc%d.probe: DMA 1\n", unit));
  424     scu->channel = 1;
  425     break;
  426 
  427   case GSC_CNF_DMA3:
  428     lprintf(("gsc%d.probe: DMA 3\n", unit));
  429     scu->channel = 3;
  430     break;
  431 
  432   case GSC_CNF_IRQ3:
  433     lprintf(("gsc%d.probe: IRQ 3\n", unit));
  434     goto probe_noirq;
  435   case GSC_CNF_IRQ5:
  436     lprintf(("gsc%d.probe: IRQ 5\n", unit));
  437   probe_noirq:
  438     lprintf(("gsc%d.probe: sorry, can't use IRQ yet\n", unit));
  439     return PROBE_FAIL;
  440   default:
  441     lprintf(("gsc%d.probe: invalid status byte 0x%02x\n", unit, (u_char) stb));
  442     return PROBE_FAIL;
  443   }
  444 
  445   if (isdp->id_drq < 0)
  446     isdp->id_drq = scu->channel;
  447   if (scu->channel != isdp->id_drq)
  448     {
  449       lprintf(("gsc%d.probe: drq mismatch: config: %d; hardware: %d\n",
  450               unit, isdp->id_drq, scu->channel));
  451       return PROBE_FAIL;
  452     }
  453 
  454   geom.g_res = stb & GSC_RES_MASK;
  455   scu->geometry = lookup_geometry(geom, scu);
  456   if (scu->geometry == INVALID)
  457     {
  458       lprintf(("gsc%d.probe: geometry lookup failed\n", unit));
  459       return PROBE_FAIL;
  460     }
  461   else
  462     {
  463       scu->ctrl_byte = geomtab[scu->geometry].s_res;
  464       outb(scu->ctrl, scu->ctrl_byte | GSC_POWER_ON);
  465 
  466       lprintf(("gsc%d.probe: status 0x%02x, %ddpi\n",
  467              unit, stb, geomtab[scu->geometry].dpi));
  468 
  469       outb(scu->ctrl, scu->ctrl_byte & ~GSC_POWER_ON);
  470     }
  471 
  472   lprintf(("gsc%d.probe: ok\n", unit));
  473 
  474   scu->flags &= ~FLAG_DEBUG;
  475 
  476   return PROBE_SUCCESS;
  477 }
  478 
  479 /***********************************************************************
  480  *
  481  * gscattach
  482  *
  483  * finish initialization of unit structure
  484  * get geometry value
  485  */
  486 
  487 static int
  488 gscattach(struct isa_device *isdp)
  489 {
  490   int unit = isdp->id_unit;
  491   struct gsc_unit *scu = unittab + unit;
  492 
  493   scu->flags |= FLAG_DEBUG;
  494 
  495   lprintf(("gsc%d.attach: "
  496          "iobase 0x%03x, irq %d, drq %d, addr %p, size %d\n",
  497          unit,
  498          isdp->id_iobase,
  499          isdp->id_irq,
  500          isdp->id_drq,
  501          isdp->id_maddr,
  502          isdp->id_msize));
  503 
  504   printf("gsc%d: GeniScan GS-4500 at %ddpi\n",
  505          unit, geomtab[scu->geometry].dpi);
  506 
  507   /*
  508    * Initialize buffer structure.
  509    * XXX this must be done early to give a good chance of getting a
  510    * contiguous buffer.  This wastes memory.
  511    */
  512   scu->sbuf.base = contigmalloc((unsigned long)MAX_BUFSIZE, M_DEVBUF, M_NOWAIT,
  513                                 0ul, 0xfffffful, 1ul, 0x10000ul);
  514   if ( scu->sbuf.base == NULL )
  515     {
  516       lprintf(("gsc%d.attach: buffer allocation failed\n", unit));
  517       return ATTACH_FAIL;       /* XXX attach must not fail */
  518     }
  519   scu->sbuf.size = INVALID;
  520   scu->sbuf.poi  = INVALID;
  521 
  522   scu->blen = DEFAULT_BLEN;
  523   scu->btime = TIMEOUT;
  524 
  525   scu->flags |= ATTACHED;
  526   lprintf(("gsc%d.attach: ok\n", unit));
  527   scu->flags &= ~FLAG_DEBUG;
  528 #ifdef DEVFS
  529 #define GSC_UID 0
  530 #define GSC_GID 13
  531     scu->devfs_gsc = 
  532                 devfs_add_devswf(&gsc_cdevsw, unit<<6, DV_CHR, GSC_UID, GSC_GID,
  533                                  0666, "gsc%d", unit);
  534     scu->devfs_gscp = 
  535                 devfs_add_devswf(&gsc_cdevsw, ((unit<<6) + FRMT_PBM), DV_CHR, 
  536                                  GSC_UID,  GSC_GID, 0666, "gsc%dp", unit);
  537     scu->devfs_gscd = 
  538                 devfs_add_devswf(&gsc_cdevsw, ((unit<<6) + DBUG_MASK), DV_CHR, 
  539                                  GSC_UID,  GSC_GID, 0666, "gsc%dd", unit);
  540     scu->devfs_gscpd = 
  541                 devfs_add_devswf(&gsc_cdevsw, ((unit<<6) + DBUG_MASK+FRMT_PBM),
  542                                  DV_CHR, GSC_UID,  GSC_GID, 0666, "gsc%dpd", 
  543                                  unit);
  544 #endif /*DEVFS*/
  545 
  546   return ATTACH_SUCCESS;
  547 }
  548 
  549 /***********************************************************************
  550  *
  551  * gscopen
  552  *
  553  * set open flag
  554  * set modes according to minor number
  555  * don't switch scanner on, wait until first read ioctls go before
  556  */
  557 
  558 static  int
  559 gscopen  (dev_t dev, int flags, int fmt, struct proc *p)
  560 {
  561   struct gsc_unit *scu;
  562   int unit;
  563 
  564   unit = UNIT(minor(dev)) & UNIT_MASK;
  565   if ( unit >= NGSC )
  566     {
  567 #ifdef GSCDEBUG
  568       /* XXX lprintf isn't valid here since there is no scu. */
  569       printf("gsc%d.open: unconfigured unit number (max %d)\n", unit, NGSC);
  570 #endif
  571       return ENXIO;
  572     }
  573   scu = unittab + unit;
  574   if ( !( scu->flags & ATTACHED ) )
  575     {
  576       lprintf(("gsc%d.open: unit was not attached successfully 0x%04x\n",
  577              unit, scu->flags));
  578       return ENXIO;
  579     }
  580 
  581   if ( minor(dev) & DBUG_MASK )
  582     scu->flags |= FLAG_DEBUG;
  583   else
  584     scu->flags &= ~FLAG_DEBUG;
  585 
  586   switch(minor(dev) & FRMT_MASK) {
  587   case FRMT_PBM:
  588     scu->flags |= PBM_MODE;
  589     lprintf(("gsc%d.open: pbm mode\n", unit));
  590     break;
  591   case FRMT_RAW:
  592     lprintf(("gsc%d.open: raw mode\n", unit));
  593     scu->flags &= ~PBM_MODE;
  594     break;
  595   default:
  596     lprintf(("gsc%d.open: gray maps are not yet supported", unit));
  597     return ENXIO;
  598   }
  599 
  600   lprintf(("gsc%d.open: minor %d\n",
  601          unit, minor(dev)));
  602 
  603   if ( scu->flags & OPEN )
  604     {
  605       lprintf(("gsc%d.open: already open", unit));
  606       return EBUSY;
  607     }
  608 
  609   if (isa_dma_acquire(scu->channel))
  610       return(EBUSY);
  611 
  612   scu->flags |= OPEN;
  613 
  614   return SUCCESS;
  615 }
  616 
  617 /***********************************************************************
  618  *
  619  * gscclose
  620  *
  621  * turn off scanner
  622  * release the buffer
  623  */
  624 
  625 static  int
  626 gscclose (dev_t dev, int flags, int fmt, struct proc *p)
  627 {
  628   int unit = UNIT(minor(dev));
  629   struct gsc_unit *scu = unittab + unit;
  630 
  631   lprintf(("gsc%d.close: minor %d\n",
  632          unit, minor(dev)));
  633 
  634   if ( unit >= NGSC || !( scu->flags & ATTACHED ) )
  635     {
  636       lprintf(("gsc%d.read: unit was not attached successfully 0x%04x\n",
  637              unit, scu->flags));
  638       return ENXIO;
  639     }
  640 
  641   outb(scu->ctrl, scu->ctrl_byte & ~GSC_POWER_ON);
  642 
  643   scu->sbuf.size = INVALID;
  644   scu->sbuf.poi  = INVALID;
  645 
  646   isa_dma_release(scu->channel);
  647 
  648   scu->flags &= ~(FLAG_DEBUG | OPEN | READING);
  649 
  650   return SUCCESS;
  651 }
  652 
  653 /***********************************************************************
  654  *
  655  * gscread
  656  */
  657 
  658 static  int
  659 gscread  (dev_t dev, struct uio *uio, int ioflag)
  660 {
  661   int unit = UNIT(minor(dev));
  662   struct gsc_unit *scu = unittab + unit;
  663   size_t nbytes;
  664   int res;
  665 
  666   lprintf(("gsc%d.read: minor %d\n", unit, minor(dev)));
  667 
  668   if ( unit >= NGSC || !( scu->flags & ATTACHED ) )
  669     {
  670       lprintf(("gsc%d.read: unit was not attached successfully 0x%04x\n",
  671              unit, scu->flags));
  672       return ENXIO;
  673     }
  674 
  675   if ( !(scu->flags & READING) )
  676     {
  677       res = buffer_allocate(scu);
  678       if ( res == SUCCESS )
  679         scu->flags |= READING;
  680       else
  681         return res;
  682 
  683       scu->ctrl_byte = geomtab[scu->geometry].s_res;
  684 
  685       /* initialize for pbm mode */
  686       if ( scu->flags & PBM_MODE )
  687         {
  688           char *p;
  689           int width = geomtab[scu->geometry].dpl;
  690 
  691           sprintf(scu->sbuf.base,"P4 %d %d\n", width, scu->height);
  692           scu->bcount = scu->height * width / 8;
  693 
  694           lprintf(("gsc%d.read: initializing pbm mode: `%s', bcount: 0x%x\n",
  695                   unit, scu->sbuf.base, scu->bcount));
  696 
  697           /* move header to end of sbuf */
  698           for(p=scu->sbuf.base; *p; p++);
  699           while(--p >= scu->sbuf.base)
  700             {
  701               *(char *)(scu->sbuf.base + --scu->sbuf.poi) = *p;
  702               scu->bcount++;
  703             }
  704         }
  705     }
  706 
  707   lprintf(("gsc%d.read(before buffer_read): "
  708           "size 0x%x, pointer 0x%x, bcount 0x%x, ok\n",
  709           unit, scu->sbuf.size, scu->sbuf.poi, scu->bcount));
  710 
  711   if ( scu->sbuf.poi == scu->sbuf.size )
  712     if ( (res = buffer_read(scu)) != SUCCESS )
  713       return res;
  714 
  715   lprintf(("gsc%d.read(after buffer_read): "
  716           "size 0x%x, pointer 0x%x, bcount 0x%x, ok\n",
  717           unit, scu->sbuf.size, scu->sbuf.poi, scu->bcount));
  718 
  719   nbytes = MIN( uio->uio_resid, scu->sbuf.size - scu->sbuf.poi );
  720 
  721   if ( (scu->flags & PBM_MODE) )
  722     nbytes = MIN( nbytes, scu->bcount );
  723 
  724   lprintf(("gsc%d.read: transferring 0x%x bytes", unit, nbytes));
  725 
  726   res = uiomove(scu->sbuf.base + scu->sbuf.poi, nbytes, uio);
  727   if ( res != SUCCESS )
  728     {
  729       lprintf(("gsc%d.read: uiomove failed %d", unit, res));
  730       return res;
  731     }
  732 
  733   scu->sbuf.poi += nbytes;
  734   if ( scu->flags & PBM_MODE ) scu->bcount -= nbytes;
  735 
  736   lprintf(("gsc%d.read: size 0x%x, pointer 0x%x, bcount 0x%x, ok\n",
  737           unit, scu->sbuf.size, scu->sbuf.poi, scu->bcount));
  738 
  739   return SUCCESS;
  740 }
  741 
  742 /***********************************************************************
  743  *
  744  * gscioctl
  745  *
  746  */
  747 
  748 static  int
  749 gscioctl (dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
  750 {
  751   int unit = UNIT(minor(dev));
  752   struct gsc_unit *scu = unittab + unit;
  753 
  754   lprintf(("gsc%d.ioctl: minor %d\n",
  755          unit, minor(dev)));
  756 
  757   if ( unit >= NGSC || !( scu->flags & ATTACHED ) )
  758     {
  759       lprintf(("gsc%d.ioctl: unit was not attached successfully 0x%04x\n",
  760              unit, scu->flags));
  761       return ENXIO;
  762     }
  763 
  764   switch(cmd) {
  765   case GSC_SRESSW:
  766     lprintf(("gsc%d.ioctl:GSC_SRESSW\n", unit));
  767     if ( scu->flags & READING )
  768       {
  769         lprintf(("gsc%d:ioctl on already reading unit\n", unit));
  770         return EBUSY;
  771       }
  772     scu->geometry = get_geometry(scu);
  773     return SUCCESS;
  774   case GSC_GRES:
  775     *(int *)data=geomtab[scu->geometry].dpi;
  776     lprintf(("gsc%d.ioctl:GSC_GRES %ddpi\n", unit, *(int *)data));
  777     return SUCCESS;
  778   case GSC_GWIDTH:
  779     *(int *)data=geomtab[scu->geometry].dpl;
  780     lprintf(("gsc%d.ioctl:GSC_GWIDTH %d\n", unit, *(int *)data));
  781     return SUCCESS;
  782   case GSC_SRES:
  783   case GSC_SWIDTH:
  784     lprintf(("gsc%d.ioctl:GSC_SRES or GSC_SWIDTH %d\n",
  785            unit, *(int *)data));
  786     { int g;
  787       struct gsc_geom geom = NEW_GEOM;
  788       if ( cmd == GSC_SRES )
  789         geom.dpi = *(int *)data;
  790       else
  791         geom.dpl = *(int *)data;
  792       if ( ( g = lookup_geometry(geom, scu) ) == INVALID )
  793         return EINVAL;
  794       scu->geometry = g;
  795       return SUCCESS;
  796     }
  797   case GSC_GHEIGHT:
  798     *(int *)data=scu->height;
  799     lprintf(("gsc%d.ioctl:GSC_GHEIGHT %d\n", unit, *(int *)data));
  800     return SUCCESS;
  801   case GSC_SHEIGHT:
  802     lprintf(("gsc%d.ioctl:GSC_SHEIGHT %d\n", unit, *(int *)data));
  803     if ( scu->flags & READING )
  804       {
  805         lprintf(("gsc%d:ioctl on already reading unit\n", unit));
  806         return EBUSY;
  807       }
  808     scu->height=*(int *)data;
  809     return SUCCESS;
  810   case GSC_GBLEN:
  811     *(int *)data=scu->blen;
  812     lprintf(("gsc%d.ioctl:GSC_GBLEN %d\n", unit, *(int *)data));
  813     return SUCCESS;
  814   case GSC_SBLEN:
  815     lprintf(("gsc%d.ioctl:GSC_SBLEN %d\n", unit, *(int *)data));
  816     if (*(int *)data * geomtab[scu->geometry].dpl / 8 > MAX_BUFSIZE)
  817       {
  818         lprintf(("gsc%d:ioctl buffer size too high\n", unit));
  819         return ENOMEM;
  820       }
  821     scu->blen=*(int *)data;
  822     return SUCCESS;
  823   case GSC_GBTIME:
  824     *(int *)data = scu->btime / hz;
  825     lprintf(("gsc%d.ioctl:GSC_GBTIME %d\n", unit, *(int *)data));
  826     return SUCCESS;
  827   case GSC_SBTIME:
  828     scu->btime = *(int *)data * hz;
  829     lprintf(("gsc%d.ioctl:GSC_SBTIME %d\n", unit, *(int *)data));
  830     return SUCCESS;
  831   default: return ENOTTY;
  832   }
  833 }
  834 
  835 
  836 static gsc_devsw_installed = 0;
  837 
  838 static void
  839 gsc_drvinit(void *unused)
  840 {
  841         dev_t dev;
  842 
  843         if( ! gsc_devsw_installed ) {
  844                 dev = makedev(CDEV_MAJOR, 0);
  845                 cdevsw_add(&dev,&gsc_cdevsw, NULL);
  846                 gsc_devsw_installed = 1;
  847         }
  848 }
  849 
  850 SYSINIT(gscdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,gsc_drvinit,NULL)
  851 
  852 
  853 #endif /* NGSC > 0 */

Cache object: 1fd60f888f7fec7301009a51733cf6b4


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.