ss.c revision 1.8
1/* $NetBSD: ss.c,v 1.8 1996/03/17 00:59:52 thorpej Exp $ */ 2 3/* 4 * Copyright (c) 1995 Kenneth Stailey. All rights reserved. 5 * modified for configurable scanner support by Joachim Koenig 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 Kenneth Stailey. 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#include <sys/types.h> 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/fcntl.h> 37#include <sys/errno.h> 38#include <sys/ioctl.h> 39#include <sys/malloc.h> 40#include <sys/buf.h> 41#include <sys/proc.h> 42#include <sys/user.h> 43#include <sys/device.h> 44#include <sys/conf.h> /* for cdevsw */ 45#include <sys/scanio.h> 46 47#include <scsi/scsi_all.h> 48#include <scsi/scsi_scanner.h> 49#include <scsi/scsiconf.h> 50#include <scsi/ssvar.h> 51 52#include <scsi/ss_mustek.h> 53 54#define SSMODE(z) ( minor(z) & 0x03) 55#define SSUNIT(z) ((minor(z) >> 4) ) 56 57/* 58 * If the mode is 3 (e.g. minor = 3,7,11,15) 59 * then the device has been openned to set defaults 60 * This mode does NOT ALLOW I/O, only ioctls 61 */ 62#define MODE_REWIND 0 63#define MODE_NONREWIND 1 64#define MODE_CONTROL 3 65 66int ssmatch __P((struct device *, void *, void *)); 67void ssattach __P((struct device *, struct device *, void *)); 68 69struct cfattach ss_ca = { 70 sizeof(struct ss_softc), ssmatch, ssattach 71}; 72 73struct cfdriver ss_cd = { 74 NULL, "ss", DV_DULL 75}; 76 77void ssstrategy __P((struct buf *)); 78void ssstart __P((void *)); 79 80struct scsi_device ss_switch = { 81 NULL, 82 ssstart, 83 NULL, 84 NULL, 85}; 86 87struct scsi_inquiry_pattern ss_patterns[] = { 88 {T_SCANNER, T_FIXED, 89 "", "", ""}, 90 {T_SCANNER, T_REMOV, 91 "", "", ""}, 92 {T_PROCESSOR, T_FIXED, 93 "HP ", "C1750A ", ""}, 94 {T_PROCESSOR, T_FIXED, 95 "HP ", "C2500A ", ""}, 96}; 97 98int 99ssmatch(parent, match, aux) 100 struct device *parent; 101 void *match, *aux; 102{ 103 struct scsibus_attach_args *sa = aux; 104 int priority; 105 106 (void)scsi_inqmatch(sa->sa_inqbuf, 107 (caddr_t)ss_patterns, sizeof(ss_patterns)/sizeof(ss_patterns[0]), 108 sizeof(ss_patterns[0]), &priority); 109 return (priority); 110} 111 112/* 113 * The routine called by the low level scsi routine when it discovers 114 * A device suitable for this driver 115 * If it is a know special, call special attach routine to install 116 * special handlers into the ss_softc structure 117 */ 118void 119ssattach(parent, self, aux) 120 struct device *parent, *self; 121 void *aux; 122{ 123 struct ss_softc *ss = (void *)self; 124 struct scsibus_attach_args *sa = aux; 125 struct scsi_link *sc_link = sa->sa_sc_link; 126 127 SC_DEBUG(sc_link, SDEV_DB2, ("ssattach: ")); 128 129 /* 130 * Store information needed to contact our base driver 131 */ 132 ss->sc_link = sc_link; 133 sc_link->device = &ss_switch; 134 sc_link->device_softc = ss; 135 sc_link->openings = 1; 136 137 /* 138 * look for non-standard scanners with help of the quirk table 139 * and install functions for special handling 140 */ 141 SC_DEBUG(sc_link, SDEV_DB2, ("ssattach:\n")); 142 if (!bcmp(sa->sa_inqbuf->vendor, "MUSTEK ", 8)) 143 mustek_attach(ss, sa); 144 if (!bcmp(sa->sa_inqbuf->vendor, "HP ", 8)) 145 scanjet_attach(ss, sa); 146 if (ss->special == NULL) { 147 /* XXX add code to restart a SCSI2 scanner, if any */ 148 } 149 150 /* 151 * Set up the buf queue for this device 152 */ 153 ss->buf_queue.b_active = 0; 154 ss->buf_queue.b_actf = 0; 155 ss->buf_queue.b_actb = &ss->buf_queue.b_actf; 156 157 printf("\n"); 158} 159 160/* 161 * open the device. 162 */ 163int 164ssopen(dev, flag, mode, p) 165 dev_t dev; 166 int flag; 167 int mode; 168 struct proc *p; 169{ 170 int unit; 171 u_int ssmode; 172 int error = 0; 173 struct ss_softc *ss; 174 struct scsi_link *sc_link; 175 176 unit = SSUNIT(dev); 177 if (unit >= ss_cd.cd_ndevs) 178 return (ENXIO); 179 ss = ss_cd.cd_devs[unit]; 180 if (!ss) 181 return (ENXIO); 182 183 ssmode = SSMODE(dev); 184 sc_link = ss->sc_link; 185 186 SC_DEBUG(sc_link, SDEV_DB1, ("open: dev=0x%x (unit %d (of %d))\n", dev, 187 unit, ss_cd.cd_ndevs)); 188 189 if (sc_link->flags & SDEV_OPEN) { 190 printf("%s: already open\n", ss->sc_dev.dv_xname); 191 return (EBUSY); 192 } 193 194 /* 195 * Catch any unit attention errors. 196 * 197 * SCSI_IGNORE_MEDIA_CHANGE: when you have an ADF, some scanners 198 * consider paper to be a changeable media 199 * 200 */ 201 error = scsi_test_unit_ready(sc_link, 202 SCSI_IGNORE_MEDIA_CHANGE | SCSI_IGNORE_ILLEGAL_REQUEST | 203 (ssmode == MODE_CONTROL ? SCSI_IGNORE_NOT_READY : 0)); 204 if (error) 205 goto bad; 206 207 sc_link->flags |= SDEV_OPEN; /* unit attn are now errors */ 208 209 /* 210 * If the mode is 3 (e.g. minor = 3,7,11,15) 211 * then the device has been opened to set defaults 212 * This mode does NOT ALLOW I/O, only ioctls 213 */ 214 if (ssmode == MODE_CONTROL) 215 return (0); 216 217 SC_DEBUG(sc_link, SDEV_DB2, ("open complete\n")); 218 return (0); 219 220bad: 221 sc_link->flags &= ~SDEV_OPEN; 222 return (error); 223} 224 225/* 226 * close the device.. only called if we are the LAST 227 * occurence of an open device 228 */ 229int 230ssclose(dev) 231 dev_t dev; 232{ 233 struct ss_softc *ss = ss_cd.cd_devs[SSUNIT(dev)]; 234 int error; 235 236 SC_DEBUG(ss->sc_link, SDEV_DB1, ("closing\n")); 237 238 if (SSMODE(dev) == MODE_REWIND) { 239 if (ss->special->rewind_scanner) { 240 /* call special handler to rewind/abort scan */ 241 error = (ss->special->rewind_scanner)(ss); 242 if (error) 243 return (error); 244 } else { 245 /* XXX add code to restart a SCSI2 scanner, if any */ 246 } 247 ss->sio.scan_window_size = 0; 248 ss->flags &= ~SSF_TRIGGERED; 249 } 250 ss->sc_link->flags &= ~SDEV_OPEN; 251 252 return (0); 253} 254 255/* 256 * trim the size of the transfer if needed, 257 * called by physio 258 * basically the smaller of our min and the scsi driver's 259 * minphys 260 */ 261void 262ssminphys(bp) 263 struct buf *bp; 264{ 265 register struct ss_softc *ss = ss_cd.cd_devs[SSUNIT(bp->b_dev)]; 266 267 (ss->sc_link->adapter->scsi_minphys)(bp); 268 269 /* 270 * trim the transfer further for special devices this is 271 * because some scanners only read multiples of a line at a 272 * time, also some cannot disconnect, so the read must be 273 * short enough to happen quickly 274 */ 275 if (ss->special->minphys) 276 (ss->special->minphys)(ss, bp); 277} 278 279/* 280 * Do a read on a device for a user process. 281 * Prime scanner at start of read, check uio values, call ssstrategy 282 * via physio for the actual transfer. 283 */ 284int 285ssread(dev, uio, flag) 286 dev_t dev; 287 struct uio *uio; 288 int flag; 289{ 290 struct ss_softc *ss = ss_cd.cd_devs[SSUNIT(dev)]; 291 int error; 292 293 /* if the scanner has not yet been started, do it now */ 294 if (!(ss->flags & SSF_TRIGGERED)) { 295 if (ss->special->trigger_scanner) { 296 error = (ss->special->trigger_scanner)(ss); 297 if (error) 298 return (error); 299 } 300 ss->flags |= SSF_TRIGGERED; 301 } 302 303 return (physio(ssstrategy, NULL, dev, B_READ, ssminphys, uio)); 304} 305 306/* 307 * Actually translate the requested transfer into one the physical 308 * driver can understand The transfer is described by a buf and will 309 * include only one physical transfer. 310 */ 311void 312ssstrategy(bp) 313 struct buf *bp; 314{ 315 struct ss_softc *ss = ss_cd.cd_devs[SSUNIT(bp->b_dev)]; 316 struct buf *dp; 317 int s; 318 319 SC_DEBUG(ss->sc_link, SDEV_DB1, 320 ("ssstrategy %d bytes @ blk %d\n", bp->b_bcount, bp->b_blkno)); 321 322 if (bp->b_bcount > ss->sio.scan_window_size) 323 bp->b_bcount = ss->sio.scan_window_size; 324 325 /* 326 * If it's a null transfer, return immediatly 327 */ 328 if (bp->b_bcount == 0) 329 goto done; 330 331 s = splbio(); 332 333 /* 334 * Place it in the queue of activities for this scanner 335 * at the end (a bit silly because we only have on user.. 336 * (but it could fork())) 337 */ 338 dp = &ss->buf_queue; 339 bp->b_actf = NULL; 340 bp->b_actb = dp->b_actb; 341 *dp->b_actb = bp; 342 dp->b_actb = &bp->b_actf; 343 344 /* 345 * Tell the device to get going on the transfer if it's 346 * not doing anything, otherwise just wait for completion 347 * (All a bit silly if we're only allowing 1 open but..) 348 */ 349 ssstart(ss); 350 351 splx(s); 352 return; 353bad: 354 bp->b_flags |= B_ERROR; 355done: 356 /* 357 * Correctly set the buf to indicate a completed xfer 358 */ 359 bp->b_resid = bp->b_bcount; 360 biodone(bp); 361} 362 363/* 364 * ssstart looks to see if there is a buf waiting for the device 365 * and that the device is not already busy. If both are true, 366 * It dequeues the buf and creates a scsi command to perform the 367 * transfer required. The transfer request will call scsi_done 368 * on completion, which will in turn call this routine again 369 * so that the next queued transfer is performed. 370 * The bufs are queued by the strategy routine (ssstrategy) 371 * 372 * This routine is also called after other non-queued requests 373 * have been made of the scsi driver, to ensure that the queue 374 * continues to be drained. 375 * ssstart() is called at splbio 376 */ 377void 378ssstart(v) 379 void *v; 380{ 381 struct ss_softc *ss = v; 382 struct scsi_link *sc_link = ss->sc_link; 383 register struct buf *bp, *dp; 384 385 SC_DEBUG(sc_link, SDEV_DB2, ("ssstart ")); 386 /* 387 * See if there is a buf to do and we are not already 388 * doing one 389 */ 390 while (sc_link->openings > 0) { 391 /* if a special awaits, let it proceed first */ 392 if (sc_link->flags & SDEV_WAITING) { 393 sc_link->flags &= ~SDEV_WAITING; 394 wakeup((caddr_t)sc_link); 395 return; 396 } 397 398 /* 399 * See if there is a buf with work for us to do.. 400 */ 401 dp = &ss->buf_queue; 402 if ((bp = dp->b_actf) == NULL) 403 return; 404 if ((dp = bp->b_actf) != NULL) 405 dp->b_actb = bp->b_actb; 406 else 407 ss->buf_queue.b_actb = bp->b_actb; 408 *bp->b_actb = dp; 409 410 if (ss->special->read) { 411 (ss->special->read)(ss, bp); 412 } else { 413 /* generic scsi2 scanner read */ 414 /* XXX add code for SCSI2 scanner read */ 415 } 416 } 417} 418 419/* 420 * Perform special action on behalf of the user; 421 * knows about the internals of this device 422 */ 423int 424ssioctl(dev, cmd, addr, flag, p) 425 dev_t dev; 426 u_long cmd; 427 caddr_t addr; 428 int flag; 429 struct proc *p; 430{ 431 struct ss_softc *ss = ss_cd.cd_devs[SSUNIT(dev)]; 432 int error = 0; 433 int unit; 434 struct scan_io *sio; 435 436 switch (cmd) { 437 case SCIOCGET: 438 if (ss->special->get_params) { 439 /* call special handler */ 440 error = (ss->special->get_params)(ss); 441 if (error) 442 return (error); 443 } else { 444 /* XXX add code for SCSI2 scanner, if any */ 445 return (EOPNOTSUPP); 446 } 447 bcopy(&ss->sio, addr, sizeof(struct scan_io)); 448 break; 449 case SCIOCSET: 450 sio = (struct scan_io *)addr; 451 452 if (ss->special->set_params) { 453 /* call special handler */ 454 error = (ss->special->set_params)(ss, sio); 455 if (error) 456 return (error); 457 } else { 458 /* XXX add code for SCSI2 scanner, if any */ 459 return (EOPNOTSUPP); 460 } 461 break; 462 case SCIOCRESTART: 463 if (ss->special->rewind_scanner ) { 464 /* call special handler */ 465 error = (ss->special->rewind_scanner)(ss); 466 if (error) 467 return (error); 468 } else 469 /* XXX add code for SCSI2 scanner, if any */ 470 return (EOPNOTSUPP); 471 ss->flags &= ~SSF_TRIGGERED; 472 break; 473#ifdef NOTYET 474 case SCAN_USE_ADF: 475 break; 476#endif 477 default: 478 if (SSMODE(dev) != MODE_CONTROL) 479 return (ENOTTY); 480 return (scsi_do_ioctl(ss->sc_link, dev, cmd, addr, flag, p)); 481 } 482 return (error); 483} 484