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

Cache object: 7c36ceaa63eb3e2c773fbd02cd87fa38


[ 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.