ss.c revision 1.36
1/*	$NetBSD: ss.c,v 1.36 2001/07/18 18:25:41 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/vnode.h>
46#include <sys/scanio.h>
47
48#include <dev/scsipi/scsi_all.h>
49#include <dev/scsipi/scsipi_all.h>
50#include <dev/scsipi/scsi_scanner.h>
51#include <dev/scsipi/scsiconf.h>
52#include <dev/scsipi/ssvar.h>
53
54#include <dev/scsipi/ss_mustek.h>
55
56#define SSMODE(z)	( minor(z)       & 0x03)
57#define SSUNIT(z)	((minor(z) >> 4)       )
58#define SSNMINOR 16
59
60/*
61 * If the mode is 3 (e.g. minor = 3,7,11,15)
62 * then the device has been openned to set defaults
63 * This mode does NOT ALLOW I/O, only ioctls
64 */
65#define MODE_REWIND	0
66#define MODE_NONREWIND	1
67#define MODE_CONTROL	3
68
69int ssmatch(struct device *, struct cfdata *, void *);
70void ssattach(struct device *, struct device *, void *);
71int ssdetach(struct device *self, int flags);
72int ssactivate(struct device *self, enum devact act);
73
74struct cfattach ss_ca = {
75	sizeof(struct ss_softc), ssmatch, ssattach, ssdetach, ssactivate
76};
77
78extern struct cfdriver ss_cd;
79
80void    ssstrategy __P((struct buf *));
81void    ssstart __P((struct scsipi_periph *));
82void	ssminphys __P((struct buf *));
83
84const struct scsipi_periphsw ss_switch = {
85	NULL,
86	ssstart,
87	NULL,
88	NULL,
89};
90
91struct scsipi_inquiry_pattern ss_patterns[] = {
92	{T_SCANNER, T_FIXED,
93	 "",         "",                 ""},
94	{T_SCANNER, T_REMOV,
95	 "",         "",                 ""},
96	{T_PROCESSOR, T_FIXED,
97	 "HP      ", "C1750A          ", ""},
98	{T_PROCESSOR, T_FIXED,
99	 "HP      ", "C2500A          ", ""},
100	{T_PROCESSOR, T_FIXED,
101	 "HP      ", "C1130A          ", ""},
102	{T_PROCESSOR, T_FIXED,
103	 "HP      ", "C5110A          ", ""},
104	{T_PROCESSOR, T_FIXED,
105	 "HP      ", "C7670A          ", ""},
106};
107
108int
109ssmatch(struct device *parent, struct cfdata *match, void *aux)
110{
111	struct scsipibus_attach_args *sa = aux;
112	int priority;
113
114	(void)scsipi_inqmatch(&sa->sa_inqbuf,
115	    (caddr_t)ss_patterns, sizeof(ss_patterns) / sizeof(ss_patterns[0]),
116	    sizeof(ss_patterns[0]), &priority);
117	return (priority);
118}
119
120/*
121 * The routine called by the low level scsi routine when it discovers
122 * A device suitable for this driver
123 * If it is a know special, call special attach routine to install
124 * special handlers into the ss_softc structure
125 */
126void
127ssattach(struct device *parent, struct device *self, void *aux)
128{
129	struct ss_softc *ss = (void *)self;
130	struct scsipibus_attach_args *sa = aux;
131	struct scsipi_periph *periph = sa->sa_periph;
132
133	SC_DEBUG(periph, SCSIPI_DB2, ("ssattach: "));
134
135	ss->flags |= SSF_AUTOCONF;
136
137	/*
138	 * Store information needed to contact our base driver
139	 */
140	ss->sc_periph = periph;
141	periph->periph_dev = &ss->sc_dev;
142	periph->periph_switch = &ss_switch;
143
144	printf("\n");
145
146	/*
147	 * look for non-standard scanners with help of the quirk table
148	 * and install functions for special handling
149	 */
150	SC_DEBUG(periph, SCSIPI_DB2, ("ssattach:\n"));
151	if (memcmp(sa->sa_inqbuf.vendor, "MUSTEK", 6) == 0)
152		mustek_attach(ss, sa);
153	if (memcmp(sa->sa_inqbuf.vendor, "HP      ", 8) == 0 &&
154	    memcmp(sa->sa_inqbuf.product, "ScanJet 5300C", 13) != 0)
155		scanjet_attach(ss, sa);
156	if (ss->special == NULL) {
157		/* XXX add code to restart a SCSI2 scanner, if any */
158	}
159
160	/*
161	 * Set up the buf queue for this device
162	 */
163	BUFQ_INIT(&ss->buf_queue);
164	ss->flags &= ~SSF_AUTOCONF;
165}
166
167int
168ssdetach(struct device *self, int flags)
169{
170	struct ss_softc *ss = (struct ss_softc *) self;
171	struct buf *bp;
172	int s, cmaj, mn;
173
174	/* locate the major number */
175	for (cmaj = 0; cmaj <= nchrdev; cmaj++)
176		if (cdevsw[cmaj].d_open == ssopen)
177			break;
178
179	s = splbio();
180
181	/* Kill off any queued buffers. */
182	while ((bp = BUFQ_FIRST(&ss->buf_queue)) != NULL) {
183		BUFQ_REMOVE(&ss->buf_queue, bp);
184		bp->b_error = EIO;
185		bp->b_flags |= B_ERROR;
186		bp->b_resid = bp->b_bcount;
187		biodone(bp);
188	}
189
190	/* Kill off any pending commands. */
191	scsipi_kill_pending(ss->sc_periph);
192
193	splx(s);
194
195	/* Nuke the vnodes for any open instances */
196	mn = SSUNIT(self->dv_unit);
197	vdevgone(cmaj, mn, mn+SSNMINOR-1, VCHR);
198
199	return (0);
200}
201
202int
203ssactivate(struct device *self, enum devact act)
204{
205	int rv = 0;
206
207	switch (act) {
208	case DVACT_ACTIVATE:
209		rv = EOPNOTSUPP;
210		break;
211
212	case DVACT_DEACTIVATE:
213		/*
214		 * Nothing to do; we key off the device's DVF_ACTIVE.
215		 */
216		break;
217	}
218	return (rv);
219}
220
221/*
222 * open the device.
223 */
224int
225ssopen(dev_t dev, int flag, int mode, struct proc *p)
226{
227	int unit;
228	u_int ssmode;
229	int error;
230	struct ss_softc *ss;
231	struct scsipi_periph *periph;
232	struct scsipi_adapter *adapt;
233
234	unit = SSUNIT(dev);
235	if (unit >= ss_cd.cd_ndevs)
236		return (ENXIO);
237	ss = ss_cd.cd_devs[unit];
238	if (!ss)
239		return (ENXIO);
240
241	if ((ss->sc_dev.dv_flags & DVF_ACTIVE) == 0)
242		return (ENODEV);
243
244	ssmode = SSMODE(dev);
245
246	periph = ss->sc_periph;
247	adapt = periph->periph_channel->chan_adapter;
248
249	SC_DEBUG(periph, SCSIPI_DB1, ("open: dev=0x%x (unit %d (of %d))\n", dev,
250	    unit, ss_cd.cd_ndevs));
251
252	if (periph->periph_flags & PERIPH_OPEN) {
253		printf("%s: already open\n", ss->sc_dev.dv_xname);
254		return (EBUSY);
255	}
256
257	if ((error = scsipi_adapter_addref(adapt)) != 0)
258		return (error);
259
260	/*
261	 * Catch any unit attention errors.
262	 *
263	 * XS_CTL_IGNORE_MEDIA_CHANGE: when you have an ADF, some scanners
264	 * consider paper to be a changeable media
265	 *
266	 */
267	error = scsipi_test_unit_ready(periph,
268	    XS_CTL_IGNORE_MEDIA_CHANGE | XS_CTL_IGNORE_ILLEGAL_REQUEST |
269	    (ssmode == MODE_CONTROL ? XS_CTL_IGNORE_NOT_READY : 0));
270	if (error)
271		goto bad;
272
273	periph->periph_flags |= PERIPH_OPEN;	/* unit attn now errors */
274
275	/*
276	 * If the mode is 3 (e.g. minor = 3,7,11,15)
277	 * then the device has been opened to set defaults
278	 * This mode does NOT ALLOW I/O, only ioctls
279	 */
280	if (ssmode == MODE_CONTROL)
281		return (0);
282
283	SC_DEBUG(periph, SCSIPI_DB2, ("open complete\n"));
284	return (0);
285
286bad:
287	scsipi_adapter_delref(adapt);
288	periph->periph_flags &= ~PERIPH_OPEN;
289	return (error);
290}
291
292/*
293 * close the device.. only called if we are the LAST
294 * occurence of an open device
295 */
296int
297ssclose(dev_t dev, int flag, int mode, struct proc *p)
298{
299	struct ss_softc *ss = ss_cd.cd_devs[SSUNIT(dev)];
300	struct scsipi_periph *periph = ss->sc_periph;
301	struct scsipi_adapter *adapt = periph->periph_channel->chan_adapter;
302	int error;
303
304	SC_DEBUG(ss->sc_periph, SCSIPI_DB1, ("closing\n"));
305
306	if (SSMODE(dev) == MODE_REWIND) {
307		if (ss->special && ss->special->rewind_scanner) {
308			/* call special handler to rewind/abort scan */
309			error = (ss->special->rewind_scanner)(ss);
310			if (error)
311				return (error);
312		} else {
313			/* XXX add code to restart a SCSI2 scanner, if any */
314		}
315		ss->sio.scan_window_size = 0;
316		ss->flags &= ~SSF_TRIGGERED;
317	}
318
319	scsipi_wait_drain(periph);
320
321	scsipi_adapter_delref(adapt);
322	periph->periph_flags &= ~PERIPH_OPEN;
323
324	return (0);
325}
326
327/*
328 * trim the size of the transfer if needed,
329 * called by physio
330 * basically the smaller of our min and the scsi driver's
331 * minphys
332 */
333void
334ssminphys(struct buf *bp)
335{
336	struct ss_softc *ss = ss_cd.cd_devs[SSUNIT(bp->b_dev)];
337	struct scsipi_periph *periph = ss->sc_periph;
338
339	(*periph->periph_channel->chan_adapter->adapt_minphys)(bp);
340
341	/*
342	 * trim the transfer further for special devices this is
343	 * because some scanners only read multiples of a line at a
344	 * time, also some cannot disconnect, so the read must be
345	 * short enough to happen quickly
346	 */
347	if (ss->special && ss->special->minphys)
348		(ss->special->minphys)(ss, bp);
349}
350
351/*
352 * Do a read on a device for a user process.
353 * Prime scanner at start of read, check uio values, call ssstrategy
354 * via physio for the actual transfer.
355 */
356int
357ssread(dev, uio, flag)
358	dev_t dev;
359	struct uio *uio;
360	int flag;
361{
362	struct ss_softc *ss = ss_cd.cd_devs[SSUNIT(dev)];
363	int error;
364
365	if ((ss->sc_dev.dv_flags & DVF_ACTIVE) == 0)
366		return (ENODEV);
367
368	/* if the scanner has not yet been started, do it now */
369	if (!(ss->flags & SSF_TRIGGERED)) {
370		if (ss->special && ss->special->trigger_scanner) {
371			error = (ss->special->trigger_scanner)(ss);
372			if (error)
373				return (error);
374		}
375		ss->flags |= SSF_TRIGGERED;
376	}
377
378	return (physio(ssstrategy, NULL, dev, B_READ, ssminphys, uio));
379}
380
381/*
382 * Actually translate the requested transfer into one the physical
383 * driver can understand The transfer is described by a buf and will
384 * include only one physical transfer.
385 */
386void
387ssstrategy(bp)
388	struct buf *bp;
389{
390	struct ss_softc *ss = ss_cd.cd_devs[SSUNIT(bp->b_dev)];
391	struct scsipi_periph *periph = ss->sc_periph;
392	int s;
393
394	SC_DEBUG(ss->sc_periph, SCSIPI_DB1,
395	    ("ssstrategy %ld bytes @ blk %d\n", bp->b_bcount, bp->b_blkno));
396
397	/*
398	 * If the device has been made invalid, error out
399	 */
400	if ((ss->sc_dev.dv_flags & DVF_ACTIVE) == 0) {
401		bp->b_flags |= B_ERROR;
402		if (periph->periph_flags & PERIPH_OPEN)
403			bp->b_error = EIO;
404		else
405			bp->b_error = ENODEV;
406		goto done;
407	}
408
409	/* If negative offset, error */
410	if (bp->b_blkno < 0) {
411		bp->b_flags |= B_ERROR;
412		bp->b_error = EINVAL;
413		goto done;
414	}
415
416	if (bp->b_bcount > ss->sio.scan_window_size)
417		bp->b_bcount = ss->sio.scan_window_size;
418
419	/*
420	 * If it's a null transfer, return immediatly
421	 */
422	if (bp->b_bcount == 0)
423		goto done;
424
425	s = splbio();
426
427	/*
428	 * Place it in the queue of activities for this scanner
429	 * at the end (a bit silly because we only have on user..
430	 * (but it could fork()))
431	 */
432	BUFQ_INSERT_TAIL(&ss->buf_queue, bp);
433
434	/*
435	 * Tell the device to get going on the transfer if it's
436	 * not doing anything, otherwise just wait for completion
437	 * (All a bit silly if we're only allowing 1 open but..)
438	 */
439	ssstart(ss->sc_periph);
440
441	splx(s);
442	return;
443	bp->b_flags |= B_ERROR;
444done:
445	/*
446	 * Correctly set the buf to indicate a completed xfer
447	 */
448	bp->b_resid = bp->b_bcount;
449	biodone(bp);
450}
451
452/*
453 * ssstart looks to see if there is a buf waiting for the device
454 * and that the device is not already busy. If both are true,
455 * It dequeues the buf and creates a scsi command to perform the
456 * transfer required. The transfer request will call scsipi_done
457 * on completion, which will in turn call this routine again
458 * so that the next queued transfer is performed.
459 * The bufs are queued by the strategy routine (ssstrategy)
460 *
461 * This routine is also called after other non-queued requests
462 * have been made of the scsi driver, to ensure that the queue
463 * continues to be drained.
464 * ssstart() is called at splbio
465 */
466void
467ssstart(periph)
468	struct scsipi_periph *periph;
469{
470	struct ss_softc *ss = (void *)periph->periph_dev;
471	struct buf *bp;
472
473	SC_DEBUG(periph, SCSIPI_DB2, ("ssstart "));
474	/*
475	 * See if there is a buf to do and we are not already
476	 * doing one
477	 */
478	while (periph->periph_active < periph->periph_openings) {
479		/* if a special awaits, let it proceed first */
480		if (periph->periph_flags & PERIPH_WAITING) {
481			periph->periph_flags &= ~PERIPH_WAITING;
482			wakeup((caddr_t)periph);
483			return;
484		}
485
486		/*
487		 * See if there is a buf with work for us to do..
488		 */
489		if ((bp = BUFQ_FIRST(&ss->buf_queue)) == NULL)
490			return;
491		BUFQ_REMOVE(&ss->buf_queue, bp);
492
493		if (ss->special && ss->special->read) {
494			(ss->special->read)(ss, bp);
495		} else {
496			/* generic scsi2 scanner read */
497			/* XXX add code for SCSI2 scanner read */
498		}
499	}
500}
501
502/*
503 * Perform special action on behalf of the user;
504 * knows about the internals of this device
505 */
506int
507ssioctl(dev, cmd, addr, flag, p)
508	dev_t dev;
509	u_long cmd;
510	caddr_t addr;
511	int flag;
512	struct proc *p;
513{
514	struct ss_softc *ss = ss_cd.cd_devs[SSUNIT(dev)];
515	int error = 0;
516	struct scan_io *sio;
517
518	if ((ss->sc_dev.dv_flags & DVF_ACTIVE) == 0)
519		return (ENODEV);
520
521	switch (cmd) {
522	case SCIOCGET:
523		if (ss->special && ss->special->get_params) {
524			/* call special handler */
525			error = (ss->special->get_params)(ss);
526			if (error)
527				return (error);
528		} else {
529			/* XXX add code for SCSI2 scanner, if any */
530			return (EOPNOTSUPP);
531		}
532		memcpy(addr, &ss->sio, sizeof(struct scan_io));
533		break;
534	case SCIOCSET:
535		sio = (struct scan_io *)addr;
536
537		if (ss->special && ss->special->set_params) {
538			/* call special handler */
539			error = (ss->special->set_params)(ss, sio);
540			if (error)
541				return (error);
542		} else {
543			/* XXX add code for SCSI2 scanner, if any */
544			return (EOPNOTSUPP);
545		}
546		break;
547	case SCIOCRESTART:
548		if (ss->special && ss->special->rewind_scanner ) {
549			/* call special handler */
550			error = (ss->special->rewind_scanner)(ss);
551			if (error)
552				return (error);
553		} else
554			/* XXX add code for SCSI2 scanner, if any */
555			return (EOPNOTSUPP);
556		ss->flags &= ~SSF_TRIGGERED;
557		break;
558#ifdef NOTYET
559	case SCAN_USE_ADF:
560		break;
561#endif
562	default:
563		return (scsipi_do_ioctl(ss->sc_periph, dev, cmd, addr,
564		    flag, p));
565	}
566	return (error);
567}
568