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