--- /dev/null
+/* $OpenBSD: kcore.h,v 1.1 1996/04/19 16:08:13 niklas Exp $ */
+/* $NetBSD: kcore.h,v 1.1 1996/03/10 21:55:18 leo Exp $ */
+
+/*
+ * Copyright (c) 1996 Leo Weppelman.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Leo Weppelman.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _M68K_KCORE_H_
+#define _M68K_KCORE_H_
+
+#define NPHYS_RAM_SEGS 8
+
+typedef struct cpu_kcore_hdr {
+ vm_offset_t kernel_pa; /* Phys. address of kernel VA 0 */
+ st_entry_t *sysseg_pa; /* Phys. address of Sysseg */
+ int mmutype;
+ phys_ram_seg_t ram_segs[NPHYS_RAM_SEGS];
+} cpu_kcore_hdr_t;
+
+#endif /* _M68K_KCORE_H_ */
--- /dev/null
+/* $OpenBSD: db_memrw.c,v 1.1 1996/04/19 16:08:17 niklas Exp $ */
+/* $NetBSD: db_memrw.c,v 1.1 1996/02/22 23:23:35 gwr Exp $ */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+/*
+ * Interface to the debugger for virtual memory read/write.
+ * This is a simple version for kernels with writable text.
+ * For an example of read-only kernel text, see the file:
+ * sys/arch/sun3/sun3/db_memrw.c
+ *
+ * ALERT! If you want to access device registers with a
+ * specific size, then the read/write functions have to
+ * make sure to do the correct sized pointer access.
+ */
+
+#include <sys/param.h>
+#include <sys/proc.h>
+
+#include <vm/vm.h>
+
+#include <machine/db_machdep.h>
+
+#include <ddb/db_access.h>
+
+/*
+ * Read bytes from kernel address space for debugger.
+ */
+void
+db_read_bytes(addr, size, data)
+ vm_offset_t addr;
+ register size_t size;
+ register char *data;
+{
+ register char *src = (char*)addr;
+
+ if (size == 4) {
+ *((int*)data) = *((int*)src);
+ return;
+ }
+
+ if (size == 2) {
+ *((short*)data) = *((short*)src);
+ return;
+ }
+
+ while (size > 0) {
+ --size;
+ *data++ = *src++;
+ }
+}
+
+/*
+ * Write bytes to kernel address space for debugger.
+ */
+void
+db_write_bytes(addr, size, data)
+ vm_offset_t addr;
+ register size_t size;
+ register char *data;
+{
+ register char *dst = (char *)addr;
+
+ if (size == 4) {
+ *((int*)dst) = *((int*)data);
+ return;
+ }
+
+ if (size == 2) {
+ *((short*)dst) = *((short*)data);
+ return;
+ }
+
+ while (size > 0) {
+ --size;
+ *dst++ = *data++;
+ }
+}
+
* System call numbers.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from NetBSD: syscalls.master,v 1.32 1995/10/07 06:27:35 mycroft Exp
+ * created from OpenBSD
*/
#define SUNOS_SYS_syscall 0
* System call names.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from NetBSD: syscalls.master,v 1.32 1995/10/07 06:27:35 mycroft Exp
+ * created from OpenBSD
*/
char *sunos_syscallnames[] = {
-# $OpenBSD: files,v 1.13 1996/04/19 07:31:23 mickey Exp $
+# $OpenBSD: files,v 1.14 1996/04/19 16:08:25 niklas Exp $
# $NetBSD: files,v 1.82 1996/03/19 01:02:35 paulus Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
define isabus { } # ISA attachment
define eisabus { } # EISA attachment
define pcibus {[bus = -1]} # PCI attachment
+define pcmciabus { } # PCMCIA attachment
define tcbus { } # TurboChannel attachment
# legitimate pseudo-devices
-/* $OpenBSD: db_aout.c,v 1.5 1996/03/30 04:51:28 mickey Exp $ */
+/* $OpenBSD: db_aout.c,v 1.6 1996/04/19 16:08:28 niklas Exp $ */
+/* $NetBSD: db_aout.c,v 1.14 1996/02/27 20:54:43 gwr Exp $ */
/*
* Mach Operating System
#ifndef DB_NO_AOUT
-#define _AOUT_INCLUDE_
-#include <nlist.h>
-#include <stab.h>
+#include <ddb/db_aout.h>
/*
* An a.out symbol table as loaded into the kernel debugger:
--- /dev/null
+/* $OpenBSD: db_aout.h,v 1.1 1996/04/19 16:08:29 niklas Exp $ */
+/* $NetBSD: db_aout.h,v 1.1 1996/02/27 20:54:44 gwr Exp $ */
+
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This is an in-line expansion of "a.out.h" customized for ddb.
+ */
+
+#ifndef _DB_AOUT_H_
+#define _DB_AOUT_H_
+
+/*
+ * @(#)nlist.h 8.2 (Berkeley) 1/21/94
+ */
+
+/*
+ * Symbol table entry format. The #ifdef's are so that programs including
+ * nlist.h can initialize nlist structures statically.
+ */
+struct nlist {
+ union {
+ char *n_name; /* symbol name (in memory) */
+ long n_strx; /* file string table offset (on disk) */
+ } n_un;
+
+#define N_UNDF 0x00 /* undefined */
+#define N_ABS 0x02 /* absolute address */
+#define N_TEXT 0x04 /* text segment */
+#define N_DATA 0x06 /* data segment */
+#define N_BSS 0x08 /* bss segment */
+#define N_INDR 0x0a /* alias definition */
+#define N_SIZE 0x0c /* pseudo type, defines a symbol's size */
+#define N_COMM 0x12 /* common reference */
+#define N_FN 0x1e /* file name (N_EXT on) */
+
+#define N_EXT 0x01 /* external (global) bit, OR'ed in */
+#define N_TYPE 0x1e /* mask for all the type bits */
+ unsigned char n_type; /* type defines */
+
+ char n_other; /* spare */
+#define n_hash n_desc /* used internally by ld(1); XXX */
+ short n_desc; /* used by stab entries */
+ unsigned long n_value; /* address/value of the symbol */
+};
+
+#define N_FORMAT "%08x" /* namelist value format; XXX */
+#define N_STAB 0x0e0 /* mask for debugger symbols -- stab(5) */
+
+/* End nlist.h */
+
+/*
+ * @(#)stab.h 5.2 (Berkeley) 4/4/91
+ */
+
+/*
+ * The following are symbols used by various debuggers and by the Pascal
+ * compiler. Each of them must have one (or more) of the bits defined by
+ * the N_STAB mask set.
+ */
+
+#define N_GSYM 0x20 /* global symbol */
+#define N_FNAME 0x22 /* F77 function name */
+#define N_FUN 0x24 /* procedure name */
+#define N_STSYM 0x26 /* data segment variable */
+#define N_LCSYM 0x28 /* bss segment variable */
+#define N_MAIN 0x2a /* main function name */
+#define N_PC 0x30 /* global Pascal symbol */
+#define N_RSYM 0x40 /* register variable */
+#define N_SLINE 0x44 /* text segment line number */
+#define N_DSLINE 0x46 /* data segment line number */
+#define N_BSLINE 0x48 /* bss segment line number */
+#define N_SSYM 0x60 /* structure/union element */
+#define N_SO 0x64 /* main source file name */
+#define N_LSYM 0x80 /* stack variable */
+#define N_BINCL 0x82 /* include file beginning */
+#define N_SOL 0x84 /* included source file name */
+#define N_PSYM 0xa0 /* parameter variable */
+#define N_EINCL 0xa2 /* include file end */
+#define N_ENTRY 0xa4 /* alternate entry point */
+#define N_LBRAC 0xc0 /* left bracket */
+#define N_EXCL 0xc2 /* deleted include file */
+#define N_RBRAC 0xe0 /* right bracket */
+#define N_BCOMM 0xe2 /* begin common */
+#define N_ECOMM 0xe4 /* end common */
+#define N_ECOML 0xe8 /* end common (local name) */
+#define N_LENG 0xfe /* length of preceding entry */
+
+#endif /* !_DB_AOUT_H_ */
-/* $OpenBSD: db_command.c,v 1.5 1996/04/19 07:43:48 mickey Exp $ */
+/* $OpenBSD: db_command.c,v 1.6 1996/04/19 16:08:30 niklas Exp $ */
+/* $NetBSD: db_command.c,v 1.19 1996/03/13 21:06:38 christos Exp $ */
/*
* Mach Operating System
--- /dev/null
+/* $OpenBSD: comvar.h,v 1.1 1996/04/19 16:08:34 niklas Exp $ */
+/* $NetBSD: comvar.h,v 1.3 1996/03/10 09:01:26 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+struct commulti_attach_args {
+ int ca_slave; /* slave number */
+
+ bus_chipset_tag_t ca_bc;
+ bus_io_handle_t ca_ioh;
+ int ca_iobase;
+ int ca_noien;
+};
+
+int comprobe1 __P((bus_chipset_tag_t, bus_io_handle_t, int));
+
+extern int comconsaddr;
+extern int comconsattached;
+extern bus_chipset_tag_t comconsbc;
+extern bus_io_handle_t comconsioh;
--- /dev/null
+/* $OpenBSD: comvar.h,v 1.1 1996/04/19 16:08:34 niklas Exp $ */
+/* $NetBSD: comvar.h,v 1.3 1996/03/10 09:01:26 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+struct commulti_attach_args {
+ int ca_slave; /* slave number */
+
+ bus_chipset_tag_t ca_bc;
+ bus_io_handle_t ca_ioh;
+ int ca_iobase;
+ int ca_noien;
+};
+
+int comprobe1 __P((bus_chipset_tag_t, bus_io_handle_t, int));
+
+extern int comconsaddr;
+extern int comconsattached;
+extern bus_chipset_tag_t comconsbc;
+extern bus_io_handle_t comconsioh;
+# $OpenBSD: Makefile,v 1.3 1996/04/19 16:08:38 niklas Exp $
# $NetBSD: Makefile,v 1.1 1995/06/18 01:07:04 cgd Exp $
AWK= awk --posix
-/* $OpenBSD: aic7870.c,v 1.5 1996/04/18 23:47:54 niklas Exp $ */
-/* $NetBSD: aic7870.c,v 1.8 1996/03/17 00:55:23 thorpej Exp $ */
+/* $NetBSD: aic7870.c,v 1.7 1996/03/04 19:30:50 cgd Exp $ */
/*
* Product specific probe and attach routines for:
static int aic7870_probe __P((struct device *, void *, void *));
static void aic7870_attach __P((struct device *, struct device *, void *));
-struct cfattach ahc_ca = {
- sizeof(struct ahc_softc), aic7870_probe, aic7870_attach
-};
-
-struct cfdriver ahc_cd = {
- NULL, "ahc", DV_DULL
+struct cfdriver ahccd = {
+ NULL, "ahc", aic7870_probe, aic7870_attach, DV_DULL,
+ sizeof(struct ahc_softc)
};
int ahcintr __P((void *));
ahcattach(ahc);
- ahc->sc_ih = pci_map_int(pa->pa_tag, IPL_BIO, ahcintr, ahc
+ ahc->sc_ih = pci_map_int(pa->pa_tag, IPL_BIO, ahcintr, ahc,
ahc->sc_dev.dv_xname);
}
-/* $OpenBSD: cd9660_util.c,v 1.2 1996/02/29 10:12:24 niklas Exp $ */
-/* $NetBSD: cd9660_util.c,v 1.9 1996/02/09 21:32:06 christos Exp $ */
+/* $OpenBSD: cd9660_util.c,v 1.3 1996/04/19 16:08:41 niklas Exp $ */
+/* $NetBSD: cd9660_util.c,v 1.10 1996/02/29 20:36:39 gwr Exp $ */
/*-
* Copyright (c) 1994
#include <miscfs/specfs/specdev.h> /* XXX */
#include <miscfs/fifofs/fifo.h> /* XXX */
#include <sys/malloc.h>
-#include <sys/dir.h>
+#include <sys/dirent.h>
#include <isofs/cd9660/iso.h>
-/* $OpenBSD: cd9660_vnops.c,v 1.3 1996/02/29 10:12:28 niklas Exp $ */
-/* $NetBSD: cd9660_vnops.c,v 1.29 1996/02/10 00:33:53 christos Exp $ */
+/* $OpenBSD: cd9660_vnops.c,v 1.4 1996/04/19 16:08:43 niklas Exp $ */
+/* $NetBSD: cd9660_vnops.c,v 1.31 1996/03/08 18:13:07 scottr Exp $ */
/*-
* Copyright (c) 1994
#include <miscfs/specfs/specdev.h>
#include <miscfs/fifofs/fifo.h>
#include <sys/malloc.h>
-#include <sys/dir.h>
+#include <sys/dirent.h>
#include <isofs/cd9660/iso.h>
#include <isofs/cd9660/cd9660_node.h>
int error;
dp->d_name[dp->d_namlen] = 0;
- dp->d_reclen = DIRSIZ(dp);
+ dp->d_reclen = DIRENT_SIZE(dp);
if (idp->uio->uio_resid < dp->d_reclen) {
idp->eofflag = 0;
}
}
}
- idp->current.d_reclen = DIRSIZ(&idp->current);
+ idp->current.d_reclen = DIRENT_SIZE(&idp->current);
if (assoc) {
idp->assocoff = idp->curroff;
bcopy(&idp->current,&idp->assocent,idp->current.d_reclen);
-/* $NetBSD: exec_ecoff.c,v 1.5 1994/08/18 22:09:35 cgd Exp $ */
+/* $OpenBSD: exec_ecoff.c,v 1.2 1996/04/19 16:08:47 niklas Exp $ */
+/* $NetBSD: exec_ecoff.c,v 1.6 1996/03/07 14:31:16 christos Exp $ */
/*
* Copyright (c) 1994 Adam Glass
struct proc *p;
struct exec_package *epp;
{
- u_long midmag, magic;
- u_short mid;
int error;
struct ecoff_filehdr *efp = epp->ep_hdr;
struct ecoff_aouthdr *eap;
if (error)
kill_vmcmds(&epp->ep_vmcmds);
-bad:
return error;
}
* System call switch table.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from NetBSD: syscalls.master,v 1.30 1995/11/22 23:07:29 cgd Exp
+ * created from OpenBSD
*/
#include <sys/param.h>
sys_nosys }, /* 173 = unimplemented */
{ 0, 0,
sys_nosys }, /* 174 = unimplemented */
+#ifdef NTP
+ { 1, s(struct ntp_gettime_args),
+ ntp_gettime }, /* 175 = ntp_gettime */
+ { 1, s(struct ntp_adjtime_args),
+ ntp_adjtime }, /* 176 = ntp_adjtime */
+#else
+ { 0, 0,
+ sys_nosys }, /* 175 = unimplemented ntp_gettime */
+ { 0, 0,
+ sys_nosys }, /* 176 = unimplemented ntp_adjtime */
+#endif
{ 0, 0,
- sys_nosys }, /* 175 = unimplemented */
- { 1, s(struct sys_ntp_adjtime_args),
- sys_ntp_adjtime }, /* 176 = ntp_adjtime */
- { 1, s(struct sys_ntp_gettime_args),
- sys_ntp_gettime }, /* 177 = ntp_gettime */
+ sys_nosys }, /* 177 = unimplemented */
{ 0, 0,
sys_nosys }, /* 178 = unimplemented */
{ 0, 0,
-/* $OpenBSD: kern_clock.c,v 1.7 1996/03/03 17:19:41 niklas Exp $ */
-/* $NetBSD: kern_clock.c,v 1.23 1995/12/28 19:16:41 thorpej Exp $ */
+/* $OpenBSD: kern_clock.c,v 1.8 1996/04/19 16:08:50 niklas Exp $ */
+/* $NetBSD: kern_clock.c,v 1.31 1996/03/15 07:56:00 mycroft Exp $ */
/*-
* Copyright (c) 1982, 1986, 1991, 1993
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
*/
-/* Portions of this software are covered by the following: */
-/******************************************************************************
- * *
- * Copyright (c) David L. Mills 1993, 1994 *
- * *
- * Permission to use, copy, modify, and distribute this software and its *
- * documentation for any purpose and without fee is hereby granted, provided *
- * that the above copyright notice appears in all copies and that both the *
- * copyright notice and this permission notice appear in supporting *
- * documentation, and that the name University of Delaware not be used in *
- * advertising or publicity pertaining to distribution of the software *
- * without specific, written prior permission. The University of Delaware *
- * makes no representations about the suitability this software for any *
- * purpose. It is provided "as is" without express or implied warranty. *
- * *
- *****************************************************************************/
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/dkstat.h>
* allocate more timeout table slots when table overflows.
*/
-/*
- * Bump a timeval by a small number of usec's.
- */
-#define BUMPTIME(t, usec) { \
- register volatile struct timeval *tp = (t); \
- register long us; \
- \
- tp->tv_usec = us = tp->tv_usec + (usec); \
- if (us >= 1000000) { \
- tp->tv_usec = us - 1000000; \
- tp->tv_sec++; \
- } \
-}
-
-int stathz;
-int profhz;
-int profprocs;
-int ticks;
-static int psdiv, pscnt; /* prof => stat divider */
-int psratio; /* ratio: prof / stat */
-
-volatile struct timeval time;
-volatile struct timeval mono_time;
+#ifdef NTP /* NTP phase-locked loop in kernel */
/*
- * Phase-lock loop (PLL) definitions
+ * Phase/frequency-lock loop (PLL/FLL) definitions
*
* The following variables are read and set by the ntp_adjtime() system
* call.
* time_status shows the status of the system clock, with bits defined
* in the timex.h header file.
*
- * time_offset is used by the PLL to adjust the system time in small
+ * time_offset is used by the PLL/FLL to adjust the system time in small
* increments.
*
* time_constant determines the bandwidth or "stiffness" of the PLL.
* whether the external clock is working or not.
*
* time_maxerror is initialized by a ntp_adjtime() call and increased by
- * the kernel once each second to reflect the maximum error
- * bound growth.
+ * the kernel once each second to reflect the maximum error bound
+ * growth.
*
* time_esterror is set and read by the ntp_adjtime() call, but
* otherwise not used by the kernel.
*/
-int time_status = STA_UNSYNC; /* clock status bits */
int time_state = TIME_OK; /* clock state */
+int time_status = STA_UNSYNC; /* clock status bits */
long time_offset = 0; /* time offset (us) */
long time_constant = 0; /* pll time constant */
long time_tolerance = MAXFREQ; /* frequency tolerance (scaled ppm) */
long time_esterror = MAXPHASE; /* estimated error (us) */
/*
- * The following variables establish the state of the PLL and the
+ * The following variables establish the state of the PLL/FLL and the
* residual time and frequency offset of the local clock. The scale
* factors are defined in the timex.h header file.
*
* time_phase and time_freq are the phase increment and the frequency
- * increment, respectively, of the kernel time variable at each tick of
- * the clock.
+ * increment, respectively, of the kernel time variable.
*
* time_freq is set via ntp_adjtime() from a value stored in a file when
* the synchronization daemon is first started. Its value is retrieved
* daemon.
*
* time_adj is the adjustment added to the value of tick at each timer
- * interrupt and is recomputed at each timer interrupt.
+ * interrupt and is recomputed from time_phase and time_freq at each
+ * seconds rollover.
*
- * time_reftime is the second's portion of the system time on the last
+ * time_reftime is the second's portion of the system time at the last
* call to ntp_adjtime(). It is used to adjust the time_freq variable
* and to increase the time_maxerror as the time since last update
* increases.
*/
-static long time_phase = 0; /* phase offset (scaled us) */
+long time_phase = 0; /* phase offset (scaled us) */
long time_freq = 0; /* frequency offset (scaled ppm) */
-static long time_adj = 0; /* tick adjust (scaled 1 / hz) */
-static long time_reftime = 0; /* time at last adjustment (s) */
+long time_adj = 0; /* tick adjust (scaled 1 / hz) */
+long time_reftime = 0; /* time at last adjustment (s) */
#ifdef PPS_SYNC
/*
- * The following variables are used only if the if the kernel PPS
- * discipline code is configured (PPS_SYNC). The scale factors are
- * defined in the timex.h header file.
+ * The following variables are used only if the kernel PPS discipline
+ * code is configured (PPS_SYNC). The scale factors are defined in the
+ * timex.h header file.
*
* pps_time contains the time at each calibration interval, as read by
- * microtime().
+ * microtime(). pps_count counts the seconds of the calibration
+ * interval, the duration of which is nominally pps_shift in powers of
+ * two.
*
* pps_offset is the time offset produced by the time median filter
- * pps_tf[], while pps_jitter is the dispersion measured by this
- * filter.
+ * pps_tf[], while pps_jitter is the dispersion (jitter) measured by
+ * this filter.
*
* pps_freq is the frequency offset produced by the frequency median
- * filter pps_ff[], while pps_stabil is the dispersion measured by
- * this filter.
+ * filter pps_ff[], while pps_stabil is the dispersion (wander) measured
+ * by this filter.
*
* pps_usec is latched from a high resolution counter or external clock
* at pps_time. Here we want the hardware counter contents only, not the
* mainly to suppress error bursts due to priority conflicts between the
* PPS interrupt and timer interrupt.
*
- * pps_count counts the seconds of the calibration interval, the
- * duration of which is pps_shift in powers of two.
- *
* pps_intcnt counts the calibration intervals for use in the interval-
* adaptation algorithm. It's just too complicated for words.
*/
struct timeval pps_time; /* kernel time at last interval */
-long pps_offset = 0; /* pps time offset (us) */
-long pps_jitter = MAXTIME; /* pps time dispersion (jitter) (us) */
long pps_tf[] = {0, 0, 0}; /* pps time offset median filter (us) */
+long pps_offset = 0; /* pps time offset (us) */
+long pps_jitter = MAXTIME; /* time dispersion (jitter) (us) */
+long pps_ff[] = {0, 0, 0}; /* pps frequency offset median filter */
long pps_freq = 0; /* frequency offset (scaled ppm) */
long pps_stabil = MAXFREQ; /* frequency dispersion (scaled ppm) */
-long pps_ff[] = {0, 0, 0}; /* frequency offset median filter */
long pps_usec = 0; /* microsec counter at last interval */
long pps_valid = PPS_VALID; /* pps signal watchdog counter */
int pps_glitch = 0; /* pps signal glitch counter */
long pps_stbcnt = 0; /* stability limit exceeded */
#endif /* PPS_SYNC */
+#ifdef EXT_CLOCK
/*
- * hardupdate() - local clock update
- *
- * This routine is called by ntp_adjtime() to update the local clock
- * phase and frequency. This is used to implement an adaptive-parameter,
- * first-order, type-II phase-lock loop. The code computes new time and
- * frequency offsets each time it is called. The hardclock() routine
- * amortizes these offsets at each tick interrupt. If the kernel PPS
- * discipline code is configured (PPS_SYNC), the PPS signal itself
- * determines the new time offset, instead of the calling argument.
- * Presumably, calls to ntp_adjtime() occur only when the caller
- * believes the local clock is valid within some bound (+-128 ms with
- * NTP). If the caller's time is far different than the PPS time, an
- * argument will ensue, and it's not clear who will lose.
- *
- * For default SHIFT_UPDATE = 12, the offset is limited to +-512 ms, the
- * maximum interval between updates is 4096 s and the maximum frequency
- * offset is +-31.25 ms/s.
+ * External clock definitions
*
- * Note: splclock() is in effect.
+ * The following definitions and declarations are used only if an
+ * external clock is configured on the system.
*/
-void
-hardupdate(offset)
- long offset;
-{
- long ltemp, mtemp;
+#define CLOCK_INTERVAL 30 /* CPU clock update interval (s) */
- if (!(time_status & STA_PLL) && !(time_status & STA_PPSTIME))
- return;
- ltemp = offset;
-#ifdef PPS_SYNC
- if (time_status & STA_PPSTIME && time_status & STA_PPSSIGNAL)
- ltemp = pps_offset;
-#endif /* PPS_SYNC */
- if (ltemp > MAXPHASE)
- time_offset = MAXPHASE << SHIFT_UPDATE;
- else if (ltemp < -MAXPHASE)
- time_offset = -(MAXPHASE << SHIFT_UPDATE);
- else
- time_offset = ltemp << SHIFT_UPDATE;
+/*
+ * The clock_count variable is set to CLOCK_INTERVAL at each PPS
+ * interrupt and decremented once each second.
+ */
+int clock_count = 0; /* CPU clock counter */
- /*
- * Select wether the frequency is to be controlled and in which
- * mode (PLL or FLL). Clamp to the operating range. Ugly
- * multiply/divide should be replaced someday.
- */
- if (time_status * STA_FREQHOLD || time_reftime == 0)
- time_reftime = time.tv_sec;
- mtemp = time.tv_sec - time_reftime;
- time_reftime = time.tv_sec;
- if (time_status & STA_FLL) {
- if (mtemp >= MINSEC) {
- ltemp = ((time_offset / mtemp) << (SHIFT_USEC - SHIFT_UPDATE));
- if (ltemp < 0)
- time_freq -= -ltemp >> SHIFT_KH;
- else
- time_freq += ltemp >> SHIFT_KH;
- }
- }
- else {
- if (mtemp < MAXSEC) {
- ltemp *= mtemp;
- if (ltemp < 0)
- time_freq -= -ltemp >> (time_constant +
- time_constant + SHIFT_KF - SHIFT_USEC);
- else
- time_freq += ltemp >> (time_constant +
- time_constant + SHIFT_KF - SHIFT_USEC);
- }
- }
- if (time_freq > time_tolerance)
- time_freq = time_tolerance;
- else if (time_freq < -time_tolerance)
- time_freq = -time_tolerance;
+#ifdef HIGHBALL
+/*
+ * The clock_offset and clock_cpu variables are used by the HIGHBALL
+ * interface. The clock_offset variable defines the offset between
+ * system time and the HIGBALL counters. The clock_cpu variable contains
+ * the offset between the system clock and the HIGHBALL clock for use in
+ * disciplining the kernel time variable.
+ */
+extern struct timeval clock_offset; /* Highball clock offset */
+long clock_cpu = 0; /* CPU clock adjust */
+#endif /* HIGHBALL */
+#endif /* EXT_CLOCK */
+#endif /* NTP */
+
+
+/*
+ * Bump a timeval by a small number of usec's.
+ */
+#define BUMPTIME(t, usec) { \
+ register volatile struct timeval *tp = (t); \
+ register long us; \
+ \
+ tp->tv_usec = us = tp->tv_usec + (usec); \
+ if (us >= 1000000) { \
+ tp->tv_usec = us - 1000000; \
+ tp->tv_sec++; \
+ } \
}
+int stathz;
+int profhz;
+int profprocs;
+int ticks;
+static int psdiv, pscnt; /* prof => stat divider */
+int psratio; /* ratio: prof / stat */
+int tickfix, tickfixinterval; /* used if tick not really integral */
+static int tickfixcnt; /* number of ticks since last fix */
+#ifdef NTP
+int fixtick; /* used by NTP for same */
+int shifthz;
+#endif
+
+volatile struct timeval time;
+volatile struct timeval mono_time;
+
/*
* Initialize clock frequencies and start both clocks running.
*/
if (profhz == 0)
profhz = i;
psratio = profhz / i;
+
+#ifdef NTP
+ switch (hz) {
+ case 60:
+ case 64:
+ shifthz = SHIFT_SCALE - 6;
+ break;
+ case 96:
+ case 100:
+ case 128:
+ shifthz = SHIFT_SCALE - 7;
+ break;
+ case 256:
+ shifthz = SHIFT_SCALE - 8;
+ break;
+ case 1024:
+ shifthz = SHIFT_SCALE - 10;
+ break;
+ default:
+ panic("weird hz");
+ }
+#endif
}
/*
{
register struct callout *p1;
register struct proc *p;
- register int needsoft;
- int time_update;
- struct timeval newtime;
- long ltemp;
+ register int delta, needsoft;
+ extern int tickdelta;
+ extern long timedelta;
+#ifdef NTP
+ register int time_update;
+ register int ltemp;
+#endif
/*
* Update real-time timeout queue.
statclock(frame);
/*
- * Increment the time-of-day
+ * Increment the time-of-day. The increment is normally just
+ * ``tick''. If the machine is one which has a clock frequency
+ * such that ``hz'' would not divide the second evenly into
+ * milliseconds, a periodic adjustment must be applied. Finally,
+ * if we are still adjusting the time (see adjtime()),
+ * ``tickdelta'' may also be added in.
*/
ticks++;
- newtime = time;
-
- if (timedelta == 0) {
- time_update = tick;
+ delta = tick;
+
+#ifndef NTP
+ if (tickfix) {
+ tickfixcnt++;
+ if (tickfixcnt >= tickfixinterval) {
+ delta += tickfix;
+ tickfixcnt = 0;
+ }
}
- else {
- time_update = tick + tickdelta;
+#endif /* !NTP */
+ /* Imprecise 4bsd adjtime() handling */
+ if (timedelta != 0) {
+ delta = tick + tickdelta;
timedelta -= tickdelta;
}
- BUMPTIME(&mono_time, time_update);
+
+#ifdef notyet
+ microset();
+#endif
+
+#ifndef NTP
+ BUMPTIME(&time, delta); /* XXX Now done using NTP code below */
+#endif
+ BUMPTIME(&mono_time, delta);
+
+#ifdef NTP
+ time_update = delta;
/*
- * Compute the phase adjustment. If the low-order bits
- * (time_phase) of the update overflow, bump the high-order
- * bits (time_update).
+ * Compute the phase adjustment. If the low-order bits
+ * (time_phase) of the update overflow, bump the high-order bits
+ * (time_update).
*/
time_phase += time_adj;
if (time_phase <= -FINEUSEC) {
ltemp = -time_phase >> SHIFT_SCALE;
time_phase += ltemp << SHIFT_SCALE;
time_update -= ltemp;
- }
- else if (time_phase >= FINEUSEC) {
+ } else if (time_phase >= FINEUSEC) {
ltemp = time_phase >> SHIFT_SCALE;
time_phase -= ltemp << SHIFT_SCALE;
time_update += ltemp;
}
- newtime.tv_usec += time_update;
+#ifdef HIGHBALL
+ /*
+ * If the HIGHBALL board is installed, we need to adjust the
+ * external clock offset in order to close the hardware feedback
+ * loop. This will adjust the external clock phase and frequency
+ * in small amounts. The additional phase noise and frequency
+ * wander this causes should be minimal. We also need to
+ * discipline the kernel time variable, since the PLL is used to
+ * discipline the external clock. If the Highball board is not
+ * present, we discipline kernel time with the PLL as usual. We
+ * assume that the external clock phase adjustment (time_update)
+ * and kernel phase adjustment (clock_cpu) are less than the
+ * value of tick.
+ */
+ clock_offset.tv_usec += time_update;
+ if (clock_offset.tv_usec >= 1000000) {
+ clock_offset.tv_sec++;
+ clock_offset.tv_usec -= 1000000;
+ }
+ if (clock_offset.tv_usec < 0) {
+ clock_offset.tv_sec--;
+ clock_offset.tv_usec += 1000000;
+ }
+ time.tv_usec += clock_cpu;
+ clock_cpu = 0;
+#else
+ time.tv_usec += time_update;
+#endif /* HIGHBALL */
+
/*
* On rollover of the second the phase adjustment to be used for
* the next second is calculated. Also, the maximum error is
* code is present, the phase is increased to compensate for the
* CPU clock oscillator frequency error.
*
- * With SHIFT_SCALE = 23, the maximum frequency adjustment is
- * +-256 us per tick, or 25.6 ms/s at a clock frequency of 100
- * Hz. The time contribution is shifted right a minimum of two
- * bits, while the frequency contribution is a right shift.
- * Thus, overflow is prevented if the frequency contribution is
- * limited to half the maximum or 15.625 ms/s.
+ * On a 32-bit machine and given parameters in the timex.h
+ * header file, the maximum phase adjustment is +-512 ms and
+ * maximum frequency offset is a tad less than) +-512 ppm. On a
+ * 64-bit machine, you shouldn't need to ask.
*/
- if (newtime.tv_usec >= 1000000) {
- newtime.tv_usec -= 1000000;
- newtime.tv_sec++;
+ if (time.tv_usec >= 1000000) {
+ time.tv_usec -= 1000000;
+ time.tv_sec++;
time_maxerror += time_tolerance >> SHIFT_USEC;
+
+ /*
+ * Leap second processing. If in leap-insert state at
+ * the end of the day, the system clock is set back one
+ * second; if in leap-delete state, the system clock is
+ * set ahead one second. The microtime() routine or
+ * external clock driver will insure that reported time
+ * is always monotonic. The ugly divides should be
+ * replaced.
+ */
+ switch (time_state) {
+ case TIME_OK:
+ if (time_status & STA_INS)
+ time_state = TIME_INS;
+ else if (time_status & STA_DEL)
+ time_state = TIME_DEL;
+ break;
+
+ case TIME_INS:
+ if (time.tv_sec % 86400 == 0) {
+ time.tv_sec--;
+ time_state = TIME_OOP;
+ }
+ break;
+
+ case TIME_DEL:
+ if ((time.tv_sec + 1) % 86400 == 0) {
+ time.tv_sec++;
+ time_state = TIME_WAIT;
+ }
+ break;
+
+ case TIME_OOP:
+ time_state = TIME_WAIT;
+ break;
+
+ case TIME_WAIT:
+ if (!(time_status & (STA_INS | STA_DEL)))
+ time_state = TIME_OK;
+ break;
+ }
+
+ /*
+ * Compute the phase adjustment for the next second. In
+ * PLL mode, the offset is reduced by a fixed factor
+ * times the time constant. In FLL mode the offset is
+ * used directly. In either mode, the maximum phase
+ * adjustment for each second is clamped so as to spread
+ * the adjustment over not more than the number of
+ * seconds between updates.
+ */
if (time_offset < 0) {
ltemp = -time_offset;
if (!(time_status & STA_FLL))
ltemp >>= SHIFT_KG + time_constant;
if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
- ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
+ ltemp = (MAXPHASE / MINSEC) <<
+ SHIFT_UPDATE;
time_offset += ltemp;
- time_adj = -ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
- }
- else {
+ time_adj = -ltemp << (shifthz - SHIFT_UPDATE);
+ } else if (time_offset > 0) {
ltemp = time_offset;
if (!(time_status & STA_FLL))
ltemp >>= SHIFT_KG + time_constant;
if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
- ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
+ ltemp = (MAXPHASE / MINSEC) <<
+ SHIFT_UPDATE;
time_offset -= ltemp;
- time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
- }
-#ifdef PPS_SYNC
+ time_adj = ltemp << (shifthz - SHIFT_UPDATE);
+ } else
+ time_adj = 0;
+
/*
- * Gnaw on the watchdog counter and update the frequency
- * computed by the pll and the PPS signal
+ * Compute the frequency estimate and additional phase
+ * adjustment due to frequency error for the next
+ * second. When the PPS signal is engaged, gnaw on the
+ * watchdog counter and update the frequency computed by
+ * the pll and the PPS signal.
*/
+#ifdef PPS_SYNC
pps_valid++;
if (pps_valid == PPS_VALID) {
pps_jitter = MAXTIME;
pps_stabil = MAXFREQ;
time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
- STA_PPSWANDER | STA_PPSERROR);
+ STA_PPSWANDER | STA_PPSERROR);
}
ltemp = time_freq + pps_freq;
#else
ltemp = time_freq;
#endif /* PPS_SYNC */
+
if (ltemp < 0)
- time_adj -= -ltemp >> (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
+ time_adj -= -ltemp >> (SHIFT_USEC - shifthz);
else
- time_adj += ltemp >> (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
+ time_adj += ltemp >> (SHIFT_USEC - shifthz);
+ time_adj += (long)fixtick << shifthz;
-#if SHIFT_HZ == 7
/*
* When the CPU clock oscillator frequency is not a
- * power of two in Hz, the SHIFT_HZ is only an
- * approximate scale factor. In the following code
- * the overall gain is increased by a factor of 1.25.
+ * power of 2 in Hz, shifthz is only an approximate
+ * scale factor.
*/
- if (hz == 100) {
+ switch (hz) {
+ case 96:
+ case 100:
+ /*
+ * In the following code the overall gain is increased
+ * by a factor of 1.25, which results in a residual
+ * error less than 3 percent.
+ */
if (time_adj < 0)
time_adj -= -time_adj >> 2;
else
time_adj += time_adj >> 2;
+ break;
+ case 60:
+ /*
+ * 60 Hz m68k and vaxes have a PLL gain factor of of
+ * 60/64 (15/16) of what it should be. In the following code
+ * the overall gain is increased by a factor of 1.0625,
+ * (17/16) which results in a residual error of just less
+ * than 0.4 percent.
+ */
+ if (time_adj < 0)
+ time_adj -= -time_adj >> 4;
+ else
+ time_adj += time_adj >> 4;
+ break;
}
-#endif /* SHIFT_HZ */
+#ifdef EXT_CLOCK
/*
- * Leap second processing. If in leap-insert state at
- * the end of the day, the system clock is set back one
- * second; if in leap-delete state, the system clock is
- * set ahead one second. The microtime() routine or
- * external clock driver will insure that reported time
- * is always monotonic. The ugly divides should be
- * replacesd.
+ * If an external clock is present, it is necessary to
+ * discipline the kernel time variable anyway, since not
+ * all system components use the microtime() interface.
+ * Here, the time offset between the external clock and
+ * kernel time variable is computed every so often.
*/
- switch (time_state) {
-
- case TIME_OK:
- if (time_status & STA_INS)
- time_state = TIME_INS;
- else if (time_status & STA_DEL)
- time_state = TIME_DEL;
- break;
-
- case TIME_INS:
- if (newtime.tv_sec % 86400 == 0) {
- newtime.tv_sec--;
- time_state = TIME_OOP;
+ clock_count++;
+ if (clock_count > CLOCK_INTERVAL) {
+ clock_count = 0;
+ microtime(&clock_ext);
+ delta.tv_sec = clock_ext.tv_sec - time.tv_sec;
+ delta.tv_usec = clock_ext.tv_usec -
+ time.tv_usec;
+ if (delta.tv_usec < 0)
+ delta.tv_sec--;
+ if (delta.tv_usec >= 500000) {
+ delta.tv_usec -= 1000000;
+ delta.tv_sec++;
}
- break;
-
- case TIME_DEL:
- if ((newtime.tv_sec + 1) % 86400 == 0) {
- newtime.tv_sec++;
- time_state = TIME_WAIT;
+ if (delta.tv_usec < -500000) {
+ delta.tv_usec += 1000000;
+ delta.tv_sec--;
}
- break;
-
- case TIME_OOP:
- time_state = TIME_WAIT;
- break;
-
- case TIME_WAIT:
- if (!(time_status & (STA_INS | STA_DEL)))
- time_state = TIME_OK;
- break;
+ if (delta.tv_sec > 0 || (delta.tv_sec == 0 &&
+ delta.tv_usec > MAXPHASE) ||
+ delta.tv_sec < -1 || (delta.tv_sec == -1 &&
+ delta.tv_usec < -MAXPHASE)) {
+ time = clock_ext;
+ delta.tv_sec = 0;
+ delta.tv_usec = 0;
+ }
+#ifdef HIGHBALL
+ clock_cpu = delta.tv_usec;
+#else /* HIGHBALL */
+ hardupdate(delta.tv_usec);
+#endif /* HIGHBALL */
}
+#endif /* EXT_CLOCK */
}
-#ifdef CPU_CLOCKUPDATE
- CPU_CLOCKUPDATE(&time, &newtime);
-#else
- time = newtime;
-#endif
+
+#endif /* NTP */
/*
* Process callouts at a very low cpu priority, so we don't keep the
hzto(tv)
struct timeval *tv;
{
- register unsigned long ticks;
- register long sec, usec;
+ register long ticks, sec;
int s;
/*
- * If the number of usecs in the whole seconds part of the time
- * difference fits in a long, then the total number of usecs will
- * fit in an unsigned long. Compute the total and convert it to
- * ticks, rounding up and adding 1 to allow for the current tick
- * to expire. Rounding also depends on unsigned long arithmetic
- * to avoid overflow.
- *
- * Otherwise, if the number of ticks in the whole seconds part of
- * the time difference fits in a long, then convert the parts to
- * ticks separately and add, using similar rounding methods and
- * overflow avoidance. This method would work in the previous
- * case but it is slightly slower and assumes that hz is integral.
+ * If number of microseconds will fit in 32 bit arithmetic,
+ * then compute number of microseconds to time and scale to
+ * ticks. Otherwise just compute number of hz in time, rounding
+ * times greater than representible to maximum value. (We must
+ * compute in microseconds, because hz can be greater than 1000,
+ * and thus tick can be less than one millisecond).
*
- * Otherwise, round the time difference down to the maximum
- * representable value.
- *
- * If ints have 32 bits, then the maximum value for any timeout in
- * 10ms ticks is 248 days.
+ * Delta times less than 14 hours can be computed ``exactly''.
+ * (Note that if hz would yeild a non-integral number of us per
+ * tick, i.e. tickfix is nonzero, timouts can be a tick longer
+ * than they should be.) Maximum value for any timeout in 10ms
+ * ticks is 250 days.
*/
- s = splclock();
+ s = splhigh();
sec = tv->tv_sec - time.tv_sec;
- usec = tv->tv_usec - time.tv_usec;
- splx(s);
- if (usec < 0) {
- sec--;
- usec += 1000000;
- }
- if (sec < 0) {
-#ifdef DIAGNOSTIC
- printf("hzto: negative time difference %ld sec %ld usec\n",
- sec, usec);
-#endif
- ticks = 1;
- }
- else if (sec <= LONG_MAX / 1000000)
- ticks = (sec * 1000000 + (unsigned long)usec + (tick - 1)) / tick + 1;
- else if (sec <= LONG_MAX / hz)
- ticks = sec * hz + ((unsigned long)usec + (tick - 1)) / tick + 1;
+ if (sec <= 0x7fffffff / 1000000 - 1)
+ ticks = ((tv->tv_sec - time.tv_sec) * 1000000 +
+ (tv->tv_usec - time.tv_usec)) / tick;
+ else if (sec <= 0x7fffffff / hz)
+ ticks = sec * hz;
else
- ticks = LONG_MAX;
- if (ticks > INT_MAX)
- ticks = INT_MAX;
+ ticks = 0x7fffffff;
+ splx(s);
return (ticks);
}
}
}
+
+#ifdef NTP /* NTP phase-locked loop in kernel */
+
+/*
+ * hardupdate() - local clock update
+ *
+ * This routine is called by ntp_adjtime() to update the local clock
+ * phase and frequency. The implementation is of an adaptive-parameter,
+ * hybrid phase/frequency-lock loop (PLL/FLL). The routine computes new
+ * time and frequency offset estimates for each call. If the kernel PPS
+ * discipline code is configured (PPS_SYNC), the PPS signal itself
+ * determines the new time offset, instead of the calling argument.
+ * Presumably, calls to ntp_adjtime() occur only when the caller
+ * believes the local clock is valid within some bound (+-128 ms with
+ * NTP). If the caller's time is far different than the PPS time, an
+ * argument will ensue, and it's not clear who will lose.
+ *
+ * For uncompensated quartz crystal oscillatores and nominal update
+ * intervals less than 1024 s, operation should be in phase-lock mode
+ * (STA_FLL = 0), where the loop is disciplined to phase. For update
+ * intervals greater than thiss, operation should be in frequency-lock
+ * mode (STA_FLL = 1), where the loop is disciplined to frequency.
+ *
+ * Note: splclock() is in effect.
+ */
+void
+hardupdate(offset)
+ long offset;
+{
+ long ltemp, mtemp;
+
+ if (!(time_status & STA_PLL) && !(time_status & STA_PPSTIME))
+ return;
+ ltemp = offset;
+#ifdef PPS_SYNC
+ if (time_status & STA_PPSTIME && time_status & STA_PPSSIGNAL)
+ ltemp = pps_offset;
+#endif /* PPS_SYNC */
+
+ /*
+ * Scale the phase adjustment and clamp to the operating range.
+ */
+ if (ltemp > MAXPHASE)
+ time_offset = MAXPHASE << SHIFT_UPDATE;
+ else if (ltemp < -MAXPHASE)
+ time_offset = -(MAXPHASE << SHIFT_UPDATE);
+ else
+ time_offset = ltemp << SHIFT_UPDATE;
+
+ /*
+ * Select whether the frequency is to be controlled and in which
+ * mode (PLL or FLL). Clamp to the operating range. Ugly
+ * multiply/divide should be replaced someday.
+ */
+ if (time_status & STA_FREQHOLD || time_reftime == 0)
+ time_reftime = time.tv_sec;
+ mtemp = time.tv_sec - time_reftime;
+ time_reftime = time.tv_sec;
+ if (time_status & STA_FLL) {
+ if (mtemp >= MINSEC) {
+ ltemp = ((time_offset / mtemp) << (SHIFT_USEC -
+ SHIFT_UPDATE));
+ if (ltemp < 0)
+ time_freq -= -ltemp >> SHIFT_KH;
+ else
+ time_freq += ltemp >> SHIFT_KH;
+ }
+ } else {
+ if (mtemp < MAXSEC) {
+ ltemp *= mtemp;
+ if (ltemp < 0)
+ time_freq -= -ltemp >> (time_constant +
+ time_constant + SHIFT_KF -
+ SHIFT_USEC);
+ else
+ time_freq += ltemp >> (time_constant +
+ time_constant + SHIFT_KF -
+ SHIFT_USEC);
+ }
+ }
+ if (time_freq > time_tolerance)
+ time_freq = time_tolerance;
+ else if (time_freq < -time_tolerance)
+ time_freq = -time_tolerance;
+}
+
+#ifdef PPS_SYNC
+/*
+ * hardpps() - discipline CPU clock oscillator to external PPS signal
+ *
+ * This routine is called at each PPS interrupt in order to discipline
+ * the CPU clock oscillator to the PPS signal. It measures the PPS phase
+ * and leaves it in a handy spot for the hardclock() routine. It
+ * integrates successive PPS phase differences and calculates the
+ * frequency offset. This is used in hardclock() to discipline the CPU
+ * clock oscillator so that intrinsic frequency error is cancelled out.
+ * The code requires the caller to capture the time and hardware counter
+ * value at the on-time PPS signal transition.
+ *
+ * Note that, on some Unix systems, this routine runs at an interrupt
+ * priority level higher than the timer interrupt routine hardclock().
+ * Therefore, the variables used are distinct from the hardclock()
+ * variables, except for certain exceptions: The PPS frequency pps_freq
+ * and phase pps_offset variables are determined by this routine and
+ * updated atomically. The time_tolerance variable can be considered a
+ * constant, since it is infrequently changed, and then only when the
+ * PPS signal is disabled. The watchdog counter pps_valid is updated
+ * once per second by hardclock() and is atomically cleared in this
+ * routine.
+ */
+void
+hardpps(tvp, usec)
+ struct timeval *tvp; /* time at PPS */
+ long usec; /* hardware counter at PPS */
+{
+ long u_usec, v_usec, bigtick;
+ long cal_sec, cal_usec;
+
+ /*
+ * An occasional glitch can be produced when the PPS interrupt
+ * occurs in the hardclock() routine before the time variable is
+ * updated. Here the offset is discarded when the difference
+ * between it and the last one is greater than tick/2, but not
+ * if the interval since the first discard exceeds 30 s.
+ */
+ time_status |= STA_PPSSIGNAL;
+ time_status &= ~(STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR);
+ pps_valid = 0;
+ u_usec = -tvp->tv_usec;
+ if (u_usec < -500000)
+ u_usec += 1000000;
+ v_usec = pps_offset - u_usec;
+ if (v_usec < 0)
+ v_usec = -v_usec;
+ if (v_usec > (tick >> 1)) {
+ if (pps_glitch > MAXGLITCH) {
+ pps_glitch = 0;
+ pps_tf[2] = u_usec;
+ pps_tf[1] = u_usec;
+ } else {
+ pps_glitch++;
+ u_usec = pps_offset;
+ }
+ } else
+ pps_glitch = 0;
+
+ /*
+ * A three-stage median filter is used to help deglitch the pps
+ * time. The median sample becomes the time offset estimate; the
+ * difference between the other two samples becomes the time
+ * dispersion (jitter) estimate.
+ */
+ pps_tf[2] = pps_tf[1];
+ pps_tf[1] = pps_tf[0];
+ pps_tf[0] = u_usec;
+ if (pps_tf[0] > pps_tf[1]) {
+ if (pps_tf[1] > pps_tf[2]) {
+ pps_offset = pps_tf[1]; /* 0 1 2 */
+ v_usec = pps_tf[0] - pps_tf[2];
+ } else if (pps_tf[2] > pps_tf[0]) {
+ pps_offset = pps_tf[0]; /* 2 0 1 */
+ v_usec = pps_tf[2] - pps_tf[1];
+ } else {
+ pps_offset = pps_tf[2]; /* 0 2 1 */
+ v_usec = pps_tf[0] - pps_tf[1];
+ }
+ } else {
+ if (pps_tf[1] < pps_tf[2]) {
+ pps_offset = pps_tf[1]; /* 2 1 0 */
+ v_usec = pps_tf[2] - pps_tf[0];
+ } else if (pps_tf[2] < pps_tf[0]) {
+ pps_offset = pps_tf[0]; /* 1 0 2 */
+ v_usec = pps_tf[1] - pps_tf[2];
+ } else {
+ pps_offset = pps_tf[2]; /* 1 2 0 */
+ v_usec = pps_tf[1] - pps_tf[0];
+ }
+ }
+ if (v_usec > MAXTIME)
+ pps_jitcnt++;
+ v_usec = (v_usec << PPS_AVG) - pps_jitter;
+ if (v_usec < 0)
+ pps_jitter -= -v_usec >> PPS_AVG;
+ else
+ pps_jitter += v_usec >> PPS_AVG;
+ if (pps_jitter > (MAXTIME >> 1))
+ time_status |= STA_PPSJITTER;
+
+ /*
+ * During the calibration interval adjust the starting time when
+ * the tick overflows. At the end of the interval compute the
+ * duration of the interval and the difference of the hardware
+ * counters at the beginning and end of the interval. This code
+ * is deliciously complicated by the fact valid differences may
+ * exceed the value of tick when using long calibration
+ * intervals and small ticks. Note that the counter can be
+ * greater than tick if caught at just the wrong instant, but
+ * the values returned and used here are correct.
+ */
+ bigtick = (long)tick << SHIFT_USEC;
+ pps_usec -= pps_freq;
+ if (pps_usec >= bigtick)
+ pps_usec -= bigtick;
+ if (pps_usec < 0)
+ pps_usec += bigtick;
+ pps_time.tv_sec++;
+ pps_count++;
+ if (pps_count < (1 << pps_shift))
+ return;
+ pps_count = 0;
+ pps_calcnt++;
+ u_usec = usec << SHIFT_USEC;
+ v_usec = pps_usec - u_usec;
+ if (v_usec >= bigtick >> 1)
+ v_usec -= bigtick;
+ if (v_usec < -(bigtick >> 1))
+ v_usec += bigtick;
+ if (v_usec < 0)
+ v_usec = -(-v_usec >> pps_shift);
+ else
+ v_usec = v_usec >> pps_shift;
+ pps_usec = u_usec;
+ cal_sec = tvp->tv_sec;
+ cal_usec = tvp->tv_usec;
+ cal_sec -= pps_time.tv_sec;
+ cal_usec -= pps_time.tv_usec;
+ if (cal_usec < 0) {
+ cal_usec += 1000000;
+ cal_sec--;
+ }
+ pps_time = *tvp;
+
+ /*
+ * Check for lost interrupts, noise, excessive jitter and
+ * excessive frequency error. The number of timer ticks during
+ * the interval may vary +-1 tick. Add to this a margin of one
+ * tick for the PPS signal jitter and maximum frequency
+ * deviation. If the limits are exceeded, the calibration
+ * interval is reset to the minimum and we start over.
+ */
+ u_usec = (long)tick << 1;
+ if (!((cal_sec == -1 && cal_usec > (1000000 - u_usec))
+ || (cal_sec == 0 && cal_usec < u_usec))
+ || v_usec > time_tolerance || v_usec < -time_tolerance) {
+ pps_errcnt++;
+ pps_shift = PPS_SHIFT;
+ pps_intcnt = 0;
+ time_status |= STA_PPSERROR;
+ return;
+ }
+
+ /*
+ * A three-stage median filter is used to help deglitch the pps
+ * frequency. The median sample becomes the frequency offset
+ * estimate; the difference between the other two samples
+ * becomes the frequency dispersion (stability) estimate.
+ */
+ pps_ff[2] = pps_ff[1];
+ pps_ff[1] = pps_ff[0];
+ pps_ff[0] = v_usec;
+ if (pps_ff[0] > pps_ff[1]) {
+ if (pps_ff[1] > pps_ff[2]) {
+ u_usec = pps_ff[1]; /* 0 1 2 */
+ v_usec = pps_ff[0] - pps_ff[2];
+ } else if (pps_ff[2] > pps_ff[0]) {
+ u_usec = pps_ff[0]; /* 2 0 1 */
+ v_usec = pps_ff[2] - pps_ff[1];
+ } else {
+ u_usec = pps_ff[2]; /* 0 2 1 */
+ v_usec = pps_ff[0] - pps_ff[1];
+ }
+ } else {
+ if (pps_ff[1] < pps_ff[2]) {
+ u_usec = pps_ff[1]; /* 2 1 0 */
+ v_usec = pps_ff[2] - pps_ff[0];
+ } else if (pps_ff[2] < pps_ff[0]) {
+ u_usec = pps_ff[0]; /* 1 0 2 */
+ v_usec = pps_ff[1] - pps_ff[2];
+ } else {
+ u_usec = pps_ff[2]; /* 1 2 0 */
+ v_usec = pps_ff[1] - pps_ff[0];
+ }
+ }
+
+ /*
+ * Here the frequency dispersion (stability) is updated. If it
+ * is less than one-fourth the maximum (MAXFREQ), the frequency
+ * offset is updated as well, but clamped to the tolerance. It
+ * will be processed later by the hardclock() routine.
+ */
+ v_usec = (v_usec >> 1) - pps_stabil;
+ if (v_usec < 0)
+ pps_stabil -= -v_usec >> PPS_AVG;
+ else
+ pps_stabil += v_usec >> PPS_AVG;
+ if (pps_stabil > MAXFREQ >> 2) {
+ pps_stbcnt++;
+ time_status |= STA_PPSWANDER;
+ return;
+ }
+ if (time_status & STA_PPSFREQ) {
+ if (u_usec < 0) {
+ pps_freq -= -u_usec >> PPS_AVG;
+ if (pps_freq < -time_tolerance)
+ pps_freq = -time_tolerance;
+ u_usec = -u_usec;
+ } else {
+ pps_freq += u_usec >> PPS_AVG;
+ if (pps_freq > time_tolerance)
+ pps_freq = time_tolerance;
+ }
+ }
+
+ /*
+ * Here the calibration interval is adjusted. If the maximum
+ * time difference is greater than tick / 4, reduce the interval
+ * by half. If this is not the case for four consecutive
+ * intervals, double the interval.
+ */
+ if (u_usec << pps_shift > bigtick >> 2) {
+ pps_intcnt = 0;
+ if (pps_shift > PPS_SHIFT)
+ pps_shift--;
+ } else if (pps_intcnt >= 4) {
+ pps_intcnt = 0;
+ if (pps_shift < PPS_SHIFTMAX)
+ pps_shift++;
+ } else
+ pps_intcnt++;
+}
+#endif /* PPS_SYNC */
+#endif /* NTP */
+
+
/*
* Return information about system clocks.
*/
/*
* Construct clockinfo structure.
*/
- clkinfo.hz = hz;
clkinfo.tick = tick;
+ clkinfo.tickadj = tickadj;
+ clkinfo.hz = hz;
clkinfo.profhz = profhz;
clkinfo.stathz = stathz ? stathz : hz;
return (sysctl_rdstruct(where, sizep, NULL, &clkinfo, sizeof(clkinfo)));
-/* $NetBSD: kern_conf.h,v 1.1 1996/02/04 02:19:27 christos Exp $ */
+/* $OpenBSD: kern_conf.h,v 1.2 1996/04/19 16:08:52 niklas Exp $ */
+/* $NetBSD: kern_conf.h,v 1.2 1996/03/14 19:01:08 christos Exp $ */
/*
* Copyright (c) 1995 Christos Zoulas. All rights reserved.
#include <sys/conf.h>
-cdev_decl(fdesc);
+cdev_decl(filedesc);
cdev_decl(log);
-/* $OpenBSD: kern_descrip.c,v 1.3 1996/03/03 17:19:42 niklas Exp $ */
-/* $NetBSD: kern_descrip.c,v 1.39 1996/02/09 18:59:26 christos Exp $ */
+/* $OpenBSD: kern_descrip.c,v 1.4 1996/04/19 16:08:53 niklas Exp $ */
+/* $NetBSD: kern_descrip.c,v 1.40 1996/03/14 19:01:10 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1993
*/
/* ARGSUSED */
int
-fdopen(dev, mode, type, p)
+filedescopen(dev, mode, type, p)
dev_t dev;
int mode, type;
struct proc *p;
-/* $OpenBSD: kern_malloc.c,v 1.2 1996/03/03 17:19:49 niklas Exp $ */
-/* $NetBSD: kern_malloc.c,v 1.13 1996/02/09 18:59:39 christos Exp $ */
+/* $OpenBSD: kern_malloc.c,v 1.3 1996/04/19 16:08:55 niklas Exp $ */
+/* $NetBSD: kern_malloc.c,v 1.14 1996/02/20 23:56:16 cgd Exp $ */
/*
* Copyright (c) 1987, 1991, 1993
for (lp = (int32_t *)va; lp < end; lp++) {
if (*lp == WEIRD_ADDR)
continue;
- printf("%s %d of object %p size %d %s %s (%p != %p)\n",
+ printf("%s %d of object %p size %d %s %s (0x%x != 0x%x)\n",
"Data modified on freelist: word", lp - (int32_t *)va,
- va, size, "previous type", savedtype, (void *)*lp,
- (void *) WEIRD_ADDR);
+ va, size, "previous type", savedtype, *lp, WEIRD_ADDR);
break;
}
+/* $OpenBSD: kern_ntptime.c,v 1.3 1996/04/19 16:08:57 niklas Exp $ */
+/* $NetBSD: kern_ntptime.c,v 1.2 1996/03/07 14:31:20 christos Exp $ */
+
/******************************************************************************
* *
* Copyright (c) David L. Mills 1993, 1994 *
* frequency of the phase-lock loop which controls the system clock.
*/
#include <sys/param.h>
+#include <sys/resourcevar.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/timex.h>
+#include <sys/vnode.h>
#include <sys/mount.h>
#include <sys/syscallargs.h>
+#include <machine/cpu.h>
+
+#include <vm/vm.h>
+#include <sys/sysctl.h>
+
+#ifdef NTP
+
/*
* The following variables are used by the hardclock() routine in the
* kern_clock.c module and are described in that module.
*/
+extern struct timeval time; /* kernel time variable */
extern int time_state; /* clock state */
extern int time_status; /* clock status bits */
extern long time_offset; /* time adjustment (us) */
extern long pps_stbcnt; /* stability limit exceeded */
#endif /* PPS_SYNC */
+
+
+/*ARGSUSED*/
/*
* ntp_gettime() - NTP user application interface
*/
int
-sys_ntp_gettime(p, v, retval)
+ntp_gettime(p, v, retval)
struct proc *p;
void *v;
register_t *retval;
+
{
- register struct sys_ntp_gettime_args /* {
- syscallarg(struct ntptimeval *) tp;
+ struct ntp_gettime_args /* {
+ syscallarg(struct timex *) tp;
} */ *uap = v;
struct timeval atv;
struct ntptimeval ntv;
- int error, s;
+ int error = 0;
+ int s;
if (SCARG(uap, tp)) {
s = splclock();
time_status & (STA_PPSWANDER | STA_PPSERROR)))
*retval = TIME_ERROR;
else
- *retval = time_state;
+ *retval = (register_t)time_state;
}
- return (error);
+ return(error);
}
+
+/* ARGSUSED */
/*
* ntp_adjtime() - NTP daemon application interface
*/
int
-sys_ntp_adjtime(p, v, retval)
+ntp_adjtime(p, v, retval)
struct proc *p;
void *v;
register_t *retval;
{
- register struct sys_ntp_adjtime_args /* {
+ struct ntp_adjtime_args /* {
syscallarg(struct timex *) tp;
} */ *uap = v;
struct timex ntv;
+ int error = 0;
int modes;
- int error, s;
+ int s;
- error = copyin((caddr_t)SCARG(uap, tp), (caddr_t)&ntv, sizeof(ntv));
- if (error)
+ if ((error = copyin((caddr_t)SCARG(uap, tp), (caddr_t)&ntv,
+ sizeof(ntv))))
return (error);
/*
* the assumption the superuser should know what it is doing.
*/
modes = ntv.modes;
- if (modes && (error = suser(p->p_ucred, &p->p_acflag)))
+ if (modes != 0 && (error = suser(p->p_ucred, &p->p_acflag)))
return (error);
+
s = splclock();
if (modes & MOD_FREQUENCY)
#ifdef PPS_SYNC
#endif /* PPS_SYNC */
(void)splx(s);
- error = copyout((caddr_t)&ntv, (caddr_t)SCARG(uap, tp),
- sizeof(ntv));
+ error = copyout((caddr_t)&ntv, (caddr_t)SCARG(uap, tp), sizeof(ntv));
if (!error) {
/*
time_status & (STA_PPSWANDER | STA_PPSERROR)))
*retval = TIME_ERROR;
else
- *retval = time_state;
+ *retval = (register_t)time_state;
+ }
+ return error;
+}
+
+
+
+/*
+ * return information about kernel precision timekeeping
+ */
+int
+sysctl_ntptime(where, sizep)
+ register char *where;
+ size_t *sizep;
+{
+ struct timeval atv;
+ struct ntptimeval ntv;
+ int s;
+
+ /*
+ * Construct ntp_timeval.
+ */
+
+ s = splclock();
+#ifdef EXT_CLOCK
+ /*
+ * The microtime() external clock routine returns a
+ * status code. If less than zero, we declare an error
+ * in the clock status word and return the kernel
+ * (software) time variable. While there are other
+ * places that call microtime(), this is the only place
+ * that matters from an application point of view.
+ */
+ if (microtime(&atv) < 0) {
+ time_status |= STA_CLOCKERR;
+ ntv.time = time;
+ } else {
+ time_status &= ~STA_CLOCKERR;
}
- return (error);
+#else /* EXT_CLOCK */
+ microtime(&atv);
+#endif /* EXT_CLOCK */
+ ntv.time = atv;
+ ntv.maxerror = time_maxerror;
+ ntv.esterror = time_esterror;
+ splx(s);
+
+#ifdef notyet
+ /*
+ * Status word error decode. If any of these conditions
+ * occur, an error is returned, instead of the status
+ * word. Most applications will care only about the fact
+ * the system clock may not be trusted, not about the
+ * details.
+ *
+ * Hardware or software error
+ */
+ if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) ||
+ ntv.time_state = TIME_ERROR;
+
+ /*
+ * PPS signal lost when either time or frequency
+ * synchronization requested
+ */
+ (time_status & (STA_PPSFREQ | STA_PPSTIME) &&
+ !(time_status & STA_PPSSIGNAL)) ||
+
+ /*
+ * PPS jitter exceeded when time synchronization
+ * requested
+ */
+ (time_status & STA_PPSTIME &&
+ time_status & STA_PPSJITTER) ||
+
+ /*
+ * PPS wander exceeded or calibration error when
+ * frequency synchronization requested
+ */
+ (time_status & STA_PPSFREQ &&
+ time_status & (STA_PPSWANDER | STA_PPSERROR)))
+ ntv.time_state = TIME_ERROR;
+ else
+ ntv.time_state = time_state;
+#endif /* notyet */
+ return (sysctl_rdstruct(where, sizep, NULL, &ntv, sizeof(ntv)));
+}
+
+#else /* !NTP */
+
+/*
+ * For kernels configured without the NTP option, emulate the behavior
+ * of a kernel with no NTP support (i.e., sys_nosys()). On systems
+ * where kernel NTP support appears present when xntpd is compiled,
+ * (e.g., sys/timex.h is present), xntpd relies on getting a SIGSYS
+ * signal in response to an ntp_adjtime() syscal, to inform xntpd that
+ * NTP support is not really present, and xntpd should fall back to
+ * using a user-level phase-locked loop to discipline the clock.
+ */
+int
+ntp_gettime(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ return(ENOSYS);
+}
+
+int
+ntp_adjtime(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ return(sys_nosys(p, v, retval));
+}
+
+int
+sysctl_ntptime(where, sizep)
+ register char *where;
+ size_t *sizep;
+{
+ return (ENOSYS);
}
+#endif /* NTP */
-/* $OpenBSD: kern_sysctl.c,v 1.3 1996/03/30 04:51:32 mickey Exp $ */
-/* $NetBSD: kern_sysctl.c,v 1.14 1996/02/09 18:59:52 christos Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.4 1996/04/19 16:08:59 niklas Exp $ */
+/* $NetBSD: kern_sysctl.c,v 1.15 1996/02/27 04:20:40 jonathan Exp $ */
/*-
* Copyright (c) 1982, 1986, 1989, 1993
return (sysctl_rdint(oldp, oldlenp, newp, MAXPARTITIONS));
case KERN_RAWPARTITION:
return (sysctl_rdint(oldp, oldlenp, newp, RAW_PART));
+ case KERN_NTPTIME:
+ return (sysctl_ntptime(oldp, oldlenp));
default:
return (EOPNOTSUPP);
}
-/* $OpenBSD: subr_autoconf.c,v 1.2 1996/03/03 17:19:59 niklas Exp $ */
-/* $NetBSD: subr_autoconf.c,v 1.17 1996/02/04 02:16:35 christos Exp $ */
+/* $OpenBSD: subr_autoconf.c,v 1.3 1996/04/19 16:09:01 niklas Exp $ */
+/* $NetBSD: subr_autoconf.c,v 1.18 1996/02/27 21:45:46 cgd Exp $ */
/*
* Copyright (c) 1992, 1993
/*
* The given `aux' argument describes a device that has been found
* on the given parent, but not necessarily configured. Locate the
- * configuration data for that device (using the cd_match configuration
- * driver function) and attach it, and return true. If the device was
+ * configuration data for that device (using the submatch function
+ * provided, or using candidates' cd_match configuration driver
+ * functions) and attach it, and return true. If the device was
* not configured, call the given `print' function and return 0.
*/
int
-config_found(parent, aux, print)
+config_found_sm(parent, aux, print, submatch)
struct device *parent;
void *aux;
cfprint_t print;
+ cfmatch_t submatch;
{
void *match;
- if ((match = config_search((cfmatch_t)NULL, parent, aux)) != NULL) {
+ if ((match = config_search(submatch, parent, aux)) != NULL) {
config_attach(parent, match, aux, print);
return (1);
}
-/* $NetBSD: subr_prf.c,v 1.21 1996/02/09 19:00:01 christos Exp $ */
+/* $OpenBSD: subr_prf.c,v 1.3 1996/04/19 16:09:03 niklas Exp $ */
+/* $NetBSD: subr_prf.c,v 1.22 1996/03/14 19:01:11 christos Exp $ */
/*-
* Copyright (c) 1986, 1988, 1991, 1993
#ifdef KADB
#include <machine/kdbparam.h>
#endif
+#ifdef KGDB
+#include <machine/cpu.h>
+#endif
#define TOCONS 0x01
#define TOTTY 0x02
* System call names.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from NetBSD: syscalls.master,v 1.30 1995/11/22 23:07:29 cgd Exp
+ * created from OpenBSD
*/
char *syscallnames[] = {
"#172 (unimplemented)", /* 172 = unimplemented */
"#173 (unimplemented)", /* 173 = unimplemented */
"#174 (unimplemented)", /* 174 = unimplemented */
- "#175 (unimplemented)", /* 175 = unimplemented */
+#ifdef NTP
+ "ntp_gettime", /* 175 = ntp_gettime */
"ntp_adjtime", /* 176 = ntp_adjtime */
- "ntp_gettime", /* 177 = ntp_gettime */
+#else
+ "#175 (unimplemented ntp_gettime)", /* 175 = unimplemented ntp_gettime */
+ "#176 (unimplemented ntp_adjtime)", /* 176 = unimplemented ntp_adjtime */
+#endif
+ "#177 (unimplemented)", /* 177 = unimplemented */
"#178 (unimplemented)", /* 178 = unimplemented */
"#179 (unimplemented)", /* 179 = unimplemented */
"#180 (unimplemented)", /* 180 = unimplemented */
- $NetBSD: syscalls.master,v 1.30 1995/11/22 23:07:29 cgd Exp $
+ $OpenBSD: syscalls.master,v 1.6 1996/04/19 16:09:07 niklas Exp $
+; $NetBSD: syscalls.master,v 1.31 1996/02/27 04:20:41 jonathan Exp $
; @(#)syscalls.master 8.2 (Berkeley) 1/13/94
172 UNIMPL
173 UNIMPL
174 UNIMPL
-175 UNIMPL
-176 STD { int sys_ntp_adjtime(struct timex *tp); }
-177 STD { int sys_ntp_gettime(struct ntptimeval *tp); }
+#ifdef NTP
+175 STD { int ntp_gettime(struct timex *tp); }
+176 STD { int ntp_adjtime(struct timex *tp); }
+#else
+175 UNIMPL ntp_gettime
+176 UNIMPL ntp_adjtime
+#endif
+177 UNIMPL
178 UNIMPL
179 UNIMPL
180 UNIMPL
-/* $NetBSD: vfs_bio.c,v 1.41 1996/02/09 19:00:53 christos Exp $ */
+/* $OpenBSD: vfs_bio.c,v 1.4 1996/04/19 16:09:09 niklas Exp $ */
+/* $NetBSD: vfs_bio.c,v 1.42 1996/02/18 11:57:08 fvdl Exp $ */
/*-
* Copyright (c) 1994 Christopher G. Demetriou
}
/* Otherwise, the "write" is done, so mark and release the buffer. */
+ CLR(bp->b_flags, B_NEEDCOMMIT);
SET(bp->b_flags, B_DONE);
brelse(bp);
}
* (Modifications made here may easily be lost!)
*
* Created from the file:
- * NetBSD: vnode_if.src,v 1.9 1996/02/09 14:45:38 mycroft Exp
+ * OpenBSD
* by the script:
- * NetBSD: vnode_if.sh,v 1.9 1996/02/29 20:58:22 cgd Exp
+ * OpenBSD
*/
/*
* SUCH DAMAGE.
*/
"
-SCRIPT_ID='$NetBSD: vnode_if.sh,v 1.9 1996/02/29 20:58:22 cgd Exp $'
+SCRIPT_ID='$OpenBSD: vnode_if.sh,v 1.3 1996/04/19 16:09:13 niklas Exp $'
+# SCRIPT_ID='$NetBSD: vnode_if.sh,v 1.9 1996/02/29 20:58:22 cgd Exp $'
# Script to produce VFS front-end sugar.
#
+# $OpenBSD: vnode_if.src,v 1.3 1996/04/19 16:09:14 niklas Exp $
# $NetBSD: vnode_if.src,v 1.9 1996/02/09 14:45:38 mycroft Exp $
#
# Copyright (c) 1992, 1993
-/* $NetBSD: __main.c,v 1.3 1994/10/26 06:42:13 cgd Exp $ */
+/* $OpenBSD: __main.c,v 1.2 1996/04/19 16:09:17 niklas Exp $ */
+/* $NetBSD: __main.c,v 1.4 1996/03/14 18:52:03 christos Exp $ */
/*
* Copyright (c) 1993 Christopher G. Demetriou
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <sys/types.h>
+
+void __main __P((void));
+
+void
__main()
{
}
-# $NetBSD: Makefile.inc,v 1.7 1995/10/07 09:52:48 mycroft Exp $
+# $OpenBSD: Makefile.inc,v 1.3 1996/04/19 16:09:44 niklas Exp $
+# $NetBSD: Makefile.inc,v 1.9 1996/03/11 05:32:00 scottr Exp $
SRCS+= __main.c imax.c imin.c lmax.c lmin.c max.c min.c ulmax.c ulmin.c \
bcmp.S ffs.S memset.S strcat.S strcmp.S strcpy.S strlen.S strncmp.c \
-/* $NetBSD: memset.c,v 1.2 1994/10/26 06:40:00 cgd Exp $ */
+/* $OpenBSD: memset.c,v 1.2 1996/04/19 16:09:46 niklas Exp $ */
+/* $NetBSD: memset.c,v 1.4 1996/03/11 05:46:51 scottr Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
#ifdef notdef
static char *sccsid = "@(#)memset.c 5.6 (Berkeley) 1/26/91";
#endif
-static char *rcsid = "$NetBSD: memset.c,v 1.2 1994/10/26 06:40:00 cgd Exp $";
+static char *rcsid = "$NetBSD: memset.c,v 1.4 1996/03/11 05:46:51 scottr Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
+/* $OpenBSD: bcmp.c,v 1.2 1996/04/19 16:09:19 niklas Exp $ */
+
/*
* Copyright (c) 1987 Regents of the University of California.
* All rights reserved.
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)bcmp.c 5.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id: bcmp.c,v 1.1.1.1 1995/10/18 08:52:49 deraadt Exp $";
+static char *rcsid = "$OpenBSD: bcmp.c,v 1.2 1996/04/19 16:09:19 niklas Exp $";
#endif /* LIBC_SCCS and not lint */
#include <string.h>
+#include <lib/libkern/libkern.h>
/*
* bcmp -- vax cmpc3 instruction
*/
+int
bcmp(b1, b2, length)
const void *b1, *b2;
register size_t length;
-/* $NetBSD: imax.c,v 1.2 1994/10/26 06:42:24 cgd Exp $ */
+/* $OpenBSD: imax.c,v 1.2 1996/04/19 16:09:20 niklas Exp $ */
+/* $NetBSD: imax.c,v 1.3 1996/03/14 18:52:06 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1991 Regents of the University of California.
* @(#)subr_xxx.c 7.10 (Berkeley) 4/20/91
*/
+#define LIBKERN_INLINE
+#include <lib/libkern/libkern.h>
+
int
imax(a, b)
int a, b;
-/* $NetBSD: imin.c,v 1.2 1994/10/26 06:42:25 cgd Exp $ */
+/* $OpenBSD: imin.c,v 1.2 1996/04/19 16:09:22 niklas Exp $ */
+/* $NetBSD: imin.c,v 1.3 1996/03/14 18:52:07 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1991 Regents of the University of California.
* @(#)subr_xxx.c 7.10 (Berkeley) 4/20/91
*/
+#define LIBKERN_INLINE
+#include <lib/libkern/libkern.h>
+
int
imin(a, b)
int a, b;
-/* $OpenBSD: libkern.h,v 1.2 1996/02/29 13:27:49 niklas Exp $ */
-/* $NetBSD: libkern.h,v 1.6 1996/02/13 23:48:26 christos Exp $ */
+/* $OpenBSD: libkern.h,v 1.3 1996/04/19 16:09:23 niklas Exp $ */
+/* $NetBSD: libkern.h,v 1.7 1996/03/14 18:52:08 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
#include <sys/types.h>
-static __inline int imax __P((int, int));
-static __inline int imin __P((int, int));
-static __inline u_int max __P((u_int, u_int));
-static __inline u_int min __P((u_int, u_int));
-static __inline long lmax __P((long, long));
-static __inline long lmin __P((long, long));
-static __inline u_long ulmax __P((u_long, u_long));
-static __inline u_long ulmin __P((u_long, u_long));
-static __inline int abs __P((int));
+#ifndef LIBKERN_INLINE
+#define LIBKERN_INLINE static __inline
+#define LIBKERN_BODY
+#endif
-static __inline int
+
+LIBKERN_INLINE int imax __P((int, int));
+LIBKERN_INLINE int imin __P((int, int));
+LIBKERN_INLINE u_int max __P((u_int, u_int));
+LIBKERN_INLINE u_int min __P((u_int, u_int));
+LIBKERN_INLINE long lmax __P((long, long));
+LIBKERN_INLINE long lmin __P((long, long));
+LIBKERN_INLINE u_long ulmax __P((u_long, u_long));
+LIBKERN_INLINE u_long ulmin __P((u_long, u_long));
+LIBKERN_INLINE int abs __P((int));
+
+#ifdef LIBKERN_BODY
+LIBKERN_INLINE int
imax(a, b)
int a, b;
{
return (a > b ? a : b);
}
-static __inline int
+LIBKERN_INLINE int
imin(a, b)
int a, b;
{
return (a < b ? a : b);
}
-static __inline long
+LIBKERN_INLINE long
lmax(a, b)
long a, b;
{
return (a > b ? a : b);
}
-static __inline long
+LIBKERN_INLINE long
lmin(a, b)
long a, b;
{
return (a < b ? a : b);
}
-static __inline u_int
+LIBKERN_INLINE u_int
max(a, b)
u_int a, b;
{
return (a > b ? a : b);
}
-static __inline u_int
+LIBKERN_INLINE u_int
min(a, b)
u_int a, b;
{
return (a < b ? a : b);
}
-static __inline u_long
+LIBKERN_INLINE u_long
ulmax(a, b)
u_long a, b;
{
return (a > b ? a : b);
}
-static __inline u_long
+LIBKERN_INLINE u_long
ulmin(a, b)
u_long a, b;
{
return (a < b ? a : b);
}
-static __inline int
+LIBKERN_INLINE int
abs(j)
int j;
{
return(j < 0 ? -j : j);
}
+#endif
/* Prototypes for non-quad routines. */
int bcmp __P((const void *, const void *, size_t));
u_long random __P((void));
char *rindex __P((const char *, int));
int scanc __P((u_int, u_char *, u_char *, int));
-int skpc __P((int, int, char *));
+int skpc __P((int, size_t, u_char *));
size_t strlen __P((const char *));
char *strcat __P((char *, const char *));
char *strcpy __P((char *, const char *));
-/* $NetBSD: lmax.c,v 1.2 1994/10/26 06:42:27 cgd Exp $ */
+/* $OpenBSD: lmax.c,v 1.2 1996/04/19 16:09:25 niklas Exp $ */
+/* $NetBSD: lmax.c,v 1.3 1996/03/14 18:52:09 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1991 Regents of the University of California.
* @(#)subr_xxx.c 7.10 (Berkeley) 4/20/91
*/
+#define LIBKERN_INLINE
+#include <lib/libkern/libkern.h>
+
long
lmax(a, b)
long a, b;
-/* $NetBSD: lmin.c,v 1.2 1994/10/26 06:42:28 cgd Exp $ */
+/* $OpenBSD: lmin.c,v 1.2 1996/04/19 16:09:27 niklas Exp $ */
+/* $NetBSD: lmin.c,v 1.3 1996/03/14 18:52:10 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1991 Regents of the University of California.
* @(#)subr_xxx.c 7.10 (Berkeley) 4/20/91
*/
+#define LIBKERN_INLINE
+#include <lib/libkern/libkern.h>
+
long
lmin(a, b)
long a, b;
-/* $NetBSD: max.c,v 1.2 1994/10/26 06:42:31 cgd Exp $ */
+/* $OpenBSD: max.c,v 1.2 1996/04/19 16:09:28 niklas Exp $ */
+/* $NetBSD: max.c,v 1.3 1996/03/14 18:52:12 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1991 Regents of the University of California.
* @(#)subr_xxx.c 7.10 (Berkeley) 4/20/91
*/
+#define LIBKERN_INLINE
+#include <lib/libkern/libkern.h>
+
unsigned int
max(a, b)
unsigned int a, b;
-/* $NetBSD: min.c,v 1.2 1994/10/26 06:42:33 cgd Exp $ */
+/* $OpenBSD: min.c,v 1.2 1996/04/19 16:09:29 niklas Exp $ */
+/* $NetBSD: min.c,v 1.3 1996/03/14 18:52:13 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1991 Regents of the University of California.
* @(#)subr_xxx.c 7.10 (Berkeley) 4/20/91
*/
+#define LIBKERN_INLINE
+#include <lib/libkern/libkern.h>
+
unsigned int
min(a, b)
unsigned int a, b;
-/* $NetBSD: quad.h,v 1.5 1995/10/12 15:13:58 jtc Exp $ */
+/* $OpenBSD: quad.h,v 1.3 1996/04/19 16:09:31 niklas Exp $ */
+/* $NetBSD: quad.h,v 1.6 1996/03/14 18:52:14 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
#else
typedef u_quad_t qshift_t;
#endif
+
+__BEGIN_DECLS
+quad_t __adddi3 __P((quad_t, quad_t));
+quad_t __anddi3 __P((quad_t, quad_t));
+quad_t __ashldi3 __P((quad_t, qshift_t));
+quad_t __ashrdi3 __P((quad_t, qshift_t));
+int __cmpdi2 __P((quad_t, quad_t));
+quad_t __divdi3 __P((quad_t, quad_t));
+quad_t __iordi3 __P((quad_t, quad_t));
+quad_t __lshldi3 __P((quad_t, qshift_t));
+quad_t __lshrdi3 __P((quad_t, qshift_t));
+quad_t __moddi3 __P((quad_t, quad_t));
+quad_t __muldi3 __P((quad_t, quad_t));
+quad_t __negdi2 __P((quad_t));
+quad_t __one_cmpldi2 __P((quad_t));
+quad_t __subdi3 __P((quad_t, quad_t));
+int __ucmpdi2 __P((u_quad_t, u_quad_t));
+u_quad_t __udivdi3 __P((u_quad_t, u_quad_t));
+u_quad_t __umoddi3 __P((u_quad_t, u_quad_t));
+quad_t __xordi3 __P((quad_t, quad_t));
+__END_DECLS
-/* $NetBSD: scanc.c,v 1.2 1994/10/26 06:42:42 cgd Exp $ */
+/* $OpenBSD: scanc.c,v 1.2 1996/04/19 16:09:33 niklas Exp $ */
+/* $NetBSD: scanc.c,v 1.3 1996/03/14 18:52:16 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
*/
#include <sys/types.h>
+#include <lib/libkern/libkern.h>
int
scanc(size, cp, table, mask)
-/* $NetBSD: skpc.c,v 1.2 1994/10/26 06:42:43 cgd Exp $ */
+/* $OpenBSD: skpc.c,v 1.2 1996/04/19 16:09:36 niklas Exp $ */
+/* $NetBSD: skpc.c,v 1.3 1996/03/14 18:52:18 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
*/
#include <sys/types.h>
+#include <lib/libkern/libkern.h>
int
skpc(mask, size, cp)
register int mask;
- u_int size;
+ size_t size;
register u_char *cp;
{
register u_char *end = &cp[size];
- while (cp < end && *cp == mask)
+ while (cp < end && *cp == (u_char) mask)
cp++;
return (end - cp);
}
+/* $OpenBSD: strcat.c,v 1.2 1996/04/19 16:09:37 niklas Exp $ */
+
/*
* Copyright (c) 1988 Regents of the University of California.
* All rights reserved.
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)strcat.c 5.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id: strcat.c,v 1.1.1.1 1995/10/18 08:52:50 deraadt Exp $";
+static char *rcsid = "$OpenBSD: strcat.c,v 1.2 1996/04/19 16:09:37 niklas Exp $";
#endif /* LIBC_SCCS and not lint */
#include <string.h>
char *save = s;
for (; *s; ++s);
- while (*s++ = *append++);
+ while ((*s++ = *append++) != '\0');
return(save);
}
+/* $OpenBSD: strcpy.c,v 1.2 1996/04/19 16:09:39 niklas Exp $ */
+
/*
* Copyright (c) 1988 Regents of the University of California.
* All rights reserved.
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)strcpy.c 5.7 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id: strcpy.c,v 1.1.1.1 1995/10/18 08:52:50 deraadt Exp $";
+static char *rcsid = "$OpenBSD: strcpy.c,v 1.2 1996/04/19 16:09:39 niklas Exp $";
#endif /* LIBC_SCCS and not lint */
#include <string.h>
{
char *save = to;
- for (; *to = *from; ++from, ++to);
+ for (; (*to = *from) != '\0'; ++from, ++to);
return(save);
}
-/* $NetBSD: ulmax.c,v 1.2 1994/10/26 06:42:52 cgd Exp $ */
+/* $OpenBSD: ulmax.c,v 1.2 1996/04/19 16:09:40 niklas Exp $ */
+/* $NetBSD: ulmax.c,v 1.3 1996/03/14 18:52:23 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1991 Regents of the University of California.
* @(#)subr_xxx.c 7.10 (Berkeley) 4/20/91
*/
+#define LIBKERN_INLINE
+#include <lib/libkern/libkern.h>
+
unsigned long
ulmax(a, b)
unsigned long a, b;
-/* $NetBSD: ulmin.c,v 1.2 1994/10/26 06:42:53 cgd Exp $ */
+/* $OpenBSD: ulmin.c,v 1.2 1996/04/19 16:09:41 niklas Exp $ */
+/* $NetBSD: ulmin.c,v 1.3 1996/03/14 18:52:25 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1991 Regents of the University of California.
* @(#)subr_xxx.c 7.10 (Berkeley) 4/20/91
*/
+#define LIBKERN_INLINE
+#include <lib/libkern/libkern.h>
+
unsigned long
ulmin(a, b)
unsigned long a, b;
-/* $NetBSD: bootparam.c,v 1.6 1995/12/08 04:10:28 gwr Exp $ */
+/* $OpenBSD: bootparam.c,v 1.3 1996/04/19 16:09:49 niklas Exp $ */
+/* $NetBSD: bootparam.c,v 1.7 1996/02/26 23:05:14 gwr Exp $ */
/*
* Copyright (c) 1995 Gordon W. Ross
#include <netinet/in.h>
#include <netinet/in_systm.h>
-#include <nfs/rpcv2.h>
-
#include <string.h>
+#include "rpcv2.h"
+
#include "stand.h"
#include "net.h"
#include "netif.h"
-/* $NetBSD: nfs.c,v 1.12 1995/09/23 03:36:08 gwr Exp $ */
+/* $OpenBSD: nfs.c,v 1.2 1996/04/19 16:09:50 niklas Exp $ */
+/* $NetBSD: nfs.c,v 1.14 1996/02/26 23:05:21 gwr Exp $ */
/*-
* Copyright (c) 1993 John Brezak
#include <netinet/in.h>
#include <netinet/in_systm.h>
-#include <nfs/rpcv2.h>
-#include <nfs/nfsv2.h>
-#include <nfs/xdr_subs.h>
+#include "rpcv2.h"
+#include "nfsv2.h"
#include "stand.h"
#include "net.h"
repl = &rdata.d;
bcopy(d->fh, args->fh, NFS_FHSIZE);
- args->off = txdr_unsigned(off);
+ args->off = htonl((n_long)off);
if (len > NFSREAD_SIZE)
len = NFSREAD_SIZE;
- args->len = txdr_unsigned(len);
- args->xxx = txdr_unsigned(0);
+ args->len = htonl((n_long)len);
+ args->xxx = htonl((n_long)0);
hlen = sizeof(*repl) - NFSREAD_SIZE;
cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_READ,
--- /dev/null
+/* $OpenBSD: nfsv2.h,v 1.1 1996/04/19 16:09:52 niklas Exp $ */
+/* $NetBSD: nfsv2.h,v 1.2 1996/02/26 23:05:23 gwr Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)nfsv2.h 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * nfs definitions as per the version 2 specs
+ */
+
+/*
+ * Constants as defined in the Sun NFS Version 2 spec.
+ * "NFS: Network File System Protocol Specification" RFC1094
+ */
+
+#define NFS_PORT 2049
+#define NFS_PROG 100003
+#define NFS_VER2 2
+#define NFS_MAXDGRAMDATA 8192
+#define NFS_MAXDATA 32768
+#define NFS_MAXPATHLEN 1024
+#define NFS_MAXNAMLEN 255
+#define NFS_FHSIZE 32
+#define NFS_MAXPKTHDR 404
+#define NFS_MAXPACKET (NFS_MAXPKTHDR+NFS_MAXDATA)
+#define NFS_MINPACKET 20
+#define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */
+
+/* Stat numbers for rpc returns */
+#define NFS_OK 0
+#define NFSERR_PERM 1
+#define NFSERR_NOENT 2
+#define NFSERR_IO 5
+#define NFSERR_NXIO 6
+#define NFSERR_ACCES 13
+#define NFSERR_EXIST 17
+#define NFSERR_NODEV 19
+#define NFSERR_NOTDIR 20
+#define NFSERR_ISDIR 21
+#define NFSERR_FBIG 27
+#define NFSERR_NOSPC 28
+#define NFSERR_ROFS 30
+#define NFSERR_NAMETOL 63
+#define NFSERR_NOTEMPTY 66
+#define NFSERR_DQUOT 69
+#define NFSERR_STALE 70
+#define NFSERR_WFLUSH 99
+
+/* Sizes in bytes of various nfs rpc components */
+#define NFSX_FH 32
+#define NFSX_UNSIGNED 4
+#define NFSX_FATTR 68
+#define NFSX_SATTR 32
+#define NFSX_STATFS 20
+#define NFSX_COOKIE 4
+
+/* nfs rpc procedure numbers */
+#define NFSPROC_NULL 0
+#define NFSPROC_GETATTR 1
+#define NFSPROC_SETATTR 2
+#define NFSPROC_NOOP 3
+#define NFSPROC_ROOT NFSPROC_NOOP /* Obsolete */
+#define NFSPROC_LOOKUP 4
+#define NFSPROC_READLINK 5
+#define NFSPROC_READ 6
+#define NFSPROC_WRITECACHE NFSPROC_NOOP /* Obsolete */
+#define NFSPROC_WRITE 8
+#define NFSPROC_CREATE 9
+#define NFSPROC_REMOVE 10
+#define NFSPROC_RENAME 11
+#define NFSPROC_LINK 12
+#define NFSPROC_SYMLINK 13
+#define NFSPROC_MKDIR 14
+#define NFSPROC_RMDIR 15
+#define NFSPROC_READDIR 16
+#define NFSPROC_STATFS 17
+
+#define NFS_NPROCS 18
+
+
+/* File types */
+typedef enum {
+ NFNON=0,
+ NFREG=1,
+ NFDIR=2,
+ NFBLK=3,
+ NFCHR=4,
+ NFLNK=5
+} nfstype;
+
+/* Structs for common parts of the rpc's */
+struct nfsv2_time {
+ n_long nfs_sec;
+ n_long nfs_usec;
+};
+
+/*
+ * File attributes and setable attributes.
+ */
+struct nfsv2_fattr {
+ n_long fa_type;
+ n_long fa_mode;
+ n_long fa_nlink;
+ n_long fa_uid;
+ n_long fa_gid;
+ n_long fa_size;
+ n_long fa_blocksize;
+ n_long fa_rdev;
+ n_long fa_blocks;
+ n_long fa_fsid;
+ n_long fa_fileid;
+ struct nfsv2_time fa_atime;
+ struct nfsv2_time fa_mtime;
+ struct nfsv2_time fa_ctime;
+};
+
+struct nfsv2_sattr {
+ n_long sa_mode;
+ n_long sa_uid;
+ n_long sa_gid;
+ n_long sa_size;
+ struct nfsv2_time sa_atime;
+ struct nfsv2_time sa_mtime;
+};
+
+struct nfsv2_statfs {
+ n_long sf_tsize;
+ n_long sf_bsize;
+ n_long sf_blocks;
+ n_long sf_bfree;
+ n_long sf_bavail;
+};
-/* $NetBSD: rpc.c,v 1.10 1995/09/23 03:36:11 gwr Exp $ */
+/* $OpenBSD: rpc.c,v 1.2 1996/04/19 16:09:53 niklas Exp $ */
+/* $NetBSD: rpc.c,v 1.12 1996/02/26 23:05:26 gwr Exp $ */
/*
* Copyright (c) 1992 Regents of the University of California.
#include <netinet/in.h>
#include <netinet/in_systm.h>
-#include <nfs/rpcv2.h>
-#include <nfs/nfsv2.h>
-#include <nfs/xdr_subs.h>
-
#include <string.h>
+#include "rpcv2.h"
+
#include "stand.h"
#include "net.h"
#include "netif.h"
--- /dev/null
+/* $OpenBSD: rpcv2.h,v 1.1 1996/04/19 16:09:55 niklas Exp $ */
+/* $NetBSD: rpcv2.h,v 1.1 1996/02/26 23:05:32 gwr Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)rpcv2.h 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * Definitions for Sun RPC Version 2, from
+ * "RPC: Remote Procedure Call Protocol Specification" RFC1057
+ */
+
+/* Version # */
+#define RPC_VER2 2
+
+/* Authentication */
+#define RPCAUTH_NULL 0
+#define RPCAUTH_UNIX 1
+#define RPCAUTH_SHORT 2
+#define RPCAUTH_MAXSIZ 400
+#define RPCAUTH_UNIXGIDS 16
+
+/* Rpc Constants */
+#define RPC_CALL 0
+#define RPC_REPLY 1
+#define RPC_MSGACCEPTED 0
+#define RPC_MSGDENIED 1
+#define RPC_PROGUNAVAIL 1
+#define RPC_PROGMISMATCH 2
+#define RPC_PROCUNAVAIL 3
+#define RPC_GARBAGE 4 /* I like this one */
+#define RPC_MISMATCH 0
+#define RPC_AUTHERR 1
+
+/* Authentication failures */
+#define AUTH_BADCRED 1
+#define AUTH_REJECTCRED 2
+#define AUTH_BADVERF 3
+#define AUTH_REJECTVERF 4
+#define AUTH_TOOWEAK 5 /* Give em wheaties */
+
+/* Sizes of rpc header parts */
+#define RPC_SIZ 24
+#define RPC_REPLYSIZ 28
+
+/* RPC Prog definitions */
+#define RPCPROG_MNT 100005
+#define RPCMNT_VER1 1
+#define RPCMNT_MOUNT 1
+#define RPCMNT_DUMP 2
+#define RPCMNT_UMOUNT 3
+#define RPCMNT_UMNTALL 4
+#define RPCMNT_EXPORT 5
+#define RPCMNT_NAMELEN 255
+#define RPCMNT_PATHLEN 1024
+#define RPCPROG_NFS 100003
-/* $OpenBSD: umap_subr.c,v 1.6 1996/03/25 18:02:56 mickey Exp $ */
-/* $NetBSD: umap_subr.c,v 1.7 1996/02/09 22:41:02 christos Exp $ */
+/* $OpenBSD: umap_subr.c,v 1.7 1996/04/19 16:09:57 niklas Exp $ */
+/* $NetBSD: umap_subr.c,v 1.8 1996/03/05 02:35:39 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
-/* $OpenBSD: msdosfs_lookup.c,v 1.3 1996/02/29 10:46:55 niklas Exp $ */
-/* $NetBSD: msdosfs_lookup.c,v 1.25 1996/02/09 19:13:47 christos Exp $ */
+/* $OpenBSD: msdosfs_lookup.c,v 1.4 1996/04/19 16:10:00 niklas Exp $ */
+/* $NetBSD: msdosfs_lookup.c,v 1.26 1996/03/07 13:30:46 ws Exp $ */
/*-
* Copyright (C) 1994, 1995 Wolfgang Solfrank.
dep->de_refcnt--;
do {
error = pcbmap(pdep, de_cluster(pmp, offset), &bn, 0, &blsize);
- if (error);
+ if (error)
return error;
error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
if (error) {
-/* $OpenBSD: msdosfs_vnops.c,v 1.3 1996/02/29 10:46:59 niklas Exp $ */
-/* $NetBSD: msdosfs_vnops.c,v 1.46 1996/02/09 19:13:53 christos Exp $ */
+/* $OpenBSD: msdosfs_vnops.c,v 1.4 1996/04/19 16:10:03 niklas Exp $ */
+/* $NetBSD: msdosfs_vnops.c,v 1.47 1996/03/08 18:13:10 scottr Exp $ */
/*-
* Copyright (C) 1994, 1995 Wolfgang Solfrank.
strcpy(dirbuf.d_name, "..");
break;
}
- dirbuf.d_reclen = DIRSIZ(&dirbuf);
+ dirbuf.d_reclen = DIRENT_SIZE(&dirbuf);
if (uio->uio_resid < dirbuf.d_reclen)
goto out;
error = uiomove((caddr_t) &dirbuf,
else
dirbuf.d_name[dirbuf.d_namlen] = 0;
chksum = -1;
- dirbuf.d_reclen = DIRSIZ(&dirbuf);
+ dirbuf.d_reclen = DIRENT_SIZE(&dirbuf);
if (uio->uio_resid < dirbuf.d_reclen) {
brelse(bp);
goto out;
-/* $OpenBSD: pk_extern.h,v 1.1 1996/03/04 07:36:40 niklas Exp $ */
+/* $OpenBSD: pk_extern.h,v 1.2 1996/04/19 16:10:07 niklas Exp $ */
/* $NetBSD: pk_extern.h,v 1.1 1996/02/13 22:05:17 christos Exp $ */
/*
void pk_parse_facilities __P((octet *, struct sockaddr_x25 *));
/* pk_llcsubr.c */
-int cons_rtrequest __P((int, struct rtentry *, struct sockaddr *));
+void cons_rtrequest __P((int, struct rtentry *, struct sockaddr *));
struct rtentry *npaidb_enter __P((struct sockaddr_dl *, struct sockaddr *,
struct rtentry *, struct llc_linkcb *));
struct rtentry *npaidb_enrich __P((short, caddr_t, struct sockaddr_dl *));
-/* $OpenBSD: pk_llcsubr.c,v 1.2 1996/03/04 07:36:42 niklas Exp $ */
+/* $OpenBSD: pk_llcsubr.c,v 1.3 1996/04/19 16:10:09 niklas Exp $ */
/* $NetBSD: pk_llcsubr.c,v 1.4 1996/02/13 22:05:26 christos Exp $ */
/*
#define XIFA(rt) ((struct x25_ifaddr *)((rt)->rt_ifa))
#define SA(s) ((struct sockaddr *)s)
-int
+static int cons_rtrequest_internal __P((int, struct rtentry *,
+ struct sockaddr *));
+
+/*
+ * ifa_rtrequest currently does not check the error from the rtrequest call
+ * so we use a void version of the cons_rtrequest routine.
+ */
+void
cons_rtrequest(cmd, rt, dst)
+ int cmd;
+ struct rtentry *rt;
+ struct sockaddr *dst;
+{
+ cons_rtrequest_internal(cmd, rt, dst);
+}
+
+
+static int
+cons_rtrequest_internal(cmd, rt, dst)
int cmd;
struct rtentry *rt;
struct sockaddr *dst;
-/* $NetBSD: ch.c,v 1.14 1995/01/16 21:31:38 mycroft Exp $ */
+/* $OpenBSD: ch.c,v 1.3 1996/04/19 16:10:12 niklas Exp $ */
+/* $NetBSD: ch.c,v 1.16 1996/03/05 00:15:09 thorpej Exp $ */
/*
* Copyright (c) 1994 Charles Hannum. All rights reserved.
* the drive. We cannot use interrupts yet, so the
* request must specify this.
*/
+ printf("\n");
+ printf("%s: ", ch->sc_dev.dv_xname);
if (ch_mode_sense(ch, SCSI_AUTOCONF) != 0)
- printf(": offline\n");
+ printf("offline\n");
else
- printf(": %d slot(s), %d drive(s), %d arm(s), %d i/e-slot(s)\n",
+ printf("%d slot(s), %d drive(s), %d arm(s), %d i/e-slot(s)\n",
ch->slots, ch->drives, ch->chms, ch->imexs);
}
+/* $OpenBSD: scsi_scanner.h,v 1.2 1996/04/19 16:10:13 niklas Exp $ */
+
+/*
+ * Copyright (c) 1995 Kenneth Stailey. All rights reserved.
+ * modified for configurable scanner support by Joachim Koenig
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Kenneth Stailey.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * SCSI scanner interface description
+ */
+
+#ifndef _SCSI_SCANNER_H_
+#define _SCSI_SCANNER_H_
+
+/* SCSI scanner commands */
+#define GET_IMAGE_STATUS 0x0f
+#define READ_BIG 0x28
+#define WRITE_BIG 0x2a
+#define OBJECT_POSITION 0x31
+#define GET_BUFFER_STATUS 0x34
+
+/* generic scanner command formats */
+
+struct scsi_rw_scanner {
+#define READ 0x08
+#define WRITE 0x0a
+ u_char opcode;
+ u_char byte2;
+#define SRW_FIXED 0x01
+ u_char len[3];
+ u_char control;
+};
+
+struct scsi_start_stop {
+ u_char opcode;
+ u_char byte2;
+ u_char unused[2];
+ u_char how;
+#define SSS_STOP 0x00
+#define SSS_START 0x01
+#define SSS_LOEJ 0x02
+ u_char control;
+};
+
+struct scsi_set_window {
+#define SET_WINDOW 0x24 /* set params of image area and windows */
+#define GET_WINDOW 0x25
+ u_char opcode;
+ u_char byte2;
+ u_char reserved[4];
+ u_char len[3];
+ u_char control;
+};
+
+struct scsi_window_header {
+ u_char reserved[6];
+ u_char len[2]; /* MSB-LSB */
+};
+
+struct scsi_window_data {
+ u_char window_id; /* must be zero */
+ u_char res1:7;
+ u_char auto_bit:1;
+ u_char x_res[2];
+ u_char y_res[2];
+ u_char x_org[4];
+ u_char y_org[4];
+ u_char width[4];
+ u_char length[4];
+ u_char brightness;
+ u_char threshold;
+ u_char contrast;
+ u_char image_comp; /* image composition (data type) */
+ u_char bits_per_pixel;
+ u_char halftone_pattern[2];
+ u_char rif:1; /* reverse image format (mono negative) */
+ u_char res2:4;
+ u_char pad_type:3;
+ u_char bit_ordering[2];
+ u_char compression_type;
+ u_char compression_arg;
+ u_char res3[6];
+};
+
+/* mustek scsi commands */
+
+#define MUSTEK_SET_WINDOW 0x04 /* set image area and windows */
+#define MUSTEK_ADF 0x10 /* ADF and backtracking selection */
+#define MUSTEK_LUT 0x55 /* look up table download */
+
+#endif /* _SCSI_SCANNER_H_ */
/*
* Copyright (c) 1995 Kenneth Stailey. All rights reserved.
* modified for configurable scanner support by Joachim Koenig
-/* $NetBSD: scsiconf.c,v 1.49 1996/02/18 20:32:43 mycroft Exp $ */
+/* $OpenBSD: scsiconf.c,v 1.7 1996/04/19 16:10:15 niklas Exp $ */
+/* $NetBSD: scsiconf.c,v 1.52 1996/03/05 01:45:42 thorpej Exp $ */
/*
* Copyright (c) 1994 Charles Hannum. All rights reserved.
sizeof(struct scsibus_softc)
};
+int scsibusprint __P((void *, char *));
+
int
scsibusmatch(parent, match, aux)
struct device *parent;
{{T_CDROM, T_REMOV,
"TEXEL ", "CD-ROM DM-XX24 K", "1.10"}, SDEV_NOLUNS},
+ {{T_DIRECT, T_FIXED,
+ "DEC ", "RZ55 (C) DEC", ""}, SDEV_AUTOSAVE},
{{T_DIRECT, T_FIXED,
"EMULEX ", "MD21/S2 ESDI", "A00"}, SDEV_FORCELUNS},
{{T_DIRECT, T_FIXED,
"MAXTOR ", "LXT-213S ", ""}, SDEV_NOLUNS},
{{T_DIRECT, T_FIXED,
"MAXTOR ", "LXT-213S SUN0207", ""}, SDEV_NOLUNS},
+ {{T_DIRECT, T_FIXED,
+ "MAXTOR ", "LXT-200S ", ""}, SDEV_NOLUNS},
{{T_DIRECT, T_FIXED,
"MST ", "SnapLink ", ""}, SDEV_NOLUNS},
{{T_DIRECT, T_FIXED,
"WangDAT ", "Model 3200 ", "02.2"}, SDEV_NOSYNCWIDE},
};
+/*
+ * Print out autoconfiguration information for a subdevice.
+ *
+ * This is a slight abuse of 'standard' autoconfiguration semantics,
+ * because 'print' functions don't normally print the colon and
+ * device information. However, in this case that's better than
+ * either printing redundant information before the attach message,
+ * or having the device driver call a special function to print out
+ * the standard device information.
+ */
+int
+scsibusprint(aux, pnp)
+ void *aux;
+ char *pnp;
+{
+ struct scsibus_attach_args *sa = aux;
+ struct scsi_inquiry_data *inqbuf;
+ u_int8_t type;
+ boolean removable;
+ char *dtype, *qtype;
+ char vendor[33], product[65], revision[17];
+ int target, lun;
+
+ if (pnp != NULL)
+ printf("%s", pnp);
+
+ inqbuf = sa->sa_inqbuf;
+
+ target = sa->sa_sc_link->target;
+ lun = sa->sa_sc_link->lun;
+
+ type = inqbuf->device & SID_TYPE;
+ removable = inqbuf->dev_qual2 & SID_REMOVABLE ? 1 : 0;
+
+ /*
+ * Figure out basic device type and qualifier.
+ */
+ dtype = 0;
+ switch (inqbuf->device & SID_QUAL) {
+ case SID_QUAL_LU_OK:
+ qtype = "";
+ break;
+
+ case SID_QUAL_LU_OFFLINE:
+ qtype = " offline";
+ break;
+
+ case SID_QUAL_RSVD:
+ case SID_QUAL_BAD_LU:
+ panic("scsibusprint: impossible qualifier");
+
+ default:
+ qtype = "";
+ dtype = "vendor-unique";
+ break;
+ }
+ if (dtype == 0) {
+ switch (type) {
+ case T_DIRECT:
+ dtype = "direct";
+ break;
+ case T_SEQUENTIAL:
+ dtype = "sequential";
+ break;
+ case T_PRINTER:
+ dtype = "printer";
+ break;
+ case T_PROCESSOR:
+ dtype = "processor";
+ break;
+ case T_CDROM:
+ dtype = "cdrom";
+ break;
+ case T_WORM:
+ dtype = "worm";
+ break;
+ case T_SCANNER:
+ dtype = "scanner";
+ break;
+ case T_OPTICAL:
+ dtype = "optical";
+ break;
+ case T_CHANGER:
+ dtype = "changer";
+ break;
+ case T_COMM:
+ dtype = "communication";
+ break;
+ case T_NODEVICE:
+ panic("scsibusprint: impossible device type");
+ default:
+ dtype = "unknown";
+ break;
+ }
+ }
+
+ scsi_strvis(vendor, inqbuf->vendor, 8);
+ scsi_strvis(product, inqbuf->product, 16);
+ scsi_strvis(revision, inqbuf->revision, 4);
+
+ printf(" targ %d lun %d: <%s, %s, %s> SCSI%d %d/%s %s%s",
+ target, lun, vendor, product, revision,
+ inqbuf->version & SID_ANSII, type, dtype,
+ removable ? "removable" : "fixed", qtype);
+
+ return (UNCONF);
+}
+
/*
* given a target and lu, ask the device what
* it is, and find the correct driver table
struct scsi_link *sc_link;
static struct scsi_inquiry_data inqbuf;
struct scsi_quirk_inquiry_pattern *finger;
- int priority;
- u_int8_t type;
- boolean removable;
- char *dtype, *qtype;
- char vendor[33], product[65], revision[17];
+ int checkdtype, priority;
struct scsibus_attach_args sa;
struct cfdata *cf;
/*
* note what BASIC type of device it is
*/
- type = inqbuf.device & SID_TYPE;
- removable = inqbuf.dev_qual2 & SID_REMOVABLE ? 1 : 0;
-
- if (removable)
+ if ((inqbuf.dev_qual2 & SID_REMOVABLE) != 0)
sc_link->flags |= SDEV_REMOVABLE;
/*
* Any device qualifier that has the top bit set (qualifier&4 != 0)
* is vendor specific and won't match in this switch.
+ * All we do here is throw out bad/negative responses.
*/
- dtype = 0;
+ checkdtype = 0;
switch (inqbuf.device & SID_QUAL) {
case SID_QUAL_LU_OK:
- qtype = "";
- break;
-
case SID_QUAL_LU_OFFLINE:
- qtype = " offline";
+ checkdtype = 1;
break;
case SID_QUAL_RSVD:
goto bad;
default:
- qtype = "";
- dtype = "vendor-unique";
break;
}
- if (dtype == 0) {
- switch (type) {
+ if (checkdtype) {
+ switch (inqbuf.device & SID_TYPE) {
case T_DIRECT:
- dtype = "direct";
- break;
case T_SEQUENTIAL:
- dtype = "sequential";
- break;
case T_PRINTER:
- dtype = "printer";
- break;
case T_PROCESSOR:
- dtype = "processor";
- break;
case T_CDROM:
- dtype = "cdrom";
- break;
case T_WORM:
- dtype = "worm";
- break;
case T_SCANNER:
- dtype = "scanner";
- break;
case T_OPTICAL:
- dtype = "optical";
- break;
case T_CHANGER:
- dtype = "changer";
- break;
case T_COMM:
- dtype = "communication";
+ default:
break;
case T_NODEVICE:
goto bad;
- default:
- dtype = "unknown";
- break;
}
}
- scsi_strvis(vendor, inqbuf.vendor, 8);
- scsi_strvis(product, inqbuf.product, 16);
- scsi_strvis(revision, inqbuf.revision, 4);
-
- printf("%s targ %d lun %d: <%s, %s, %s> SCSI%d %d/%s %s%s\n",
- ((struct device *)sc_link->adapter_softc)->dv_xname,
- target, lun, vendor, product, revision,
- inqbuf.version & SID_ANSII, type, dtype,
- removable ? "removable" : "fixed", qtype);
-
sa.sa_sc_link = sc_link;
sa.sa_inqbuf = &inqbuf;
if ((cf = config_search(scsibussubmatch, (struct device *)scsi, &sa)) != 0) {
scsi->sc_link[target][lun] = sc_link;
- config_attach((struct device *)scsi, cf, &sa, NULL);
- } else
+ config_attach((struct device *)scsi, cf, &sa, scsibusprint);
+ } else {
+ scsibusprint(&sa, scsi->sc_dev.dv_xname);
+ printf(" not configured\n");
goto bad;
+ }
return;
-/* $NetBSD: sd.c,v 1.87 1996/02/14 21:47:40 christos Exp $ */
+/* $OpenBSD: sd.c,v 1.6 1996/04/19 16:10:17 niklas Exp $ */
+/* $NetBSD: sd.c,v 1.88 1996/03/05 00:15:15 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
* the drive. We cannot use interrupts yet, so the
* request must specify this.
*/
+ printf("\n");
+ printf("%s: ", sd->sc_dev.dv_xname);
if (scsi_start(sd->sc_link, SSS_START,
SCSI_AUTOCONF | SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE | SCSI_SILENT) ||
sd_get_parms(sd, SCSI_AUTOCONF) != 0)
- printf(": drive offline\n");
+ printf("drive offline\n");
else
- printf(": %dMB, %d cyl, %d head, %d sec, %d bytes/sec\n",
+ printf("%dMB, %d cyl, %d head, %d sec, %d bytes/sec\n",
dp->disksize / (1048576 / dp->blksize), dp->cyls,
dp->heads, dp->sectors, dp->blksize);
}
+/* $OpenBSD: ss.c,v 1.2 1996/04/19 16:10:19 niklas Exp $ */
+/* $NetBSD: ss.c,v 1.7 1996/03/05 00:15:18 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1995 Kenneth Stailey. All rights reserved.
+ * modified for configurable scanner support by Joachim Koenig
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Kenneth Stailey.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/fcntl.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/malloc.h>
+#include <sys/buf.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/device.h>
+#include <sys/conf.h> /* for cdevsw */
+#include <sys/scanio.h>
+
+#include <scsi/scsi_all.h>
+#include <scsi/scsi_scanner.h>
+#include <scsi/scsiconf.h>
+#include <scsi/ssvar.h>
+
+#include <scsi/ss_mustek.h>
+
+#define SSMODE(z) ( minor(z) & 0x03)
+#define SSUNIT(z) ((minor(z) >> 4) )
+
+/*
+ * If the mode is 3 (e.g. minor = 3,7,11,15)
+ * then the device has been openned to set defaults
+ * This mode does NOT ALLOW I/O, only ioctls
+ */
+#define MODE_REWIND 0
+#define MODE_NONREWIND 1
+#define MODE_CONTROL 3
+
+int ssmatch __P((struct device *, void *, void *));
+void ssattach __P((struct device *, struct device *, void *));
+
+struct cfdriver sscd = {
+ NULL, "ss", ssmatch, ssattach, DV_DULL, sizeof(struct ss_softc)
+};
+
+void ssstrategy __P((struct buf *));
+void ssstart __P((void *));
+
+struct scsi_device ss_switch = {
+ NULL,
+ ssstart,
+ NULL,
+ NULL,
+};
+
+struct scsi_inquiry_pattern ss_patterns[] = {
+ {T_SCANNER, T_FIXED,
+ "", "", ""},
+ {T_SCANNER, T_REMOV,
+ "", "", ""},
+ {T_PROCESSOR, T_FIXED,
+ "HP ", "C1750A ", ""},
+ {T_PROCESSOR, T_FIXED,
+ "HP ", "C2500A ", ""},
+};
+
+int
+ssmatch(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct scsibus_attach_args *sa = aux;
+ int priority;
+
+ (void)scsi_inqmatch(sa->sa_inqbuf,
+ (caddr_t)ss_patterns, sizeof(ss_patterns)/sizeof(ss_patterns[0]),
+ sizeof(ss_patterns[0]), &priority);
+ return (priority);
+}
+
+/*
+ * The routine called by the low level scsi routine when it discovers
+ * A device suitable for this driver
+ * If it is a know special, call special attach routine to install
+ * special handlers into the ss_softc structure
+ */
+void
+ssattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct ss_softc *ss = (void *)self;
+ struct scsibus_attach_args *sa = aux;
+ struct scsi_link *sc_link = sa->sa_sc_link;
+
+ SC_DEBUG(sc_link, SDEV_DB2, ("ssattach: "));
+
+ /*
+ * Store information needed to contact our base driver
+ */
+ ss->sc_link = sc_link;
+ sc_link->device = &ss_switch;
+ sc_link->device_softc = ss;
+ sc_link->openings = 1;
+
+ /*
+ * look for non-standard scanners with help of the quirk table
+ * and install functions for special handling
+ */
+ SC_DEBUG(sc_link, SDEV_DB2, ("ssattach:\n"));
+ if (!bcmp(sa->sa_inqbuf->vendor, "MUSTEK ", 8))
+ mustek_attach(ss, sa);
+ if (!bcmp(sa->sa_inqbuf->vendor, "HP ", 8))
+ scanjet_attach(ss, sa);
+ if (ss->special == NULL) {
+ /* XXX add code to restart a SCSI2 scanner, if any */
+ }
+
+ /*
+ * Set up the buf queue for this device
+ */
+ ss->buf_queue.b_active = 0;
+ ss->buf_queue.b_actf = 0;
+ ss->buf_queue.b_actb = &ss->buf_queue.b_actf;
+
+ printf("\n");
+}
+
+/*
+ * open the device.
+ */
+int
+ssopen(dev, flag, mode, p)
+ dev_t dev;
+ int flag;
+ int mode;
+ struct proc *p;
+{
+ int unit;
+ u_int ssmode;
+ int error = 0;
+ struct ss_softc *ss;
+ struct scsi_link *sc_link;
+
+ unit = SSUNIT(dev);
+ if (unit >= sscd.cd_ndevs)
+ return (ENXIO);
+ ss = sscd.cd_devs[unit];
+ if (!ss)
+ return (ENXIO);
+
+ ssmode = SSMODE(dev);
+ sc_link = ss->sc_link;
+
+ SC_DEBUG(sc_link, SDEV_DB1, ("open: dev=0x%x (unit %d (of %d))\n", dev,
+ unit, sscd.cd_ndevs));
+
+ if (sc_link->flags & SDEV_OPEN) {
+ printf("%s: already open\n", ss->sc_dev.dv_xname);
+ return (EBUSY);
+ }
+
+ /*
+ * Catch any unit attention errors.
+ *
+ * SCSI_IGNORE_MEDIA_CHANGE: when you have an ADF, some scanners
+ * consider paper to be a changeable media
+ *
+ */
+ error = scsi_test_unit_ready(sc_link,
+ SCSI_IGNORE_MEDIA_CHANGE | SCSI_IGNORE_ILLEGAL_REQUEST |
+ (ssmode == MODE_CONTROL ? SCSI_IGNORE_NOT_READY : 0));
+ if (error)
+ goto bad;
+
+ sc_link->flags |= SDEV_OPEN; /* unit attn are now errors */
+
+ /*
+ * If the mode is 3 (e.g. minor = 3,7,11,15)
+ * then the device has been opened to set defaults
+ * This mode does NOT ALLOW I/O, only ioctls
+ */
+ if (ssmode == MODE_CONTROL)
+ return (0);
+
+ SC_DEBUG(sc_link, SDEV_DB2, ("open complete\n"));
+ return (0);
+
+bad:
+ sc_link->flags &= ~SDEV_OPEN;
+ return (error);
+}
+
+/*
+ * close the device.. only called if we are the LAST
+ * occurence of an open device
+ */
+int
+ssclose(dev)
+ dev_t dev;
+{
+ struct ss_softc *ss = sscd.cd_devs[SSUNIT(dev)];
+ int error;
+
+ SC_DEBUG(ss->sc_link, SDEV_DB1, ("closing\n"));
+
+ if (SSMODE(dev) == MODE_REWIND) {
+ if (ss->special->rewind_scanner) {
+ /* call special handler to rewind/abort scan */
+ error = (ss->special->rewind_scanner)(ss);
+ if (error)
+ return (error);
+ } else {
+ /* XXX add code to restart a SCSI2 scanner, if any */
+ }
+ ss->sio.scan_window_size = 0;
+ ss->flags &= ~SSF_TRIGGERED;
+ }
+ ss->sc_link->flags &= ~SDEV_OPEN;
+
+ return (0);
+}
+
+/*
+ * trim the size of the transfer if needed,
+ * called by physio
+ * basically the smaller of our min and the scsi driver's
+ * minphys
+ */
+void
+ssminphys(bp)
+ struct buf *bp;
+{
+ register struct ss_softc *ss = sscd.cd_devs[SSUNIT(bp->b_dev)];
+
+ (ss->sc_link->adapter->scsi_minphys)(bp);
+
+ /*
+ * trim the transfer further for special devices this is
+ * because some scanners only read multiples of a line at a
+ * time, also some cannot disconnect, so the read must be
+ * short enough to happen quickly
+ */
+ if (ss->special->minphys)
+ (ss->special->minphys)(ss, bp);
+}
+
+/*
+ * Do a read on a device for a user process.
+ * Prime scanner at start of read, check uio values, call ssstrategy
+ * via physio for the actual transfer.
+ */
+int
+ssread(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ struct ss_softc *ss = sscd.cd_devs[SSUNIT(dev)];
+ int error;
+
+ /* if the scanner has not yet been started, do it now */
+ if (!(ss->flags & SSF_TRIGGERED)) {
+ if (ss->special->trigger_scanner) {
+ error = (ss->special->trigger_scanner)(ss);
+ if (error)
+ return (error);
+ }
+ ss->flags |= SSF_TRIGGERED;
+ }
+
+ return (physio(ssstrategy, NULL, dev, B_READ, ssminphys, uio));
+}
+
+/*
+ * Actually translate the requested transfer into one the physical
+ * driver can understand The transfer is described by a buf and will
+ * include only one physical transfer.
+ */
+void
+ssstrategy(bp)
+ struct buf *bp;
+{
+ struct ss_softc *ss = sscd.cd_devs[SSUNIT(bp->b_dev)];
+ struct buf *dp;
+ int s;
+
+ SC_DEBUG(ss->sc_link, SDEV_DB1,
+ ("ssstrategy %d bytes @ blk %d\n", bp->b_bcount, bp->b_blkno));
+
+ if (bp->b_bcount > ss->sio.scan_window_size)
+ bp->b_bcount = ss->sio.scan_window_size;
+
+ /*
+ * If it's a null transfer, return immediatly
+ */
+ if (bp->b_bcount == 0)
+ goto done;
+
+ s = splbio();
+
+ /*
+ * Place it in the queue of activities for this scanner
+ * at the end (a bit silly because we only have on user..
+ * (but it could fork()))
+ */
+ dp = &ss->buf_queue;
+ bp->b_actf = NULL;
+ bp->b_actb = dp->b_actb;
+ *dp->b_actb = bp;
+ dp->b_actb = &bp->b_actf;
+
+ /*
+ * Tell the device to get going on the transfer if it's
+ * not doing anything, otherwise just wait for completion
+ * (All a bit silly if we're only allowing 1 open but..)
+ */
+ ssstart(ss);
+
+ splx(s);
+ return;
+bad:
+ bp->b_flags |= B_ERROR;
+done:
+ /*
+ * Correctly set the buf to indicate a completed xfer
+ */
+ bp->b_resid = bp->b_bcount;
+ biodone(bp);
+}
+
+/*
+ * ssstart looks to see if there is a buf waiting for the device
+ * and that the device is not already busy. If both are true,
+ * It dequeues the buf and creates a scsi command to perform the
+ * transfer required. The transfer request will call scsi_done
+ * on completion, which will in turn call this routine again
+ * so that the next queued transfer is performed.
+ * The bufs are queued by the strategy routine (ssstrategy)
+ *
+ * This routine is also called after other non-queued requests
+ * have been made of the scsi driver, to ensure that the queue
+ * continues to be drained.
+ * ssstart() is called at splbio
+ */
+void
+ssstart(v)
+ void *v;
+{
+ struct ss_softc *ss = v;
+ struct scsi_link *sc_link = ss->sc_link;
+ register struct buf *bp, *dp;
+
+ SC_DEBUG(sc_link, SDEV_DB2, ("ssstart "));
+ /*
+ * See if there is a buf to do and we are not already
+ * doing one
+ */
+ while (sc_link->openings > 0) {
+ /* if a special awaits, let it proceed first */
+ if (sc_link->flags & SDEV_WAITING) {
+ sc_link->flags &= ~SDEV_WAITING;
+ wakeup((caddr_t)sc_link);
+ return;
+ }
+
+ /*
+ * See if there is a buf with work for us to do..
+ */
+ dp = &ss->buf_queue;
+ if ((bp = dp->b_actf) == NULL)
+ return;
+ if ((dp = bp->b_actf) != NULL)
+ dp->b_actb = bp->b_actb;
+ else
+ ss->buf_queue.b_actb = bp->b_actb;
+ *bp->b_actb = dp;
+
+ if (ss->special->read) {
+ (ss->special->read)(ss, bp);
+ } else {
+ /* generic scsi2 scanner read */
+ /* XXX add code for SCSI2 scanner read */
+ }
+ }
+}
+
+/*
+ * Perform special action on behalf of the user;
+ * knows about the internals of this device
+ */
+int
+ssioctl(dev, cmd, addr, flag, p)
+ dev_t dev;
+ u_long cmd;
+ caddr_t addr;
+ int flag;
+ struct proc *p;
+{
+ struct ss_softc *ss = sscd.cd_devs[SSUNIT(dev)];
+ int error = 0;
+ int unit;
+ struct scan_io *sio;
+
+ switch (cmd) {
+ case SCIOCGET:
+ if (ss->special->get_params) {
+ /* call special handler */
+ error = (ss->special->get_params)(ss);
+ if (error)
+ return (error);
+ } else {
+ /* XXX add code for SCSI2 scanner, if any */
+ return (EOPNOTSUPP);
+ }
+ bcopy(&ss->sio, addr, sizeof(struct scan_io));
+ break;
+ case SCIOCSET:
+ sio = (struct scan_io *)addr;
+
+ if (ss->special->set_params) {
+ /* call special handler */
+ error = (ss->special->set_params)(ss, sio);
+ if (error)
+ return (error);
+ } else {
+ /* XXX add code for SCSI2 scanner, if any */
+ return (EOPNOTSUPP);
+ }
+ break;
+ case SCIOCRESTART:
+ if (ss->special->rewind_scanner ) {
+ /* call special handler */
+ error = (ss->special->rewind_scanner)(ss);
+ if (error)
+ return (error);
+ } else
+ /* XXX add code for SCSI2 scanner, if any */
+ return (EOPNOTSUPP);
+ ss->flags &= ~SSF_TRIGGERED;
+ break;
+#ifdef NOTYET
+ case SCAN_USE_ADF:
+ break;
+#endif
+ default:
+ if (SSMODE(dev) != MODE_CONTROL)
+ return (ENOTTY);
+ return (scsi_do_ioctl(ss->sc_link, dev, cmd, addr, flag, p));
+ }
+ return (error);
+}
/* $NetBSD: ss.c,v 1.6 1996/02/19 00:06:07 mycroft Exp $ */
/*
+/* $OpenBSD: ss_mustek.c,v 1.2 1996/04/19 16:10:21 niklas Exp $ */
+/* $NetBSD: ss_mustek.c,v 1.1 1996/02/18 20:32:47 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1995 Joachim Koenig-Baltes. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Joachim Koenig-Baltes.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * special driver for MUSTEK flatbed scanners MFS 06000CX and MFS 12000CX
+ * these scanners come with their own scsi card, containing an NCR53C400
+ * SCSI controller chip. I'm in the progress of writing a driver for this
+ * card to work under NetBSD-current. I've hooked it up to a Seagate ST01
+ * hostadapter in the meantime, giving 350KB/sec for higher resolutions!
+ *
+ * I tried to connect it to my Adaptec 1542B, but with no success. It seems,
+ * it does not like synchronous negotiation between Hostadapter and other
+ * targets, but I could not turn this off for the 1542B.
+ *
+ * There is also an other reason why you would not like to connect it to your
+ * favourite SCSI host adapter: The Mustek DOES NOT DISCONNECT. It will block
+ * other traffic from the bus while a transfer is active.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/fcntl.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/malloc.h>
+#include <sys/buf.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/device.h>
+#include <sys/conf.h> /* for cdevsw */
+#include <sys/scanio.h>
+
+#include <scsi/scsi_all.h>
+#include <scsi/scsi_scanner.h>
+#include <scsi/scsiconf.h>
+#include <scsi/ssvar.h>
+#include <scsi/ss_mustek.h>
+
+#define MUSTEK_RETRIES 4
+
+int mustek_get_params __P((struct ss_softc *));
+int mustek_set_params __P((struct ss_softc *, struct scan_io *));
+int mustek_trigger_scanner __P((struct ss_softc *));
+void mustek_minphys __P((struct ss_softc *, struct buf *));
+int mustek_read __P((struct ss_softc *, struct buf *));
+int mustek_rewind_scanner __P((struct ss_softc *));
+
+/* only used internally */
+int mustek_get_status __P((struct ss_softc *, int, int));
+void mustek_compute_sizes __P((struct ss_softc *));
+
+/*
+ * structure for the special handlers
+ */
+struct ss_special mustek_special = {
+ mustek_set_params,
+ mustek_trigger_scanner,
+ mustek_get_params,
+ mustek_minphys,
+ mustek_read,
+ mustek_rewind_scanner,
+ NULL, /* no adf support right now */
+ NULL /* no adf support right now */
+};
+
+/*
+ * mustek_attach: attach special functions to ss
+ */
+void
+mustek_attach(ss, sa)
+ struct ss_softc *ss;
+ struct scsibus_attach_args *sa;
+{
+ struct scsi_link *sc_link = sa->sa_sc_link;
+
+ SC_DEBUG(sc_link, SDEV_DB1, ("mustek_attach: start\n"));
+ ss->sio.scan_scanner_type = 0;
+
+ /* first, check the model which determines resolutions */
+ if (!bcmp(sa->sa_inqbuf->product, "MFS-06000CX", 11)) {
+ ss->sio.scan_scanner_type = MUSTEK_06000CX;
+ printf(": Mustek 6000CX Flatbed 3-pass color scanner, 3 - 600 dpi\n");
+ }
+ if (!bcmp(sa->sa_inqbuf->product, "MFS-12000CX", 11)) {
+ ss->sio.scan_scanner_type = MUSTEK_12000CX;
+ printf(": Mustek 12000CX Flatbed 3-pass color scanner, 6 - 1200 dpi\n");
+ }
+
+ SC_DEBUG(sc_link, SDEV_DB1, ("mustek_attach: scanner_type = %d\n",
+ ss->sio.scan_scanner_type));
+
+ /* install special handlers */
+ ss->special = &mustek_special;
+
+ /*
+ * populate the scanio struct with legal values
+ * the default should come from user space
+ */
+ ss->sio.scan_width = 1200;
+ ss->sio.scan_height = 1200;
+ ss->sio.scan_x_resolution = 99;
+ ss->sio.scan_y_resolution = 99;
+ ss->sio.scan_x_origin = 0;
+ ss->sio.scan_y_origin = 0;
+ ss->sio.scan_brightness = 100;
+ ss->sio.scan_contrast = 100;
+ ss->sio.scan_quality = 100;
+ ss->sio.scan_image_mode = SIM_GRAYSCALE;
+
+ mustek_compute_sizes(ss);
+}
+
+int
+mustek_get_params (ss)
+ struct ss_softc *ss;
+{
+
+ return (0);
+}
+
+/*
+ * check the parameters if the mustek is capable of fulfilling it
+ * but don't send the command to the scanner in case the user wants
+ * to change parameters by more than one call
+ */
+int
+mustek_set_params(ss, sio)
+ struct ss_softc *ss;
+ struct scan_io *sio;
+{
+ int error;
+
+ /*
+ * if the scanner is triggered, then rewind it
+ */
+ if (ss->flags & SSF_TRIGGERED) {
+ error = mustek_rewind_scanner(ss);
+ if (error)
+ return (error);
+ }
+
+ /* size constraints: 8.5" horizontally and 14" vertically */
+#ifdef MUSTEK_INCH_SPEC
+ /* sizes must be a multiple of 1/8" */
+ sio->scan_x_origin -= sio->scan_x_origin % 150;
+ sio->scan_y_origin -= sio->scan_y_origin % 150;
+ sio->scan_width -= sio->scan_width % 150;
+ sio->scan_height -= sio->scan_height % 150;
+#endif
+ if (sio->scan_width == 0 ||
+ sio->scan_x_origin + sio->scan_width > 10200 ||
+ sio->scan_height == 0 ||
+ sio->scan_y_origin + sio->scan_height > 16800)
+ return (EINVAL);
+
+ /*
+ * for now, only realize the values for the MUSTEK_06000CX
+ * in the future, values for the MUSTEK_12000CX will be implemented
+ */
+
+ /*
+ * resolution (dpi) must be <= 300 and a multiple of 3 or
+ * between 300 and 600 and a multiple of 30
+ */
+ sio->scan_x_resolution -= sio->scan_x_resolution <= 300 ?
+ sio->scan_x_resolution % 3 : sio->scan_x_resolution % 30;
+ sio->scan_y_resolution -= sio->scan_y_resolution <= 300 ?
+ sio->scan_y_resolution % 3 : sio->scan_y_resolution % 30;
+ if (sio->scan_x_resolution < 3 || sio->scan_x_resolution > 600 ||
+ sio->scan_x_resolution != sio->scan_y_resolution)
+ return (EINVAL);
+
+ /* assume brightness values are between 64 and 136 in steps of 3 */
+ sio->scan_brightness -= (sio->scan_brightness - 64) % 3;
+ if (sio->scan_brightness < 64 || sio->scan_brightness > 136)
+ return (EINVAL);
+
+ /* contrast values must be between 16 and 184 in steps of 7 */
+ sio->scan_contrast -= (sio->scan_contrast - 16) % 7;
+ if (sio->scan_contrast < 16 || sio->scan_contrast > 184)
+ return (EINVAL);
+
+ /*
+ * velocity: between 0 (fast) and 4 (slow) which will be mapped
+ * to 100% = 4, 80% = 3, 60% = 2, 40% = 1, 20% = 0
+ * must be a multiple of 20
+ */
+ sio->scan_quality -= sio->scan_quality % 20;
+ if (sio->scan_quality < 20 || sio->scan_quality > 100)
+ return (EINVAL);
+
+ switch (sio->scan_image_mode) {
+ case SIM_BINARY_MONOCHROME:
+ case SIM_DITHERED_MONOCHROME:
+ case SIM_GRAYSCALE:
+ case SIM_RED:
+ case SIM_GREEN:
+ case SIM_BLUE:
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ /* change ss_softc to the new values, but save ro-variables */
+ sio->scan_scanner_type = ss->sio.scan_scanner_type;
+ bcopy(sio, &ss->sio, sizeof(struct scan_io));
+
+ mustek_compute_sizes(ss);
+
+ return (0);
+}
+
+/*
+ * trim the requested transfer to a multiple of the line size
+ * this is called only from ssread() which guarantees, scanner is triggered
+ * In the future, it will trim the transfer to not read to much at a time
+ * because the mustek cannot disconnect. It will be calculated by the
+ * resolution, the velocity and the number of bytes per line.
+ */
+void
+mustek_minphys(ss, bp)
+ struct ss_softc *ss;
+ struct buf *bp;
+{
+ struct scsi_link *sc_link = ss->sc_link;
+
+ SC_DEBUG(sc_link, SDEV_DB1, ("mustek_minphys: before: %d\n",
+ bp->b_bcount));
+ bp->b_bcount -= bp->b_bcount %
+ ((ss->sio.scan_pixels_per_line * ss->sio.scan_bits_per_pixel) / 8);
+ SC_DEBUG(sc_link, SDEV_DB1, ("mustek_minphys: after: %d\n",
+ bp->b_bcount));
+}
+
+/*
+ * trigger the scanner to start a scan operation
+ * this includes sending the mode- and window-data, starting the scanner
+ * and getting the image size info
+ */
+int
+mustek_trigger_scanner(ss)
+ struct ss_softc *ss;
+{
+ struct mustek_mode_select_cmd mode_cmd;
+ struct mustek_mode_select_data mode_data;
+ struct mustek_set_window_cmd window_cmd;
+ struct mustek_set_window_data window_data;
+ struct mustek_start_scan_cmd start_scan_cmd;
+ struct scsi_link *sc_link = ss->sc_link;
+#ifndef MUSTEK_INCH_SPEC
+ int pixel_tlx, pixel_tly, pixel_brx, pixel_bry, paperlength;
+#endif
+ int error;
+
+ mustek_compute_sizes(ss);
+
+ SC_DEBUG(sc_link, SDEV_DB1, ("mustek_trigger_scanner\n"));
+
+ /*
+ * set the window params and send the scsi command
+ */
+ bzero(&window_cmd, sizeof(window_cmd));
+ window_cmd.opcode = MUSTEK_SET_WINDOW;
+ window_cmd.length = sizeof(window_data);
+
+ bzero(&window_data, sizeof(window_data));
+ window_data.frame_header = MUSTEK_LINEART_BACKGROUND | MUSTEK_UNIT_SPEC;
+#ifdef MUSTEK_INCH_SPEC
+ /* the positional values are all 1 byte because 256 / 8 = 32" */
+ window_data.frame_tl_x_0 = ss->sio.scan_x_origin / 150;
+ window_data.frame_tl_x_1 = 0;
+ window_data.frame_tl_y_0 = ss->sio.scan_y_origin / 150;
+ window_data.frame_tl_y_1 = 0;
+ window_data.frame_br_x_0 = (ss->sio.scan_x_origin +
+ ss->sio.scan_width) / 150;
+ window_data.frame_br_x_1 = 0;
+ window_data.frame_br_y_0 = (ss->sio.scan_y_origin +
+ ss->sio.scan_height) / 150;
+ window_data.frame_br_y_1 = 0;
+#else
+ pixel_tlx = (ss->sio.scan_x_origin * ss->sio.scan_x_resolution) / 1200;
+ window_data.frame_tl_x_0 = pixel_tlx & 0xff;
+ window_data.frame_tl_x_1 = (pixel_tlx >> 8) & 0xff;
+ pixel_tly = (ss->sio.scan_y_origin * ss->sio.scan_y_resolution) / 1200;
+ window_data.frame_tl_y_0 = pixel_tly & 0xff;
+ window_data.frame_tl_y_1 = (pixel_tly >> 8) & 0xff;
+ pixel_brx = pixel_tlx +
+ (ss->sio.scan_width * ss->sio.scan_x_resolution) / 1200;
+ window_data.frame_br_x_0 = pixel_brx & 0xff;
+ window_data.frame_br_x_1 = (pixel_brx >> 8) & 0xff;
+ pixel_bry = pixel_tly +
+ (ss->sio.scan_height * ss->sio.scan_y_resolution) / 1200;
+ window_data.frame_br_y_0 = pixel_bry & 0xff;
+ window_data.frame_br_y_1 = (pixel_bry >> 8) & 0xff;
+#endif
+
+#if MUSTEK_WINDOWS >= 1
+ window_data.window1_header = MUSTEK_WINDOW_MASK | MUSTEK_UNIT_SPEC;
+ window_data.window1_tl_x_0 = window_data.frame_tl_x_0;
+ window_data.window1_tl_x_1 = window_data.frame_tl_x_1;
+ window_data.window1_tl_y_0 = window_data.frame_tl_y_0;
+ window_data.window1_tl_y_1 = window_data.frame_tl_y_1;
+ window_data.window1_br_x_0 = window_data.frame_br_x_0;
+ window_data.window1_br_x_1 = window_data.frame_br_x_1;
+ window_data.window1_br_y_0 = window_data.frame_br_y_0;
+ window_data.window1_br_y_1 = window_data.frame_br_y_1;
+#endif
+
+ /* send the set window command to the scanner */
+ SC_DEBUG(sc_link, SDEV_DB1, ("mustek_set_parms: set_window\n"));
+ error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &window_cmd,
+ sizeof(window_cmd), (u_char *) &window_data, sizeof(window_data),
+ MUSTEK_RETRIES, 5000, NULL, SCSI_DATA_OUT);
+ if (error)
+ return (error);
+
+ /*
+ * do what it takes to actualize the mode
+ */
+ bzero(&mode_cmd, sizeof(mode_cmd));
+ mode_cmd.opcode = MUSTEK_MODE_SELECT;
+ mode_cmd.length_0 = sizeof(mode_data);
+
+ bzero(&mode_data, sizeof(mode_data));
+ mode_data.mode =
+ MUSTEK_MODE_MASK | MUSTEK_HT_PATTERN_BUILTIN | MUSTEK_UNIT_SPEC;
+ if (ss->sio.scan_x_resolution <= 300) {
+ mode_data.resolution = ss->sio.scan_x_resolution / 3;
+ } else {
+ /*
+ * the resolution values is computed by modulo 100, but not
+ * for 600dpi, where the value is 100 (a bit tricky, but ...)
+ */
+ mode_data.resolution =
+ ((ss->sio.scan_x_resolution - 1) % 100) + 1;
+ }
+ mode_data.brightness = (ss->sio.scan_brightness - 64) / 3;
+ mode_data.contrast = (ss->sio.scan_contrast - 16) / 7;
+ mode_data.grain = 0;
+ mode_data.velocity = ss->sio.scan_quality / 20 - 1;
+#ifdef MUSTEK_INCH_SPEC
+ mode_data.paperlength_0 = 14 * 8; /* 14" */
+ mode_data.paperlength_1 = 0;
+#else
+ paperlength = 14 * ss->sio.scan_y_resolution; /* 14" */
+ mode_data.paperlength_0 = paperlength & 0xff;
+ mode_data.paperlength_1 = (paperlength >> 8) & 0xff;
+#endif
+
+ SC_DEBUG(sc_link, SDEV_DB1, ("mustek_trigger_scanner: mode_select\n"));
+ /* send the command to the scanner */
+ error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &mode_cmd,
+ sizeof(mode_cmd), (u_char *) &mode_data, sizeof(mode_data),
+ MUSTEK_RETRIES, 5000, NULL, SCSI_DATA_OUT);
+ if (error)
+ return (error);
+
+ /*
+ * now construct and send the start command
+ */
+ bzero(&start_scan_cmd,sizeof(start_scan_cmd));
+ start_scan_cmd.opcode = MUSTEK_START_STOP;
+ start_scan_cmd.mode = MUSTEK_SCAN_START;
+ if (ss->sio.scan_x_resolution <= 300)
+ start_scan_cmd.mode |= MUSTEK_RES_STEP_1;
+ else
+ start_scan_cmd.mode |= MUSTEK_RES_STEP_10;
+ switch (ss->sio.scan_image_mode) {
+ case SIM_BINARY_MONOCHROME:
+ case SIM_DITHERED_MONOCHROME:
+ start_scan_cmd.mode |= MUSTEK_BIT_MODE | MUSTEK_GRAY_FILTER;
+ break;
+ case SIM_GRAYSCALE:
+ start_scan_cmd.mode |= MUSTEK_GRAY_MODE | MUSTEK_GRAY_FILTER;
+ break;
+ case SIM_RED:
+ start_scan_cmd.mode |= MUSTEK_GRAY_MODE | MUSTEK_RED_FILTER;
+ break;
+ case SIM_GREEN:
+ start_scan_cmd.mode |= MUSTEK_GRAY_MODE | MUSTEK_GREEN_FILTER;
+ break;
+ case SIM_BLUE:
+ start_scan_cmd.mode |= MUSTEK_GRAY_MODE | MUSTEK_BLUE_FILTER;
+ break;
+ }
+
+ /* send the command to the scanner */
+ SC_DEBUG(sc_link, SDEV_DB1, ("mustek_trigger_scanner: start_scan\n"));
+ error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &start_scan_cmd,
+ sizeof(start_scan_cmd), NULL, 0,
+ MUSTEK_RETRIES, 5000, NULL, 0);
+ if (error)
+ return (error);
+
+ /*
+ * now check if scanner ready this time with update of size info
+ * we wait here so that if the user issues a read directly afterwards,
+ * the scanner will respond directly (otherwise we had to sleep with
+ * a buffer locked in memory)
+ */
+ SC_DEBUG(sc_link, SDEV_DB1, ("mustek_trigger_scanner: get_status\n"));
+ error = mustek_get_status(ss, 60, 1);
+ if (error)
+ return (error);
+
+ return (0);
+}
+
+/*
+ * stop a scan operation in progress
+ */
+int
+mustek_rewind_scanner(ss)
+ struct ss_softc *ss;
+{
+ struct mustek_start_scan_cmd cmd;
+ struct scsi_link *sc_link = ss->sc_link;
+ int error;
+
+ if (ss->sio.scan_window_size != 0) {
+ /*
+ * only if not all data has been read, the scanner has to be
+ * stopped
+ */
+ bzero(&cmd, sizeof(cmd));
+ cmd.opcode = MUSTEK_START_STOP;
+ cmd.mode = MUSTEK_SCAN_STOP;
+
+ /* send the command to the scanner */
+ SC_DEBUG(sc_link, SDEV_DB1,
+ ("mustek_rewind_scanner: stop_scan\n"));
+ error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd,
+ sizeof(cmd), NULL, 0, MUSTEK_RETRIES, 5000, NULL, 0);
+ if (error)
+ return (error);
+ }
+
+ SC_DEBUG(sc_link, SDEV_DB1, ("mustek_rewind_scanner: end\n"));
+
+ return (0);
+}
+
+/*
+ * read the requested number of bytes/lines from the scanner
+ */
+int
+mustek_read(ss, bp)
+ struct ss_softc *ss;
+ struct buf *bp;
+{
+ struct mustek_read_cmd cmd;
+ struct scsi_link *sc_link = ss->sc_link;
+ u_long lines_to_read;
+
+ SC_DEBUG(sc_link, SDEV_DB1, ("mustek_read: start\n"));
+
+ bzero(&cmd, sizeof(cmd));
+ cmd.opcode = MUSTEK_READ;
+
+ /* instead of the bytes, the mustek wants the number of lines */
+ lines_to_read = bp->b_bcount /
+ ((ss->sio.scan_pixels_per_line * ss->sio.scan_bits_per_pixel) / 8);
+ SC_DEBUG(sc_link, SDEV_DB1, ("mustek_read: read %d lines\n",
+ lines_to_read));
+ cmd.length_0 = lines_to_read & 0xff;
+ cmd.length_1 = (lines_to_read >> 8) & 0xff;
+ cmd.length_2 = (lines_to_read >> 16) & 0xff;
+
+ /*
+ * go ask the adapter to do all this for us
+ */
+ if (scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd, sizeof(cmd),
+ (u_char *) bp->b_data, bp->b_bcount, MUSTEK_RETRIES, 10000, bp,
+ SCSI_NOSLEEP | SCSI_DATA_IN) != SUCCESSFULLY_QUEUED)
+ printf("%s: not queued\n", ss->sc_dev.dv_xname);
+ else {
+ ss->sio.scan_lines -= lines_to_read;
+ ss->sio.scan_window_size -= bp->b_bcount;
+ }
+
+ return (0);
+}
+
+/*
+ * check if the scanner is ready to take commands
+ * wait timeout seconds and try only every second
+ * if update, then update picture size info
+ *
+ * returns EBUSY if scanner not ready
+ */
+int
+mustek_get_status(ss, timeout, update)
+ struct ss_softc *ss;
+ int timeout, update;
+{
+ struct mustek_get_status_cmd cmd;
+ struct mustek_get_status_data data;
+ struct scsi_link *sc_link = ss->sc_link;
+ int error, lines, bytes_per_line;
+
+ bzero(&cmd, sizeof(cmd));
+ cmd.opcode = MUSTEK_GET_STATUS;
+ cmd.length = sizeof(data);
+
+ while (1) {
+ SC_DEBUG(sc_link, SDEV_DB1, ("mustek_get_status: stat_cmd\n"));
+ error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd,
+ sizeof(cmd), (u_char *) &data, sizeof(data), MUSTEK_RETRIES,
+ 5000, NULL, SCSI_DATA_IN);
+ if (error)
+ return (error);
+ if ((data.ready_busy == MUSTEK_READY) ||
+ (timeout-- <= 0))
+ break;
+ /* please wait a second */
+ tsleep((caddr_t)mustek_get_status, PRIBIO + 1, "mtkrdy", hz);
+ }
+
+ if (update) {
+ bytes_per_line =
+ (data.bytes_per_line_1 << 8) |
+ data.bytes_per_line_0;
+ lines =
+ (data.lines_2 << 16) |
+ (data.lines_1 << 8) |
+ data.lines_0;
+ if (lines != ss->sio.scan_lines) {
+ printf("mustek: lines actual(%d) != computed(%d)\n",
+ lines, ss->sio.scan_lines);
+ return (EIO);
+ }
+ if (bytes_per_line * lines != ss->sio.scan_window_size) {
+ printf("mustek: win-size actual(%d) != computed(%d)\n",
+ bytes_per_line * lines, ss->sio.scan_window_size);
+ return (EIO);
+ }
+
+ SC_DEBUG(sc_link, SDEV_DB1,
+ ("mustek_get_size: bpl=%d, lines=%d\n",
+ (ss->sio.scan_pixels_per_line * ss->sio.scan_bits_per_pixel) / 8,
+ ss->sio.scan_lines));
+ SC_DEBUG(sc_link, SDEV_DB1, ("window size = %d\n",
+ ss->sio.scan_window_size));
+ }
+
+ SC_DEBUG(sc_link, SDEV_DB1, ("mustek_get_status: end\n"));
+ if (data.ready_busy == MUSTEK_READY)
+ return (0);
+ else
+ return (EBUSY);
+}
+
+/*
+ * mustek_compute_sizes: compute window_size and lines for the picture
+ * this function is called from different places in the code
+ */
+void
+mustek_compute_sizes(ss)
+ struct ss_softc *ss;
+{
+
+ switch (ss->sio.scan_image_mode) {
+ case SIM_BINARY_MONOCHROME:
+ case SIM_DITHERED_MONOCHROME:
+ ss->sio.scan_bits_per_pixel = 1;
+ break;
+ case SIM_GRAYSCALE:
+ case SIM_RED:
+ case SIM_GREEN:
+ case SIM_BLUE:
+ ss->sio.scan_bits_per_pixel = 8;
+ break;
+ }
+
+ /*
+ * horizontal number of bytes is always a multiple of 2,
+ * in 8-bit mode at least
+ */
+ ss->sio.scan_pixels_per_line =
+ (ss->sio.scan_width * ss->sio.scan_x_resolution) / 1200;
+ if (ss->sio.scan_bits_per_pixel == 1)
+ /* make it a multiple of 16, and thus of 2 bytes */
+ ss->sio.scan_pixels_per_line =
+ (ss->sio.scan_pixels_per_line + 15) & 0xfffffff0;
+ else
+ ss->sio.scan_pixels_per_line =
+ (ss->sio.scan_pixels_per_line + 1) & 0xfffffffe;
+
+ ss->sio.scan_lines =
+ (ss->sio.scan_height * ss->sio.scan_y_resolution) / 1200;
+ ss->sio.scan_window_size = ss->sio.scan_lines *
+ ((ss->sio.scan_pixels_per_line * ss->sio.scan_bits_per_pixel) / 8);
+}
/* $NetBSD: ss_mustek.c,v 1.1 1996/02/18 20:32:47 mycroft Exp $ */
/*
+/* $OpenBSD: ss_mustek.h,v 1.2 1996/04/19 16:10:22 niklas Exp $ */
+/* $NetBSD: ss_mustek.h,v 1.1 1996/02/18 20:32:48 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1995 Joachim Koenig-Baltes. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Joachim Koenig-Baltes.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SS_MUSTEK_H_
+#define _SS_MUSTEK_H_ 1
+
+/*
+ * support for MUSTEK flatbed SCSI scanners MFS-06000CX and MFS-12000CX
+ * (600 and 1200 dpi horizontally resp), not conforming to the SCSI2 spec.
+ */
+
+/*
+ * Configuration section: describes the mode in which scanner is driven
+ * MUSTEK_INCH_SPEC: frame/window sizes are given in inches instead of
+ * pixels, note: unit is 1/8th of an inch
+ * MUSTEK_WINDOWS: number of windows in a frame, up to 4 allowed,
+ * not used yet, so set to 0
+ */
+#define MUSTEK_INCH_SPEC /* use inches to specify sizes */
+#define MUSTEK_WINDOWS 0 /* no window support yet */
+
+/* mustek scsi commands */
+#define MUSTEK_SET_WINDOW 0x04 /* set image area and windows */
+#define MUSTEK_READ 0x08 /* read command */
+#define MUSTEK_GET_STATUS 0x0f /* image status */
+#define MUSTEK_MODE_SELECT 0x15 /* set resolution, paper length, .. */
+#define MUSTEK_ADF 0x10 /* ADF and backtracking selection */
+#define MUSTEK_START_STOP 0x1b /* start/stop scan */
+#define MUSTEK_LUT 0x55 /* look up table download */
+
+/* the size spec is at the same bit position in different commands */
+#define MUSTEK_UNIT_INCHES 0x00
+#define MUSTEK_UNIT_PIXELS 0x08
+#ifdef MUSTEK_INCH_SPEC
+#define MUSTEK_UNIT_SPEC MUSTEK_UNIT_INCHES
+#else
+#define MUSTEK_UNIT_SPEC MUSTEK_UNIT_PIXELS
+#endif
+
+/*
+ * SCSI command formats
+ */
+
+struct mustek_set_window_cmd {
+ u_char opcode; /* 0x04 */
+ u_char reserved[3];
+ u_char length; /* in bytes */
+ u_char control;
+};
+
+struct mustek_set_window_data {
+#define MUSTEK_LINEART_BACKGROUND 0x00
+#define MUSTEK_HALFTONE_BACKGROUND 0x01
+ u_char frame_header; /* unit-defines also apply */
+ u_char frame_tl_x_0;
+ u_char frame_tl_x_1;
+ u_char frame_tl_y_0;
+ u_char frame_tl_y_1;
+ u_char frame_br_x_0;
+ u_char frame_br_x_1;
+ u_char frame_br_y_0;
+ u_char frame_br_y_1;
+#if MUSTEK_WINDOWS >= 1
+#define MUSTEK_WINDOW_MASK 0x80
+ u_char window1_header; /* unit-defines also apply */
+ u_char window1_tl_x_0;
+ u_char window1_tl_x_1;
+ u_char window1_tl_y_0;
+ u_char window1_tl_y_1;
+ u_char window1_br_x_0;
+ u_char window1_br_x_1;
+ u_char window1_br_y_0;
+ u_char window1_br_y_1;
+#endif
+#if MUSTEK_WINDOWS >= 2
+ u_char window2_header;
+ u_char window2_tl_x_0;
+ u_char window2_tl_x_1;
+ u_char window2_tl_y_0;
+ u_char window2_tl_y_1;
+ u_char window2_br_x_0;
+ u_char window2_br_x_1;
+ u_char window2_br_y_0;
+ u_char window2_br_y_1;
+#endif
+#if MUSTEK_WINDOWS >= 3
+ u_char window3_header;
+ u_char window3_tl_x_0;
+ u_char window3_tl_x_1;
+ u_char window3_tl_y_0;
+ u_char window3_tl_y_1;
+ u_char window3_br_x_0;
+ u_char window3_br_x_1;
+ u_char window3_br_y_0;
+ u_char window3_br_y_1;
+#endif
+#if MUSTEK_WINDOWS == 4
+ u_char window4_header;
+ u_char window4_tl_x_0;
+ u_char window4_tl_x_1;
+ u_char window4_tl_y_0;
+ u_char window4_tl_y_1;
+ u_char window4_br_x_0;
+ u_char window4_br_x_1;
+ u_char window4_br_y_0;
+ u_char window4_br_y_1;
+#endif
+};
+
+struct mustek_read_cmd {
+ u_char opcode; /* 0x08 */
+ u_char reserved;
+ u_char length_2; /* number of LINES to be read (MSB) */
+ u_char length_1; /* number of LINES to be read */
+ u_char length_0; /* number of LINES to be read (LSB) */
+ u_char control;
+};
+
+struct mustek_get_status_cmd {
+ u_char opcode; /* 0x0f */
+ u_char reserved[3];
+ u_char length; /* 0x06 */
+ u_char control;
+};
+
+struct mustek_get_status_data {
+#define MUSTEK_READY 0
+#define MUSTEK_BUSY -1
+ u_char ready_busy; /* 0 = ready */
+ u_char bytes_per_line_0; /* LSB */
+ u_char bytes_per_line_1; /* MSB */
+ u_char lines_0; /* LSB */
+ u_char lines_1;
+ u_char lines_2; /* MSB */
+};
+
+struct mustek_mode_select_cmd {
+ u_char opcode; /* 0x15 */
+ u_char reserved[2];
+ u_char length_1; /* MSB */
+ u_char length_0; /* LSB */
+ u_char control;
+};
+
+/*
+ * resolution settings:
+ * MFS06000CX:
+ * 1% : 0x01 0x02 ... 0x64
+ * 3 6 ... 300 dpi
+ * 10%: 0x1e 0x3c 0x5a 0x14 0x32 0x50 0x0a 0x28 0x46 0x64
+ * 330 360 390 420 450 480 510 540 570 600 dpi
+ * MFS12000CX:
+ * 1% : 0x01 0x02 ... 0x64
+ * 6 12 ... 600 dpi
+ * 10%: 0x1e 0x3c 0x5a 0x14 0x32 0x50 0x0a 0x28 0x46 0x64
+ * 660 720 780 840 900 960 1020 1080 1140 1200 dpi
+ */
+struct mustek_mode_select_data {
+#define MUSTEK_MODE_MASK 0x83
+#define MUSTEK_HT_PATTERN_BUILTIN 0x00
+#define MUSTEK_HT_PATTERN_DOWNLOADED 0x10
+ u_char mode;
+ u_char resolution;
+ u_char brightness;
+ u_char contrast;
+ u_char grain; /* 0 = 8x8, ..... 5 = 2x2 */
+ u_char velocity; /* 0 = fast, ...., 4 = slow */
+ u_char reserved[2];
+ u_char paperlength_0; /* LSB */
+ u_char paperlength_1; /* MSB */
+};
+
+struct mustek_start_scan_cmd {
+ u_char opcode; /* 0x1b */
+ u_char reserved[3];
+#define MUSTEK_SCAN_STOP 0x00
+#define MUSTEK_SCAN_START 0x01
+#define MUSTEK_GRAY_FILTER 0x00
+#define MUSTEK_RED_FILTER 0x08
+#define MUSTEK_GREEN_FILTER 0x10
+#define MUSTEK_BLUE_FILTER 0x18
+#define MUSTEK_GRAY_MODE 0x40
+#define MUSTEK_BIT_MODE 0x00
+#define MUSTEK_RES_STEP_1 0x00
+#define MUSTEK_RES_STEP_10 0x80
+ u_char mode;
+ u_char control;
+};
+
+#endif /* _SS_MUSTEK_H_ */
/* $NetBSD: ss_mustek.h,v 1.1 1996/02/18 20:32:48 mycroft Exp $ */
/*
+/* $OpenBSD: ss_scanjet.c,v 1.2 1996/04/19 16:10:24 niklas Exp $ */
+/* $NetBSD: ss_scanjet.c,v 1.1 1996/02/18 20:32:49 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1995 Kenneth Stailey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Kenneth Stailey.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * special functions for the HP ScanJet IIc and IIcx
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/fcntl.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/malloc.h>
+#include <sys/buf.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/device.h>
+#include <sys/conf.h> /* for cdevsw */
+#include <sys/scanio.h>
+
+#include <scsi/scsi_all.h>
+#include <scsi/scsi_scanner.h>
+#include <scsi/scsiconf.h>
+#include <scsi/ssvar.h>
+
+#define SCANJET_RETRIES 4
+
+int scanjet_get_params __P((struct ss_softc *));
+int scanjet_set_params __P((struct ss_softc *, struct scan_io *));
+int scanjet_trigger_scanner __P((struct ss_softc *));
+int scanjet_read __P((struct ss_softc *, struct buf *));
+
+/* only used internally */
+int scanjet_write __P((struct ss_softc *ss, char *buf, u_int size, int flags));
+int scanjet_set_window __P((struct ss_softc *ss));
+void scanjet_compute_sizes __P((struct ss_softc *));
+
+/*
+ * structure for the special handlers
+ */
+struct ss_special scanjet_special = {
+ scanjet_set_params,
+ scanjet_trigger_scanner,
+ scanjet_get_params,
+ NULL, /* no special minphys */
+ scanjet_read, /* scsi 6-byte read */
+ NULL, /* no "rewind" code (yet?) */
+ NULL, /* no adf support right now */
+ NULL /* no adf support right now */
+};
+
+/*
+ * scanjet_attach: attach special functions to ss
+ */
+void
+scanjet_attach(ss, sa)
+ struct ss_softc *ss;
+ struct scsibus_attach_args *sa;
+{
+ struct scsi_link *sc_link = sa->sa_sc_link;
+
+ SC_DEBUG(sc_link, SDEV_DB1, ("scanjet_attach: start\n"));
+ ss->sio.scan_scanner_type = 0;
+
+ /* first, check the model (which determines nothing yet) */
+
+ if (!bcmp(sa->sa_inqbuf->product, "C1750A", 6)) {
+ ss->sio.scan_scanner_type = HP_SCANJET_IIC;
+ printf(": HP ScanJet IIc\n");
+ }
+ if (!bcmp(sa->sa_inqbuf->product, "C2500A", 6)) {
+ ss->sio.scan_scanner_type = HP_SCANJET_IIC;
+ printf(": HP ScanJet IIcx\n");
+ }
+
+ SC_DEBUG(sc_link, SDEV_DB1, ("mustek_attach: scanner_type = %d\n",
+ ss->sio.scan_scanner_type));
+
+ /* now install special handlers */
+ ss->special = &scanjet_special;
+
+ /*
+ * populate the scanio struct with legal values
+ */
+ ss->sio.scan_width = 1200;
+ ss->sio.scan_height = 1200;
+ ss->sio.scan_x_resolution = 100;
+ ss->sio.scan_y_resolution = 100;
+ ss->sio.scan_x_origin = 0;
+ ss->sio.scan_y_origin = 0;
+ ss->sio.scan_brightness = 100;
+ ss->sio.scan_contrast = 100;
+ ss->sio.scan_quality = 100;
+ ss->sio.scan_image_mode = SIM_GRAYSCALE;
+
+ scanjet_compute_sizes(ss);
+}
+
+int
+scanjet_get_params(ss)
+ struct ss_softc *ss;
+{
+
+ return (0);
+}
+
+/*
+ * check the parameters if the scanjet is capable of fulfilling it
+ * but don't send the command to the scanner in case the user wants
+ * to change parameters by more than one call
+ */
+int
+scanjet_set_params(ss, sio)
+ struct ss_softc *ss;
+ struct scan_io *sio;
+{
+ int error;
+
+#if 0
+ /*
+ * if the scanner is triggered, then rewind it
+ */
+ if (ss->flags & SSF_TRIGGERED) {
+ error = scanjet_rewind_scanner(ss);
+ if (error)
+ return (error);
+ }
+#endif
+
+ /* size constraints... */
+ if (sio->scan_width == 0 ||
+ sio->scan_x_origin + sio->scan_width > 10200 || /* 8.5" */
+ sio->scan_height == 0 ||
+ sio->scan_y_origin + sio->scan_height > 16800) /* 14" */
+ return (EINVAL);
+
+ /* resolution (dpi)... */
+ if (sio->scan_x_resolution < 100 ||
+ sio->scan_x_resolution > 400 ||
+ sio->scan_y_resolution < 100 ||
+ sio->scan_y_resolution > 400)
+ return (EINVAL);
+
+ switch (sio->scan_image_mode) {
+ case SIM_BINARY_MONOCHROME:
+ case SIM_DITHERED_MONOCHROME:
+ case SIM_GRAYSCALE:
+ case SIM_COLOR:
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ /* change ss_softc to the new values, but save ro-variables */
+ sio->scan_scanner_type = ss->sio.scan_scanner_type;
+ bcopy(sio, &ss->sio, sizeof(struct scan_io));
+
+ scanjet_compute_sizes(ss);
+
+ return (0);
+}
+
+/*
+ * trigger the scanner to start a scan operation
+ * this includes sending the mode- and window-data,
+ * and starting the scanner
+ */
+int
+scanjet_trigger_scanner(ss)
+ struct ss_softc *ss;
+{
+ char escape_codes[20];
+ struct scsi_link *sc_link = ss->sc_link;
+ int error;
+
+ scanjet_compute_sizes(ss);
+
+ /* send parameters */
+ error = scanjet_set_window(ss);
+ if (error) {
+ uprintf("set window failed\n");
+ return (error);
+ }
+
+ /* send "trigger" operation */
+ strcpy(escape_codes, "\033*f0S");
+ error = scanjet_write(ss, escape_codes, strlen(escape_codes), 0);
+ if (error) {
+ uprintf("trigger failed\n");
+ return (error);
+ }
+
+ return (0);
+}
+
+int
+scanjet_read(ss, bp)
+ struct ss_softc *ss;
+ struct buf *bp;
+{
+ struct scsi_rw_scanner cmd;
+ struct scsi_link *sc_link = ss->sc_link;
+
+ /*
+ * Fill out the scsi command
+ */
+ bzero(&cmd, sizeof(cmd));
+ cmd.opcode = READ;
+
+ /*
+ * Handle "fixed-block-mode" tape drives by using the
+ * block count instead of the length.
+ */
+ lto3b(bp->b_bcount, cmd.len);
+
+ /*
+ * go ask the adapter to do all this for us
+ */
+ if (scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd, sizeof(cmd),
+ (u_char *) bp->b_data, bp->b_bcount, SCANJET_RETRIES, 100000, bp,
+ SCSI_NOSLEEP | SCSI_DATA_IN) != SUCCESSFULLY_QUEUED)
+ printf("%s: not queued\n", ss->sc_dev.dv_xname);
+ else {
+ ss->sio.scan_window_size -= bp->b_bcount;
+ if (ss->sio.scan_window_size < 0)
+ ss->sio.scan_window_size = 0;
+ }
+
+ return (0);
+}
+
+
+/*
+ * Do a synchronous write. Used to send control messages.
+ */
+int
+scanjet_write(ss, buf, size, flags)
+ struct ss_softc *ss;
+ char *buf;
+ u_int size;
+ int flags;
+{
+ struct scsi_rw_scanner cmd;
+
+ /*
+ * If it's a null transfer, return immediatly
+ */
+ if (size == 0)
+ return (0);
+ bzero(&cmd, sizeof(cmd));
+ cmd.opcode = WRITE;
+ lto3b(size, cmd.len);
+ return (scsi_scsi_cmd(ss->sc_link, (struct scsi_generic *) &cmd,
+ sizeof(cmd), (u_char *) buf, size, 0, 100000, NULL,
+ flags | SCSI_DATA_OUT));
+}
+
+#ifdef SCANJETDEBUG
+static void show_es(char *es)
+{
+ char *p = es;
+ while (*p) {
+ if (*p == '\033')
+ printf("[Esc]");
+ else
+ printf("%c", *p);
+ ++p;
+ }
+ printf("\n");
+}
+#endif
+
+/*
+ * simulate SCSI_SET_WINDOW for ScanJets
+ */
+int
+scanjet_set_window(ss)
+ struct ss_softc *ss;
+{
+ char escape_codes[128], *p;
+
+ p = escape_codes;
+
+ sprintf(p, "\033*f%dP", ss->sio.scan_width / 4);
+ p += strlen(p);
+ sprintf(p, "\033*f%dQ", ss->sio.scan_height / 4);
+ p += strlen(p);
+ sprintf(p, "\033*f%dX", ss->sio.scan_x_origin / 4);
+ p += strlen(p);
+ sprintf(p, "\033*f%dY", ss->sio.scan_y_origin / 4);
+ p += strlen(p);
+ sprintf(p, "\033*a%dR", ss->sio.scan_x_resolution);
+ p += strlen(p);
+ sprintf(p, "\033*a%dS", ss->sio.scan_y_resolution);
+ p += strlen(p);
+
+ switch (ss->sio.scan_image_mode) {
+ case SIM_BINARY_MONOCHROME:
+ /* use "line art" mode */
+ strcpy(p, "\033*a0T");
+ p += strlen(p);
+ /* make image data be "min-is-white ala PBM */
+ strcpy(p, "\033*a0I");
+ p += strlen(p);
+ break;
+ case SIM_DITHERED_MONOCHROME:
+ /* use dithered mode */
+ strcpy(p, "\033*a3T");
+ p += strlen(p);
+ /* make image data be "min-is-white ala PBM */
+ strcpy(p, "\033*a0I");
+ p += strlen(p);
+ break;
+ case SIM_GRAYSCALE:
+ /* use grayscale mode */
+ strcpy(p, "\033*a4T");
+ p += strlen(p);
+ /* make image data be "min-is-black ala PGM */
+ strcpy(p, "\033*a1I");
+ p += strlen(p);
+ break;
+ case SIM_COLOR:
+ /* use RGB color mode */
+ strcpy(p, "\033*a5T");
+ p += strlen(p);
+ /* make image data be "min-is-black ala PPM */
+ strcpy(p, "\033*a1I");
+ p += strlen(p);
+ /* use pass-through matrix (disable NTSC) */
+ strcpy(p, "\033*u2T");
+ p += strlen(p);
+ }
+
+ sprintf(p, "\033*a%dG", ss->sio.scan_bits_per_pixel);
+ p += strlen(p);
+ sprintf(p, "\033*a%dL", (int)(ss->sio.scan_brightness) - 128);
+ p += strlen(p);
+ sprintf(p, "\033*a%dK", (int)(ss->sio.scan_contrast) - 128);
+ p += strlen(p);
+
+ return (scanjet_write(ss, escape_codes, p - escape_codes, 0));
+}
+
+void
+scanjet_compute_sizes(ss)
+ struct ss_softc *ss;
+{
+
+ /*
+ * Deal with the fact that the HP ScanJet IIc uses 1/300" not 1/1200"
+ * as its base unit of measurement. PINT uses 1/1200" (yes I know
+ * ScanJet II's use decipoints as well but 1200 % 720 != 0)
+ */
+ ss->sio.scan_width = (ss->sio.scan_width + 3) & 0xfffffffc;
+ ss->sio.scan_height = (ss->sio.scan_height + 3) & 0xfffffffc;
+
+ switch (ss->sio.scan_image_mode) {
+ case SIM_BINARY_MONOCHROME:
+ case SIM_DITHERED_MONOCHROME:
+ ss->sio.scan_bits_per_pixel = 1;
+ break;
+ case SIM_GRAYSCALE:
+ ss->sio.scan_bits_per_pixel = 8;
+ break;
+ case SIM_COLOR:
+ ss->sio.scan_bits_per_pixel = 24;
+ break;
+ }
+
+ ss->sio.scan_pixels_per_line =
+ (ss->sio.scan_width * ss->sio.scan_x_resolution) / 1200;
+ if (ss->sio.scan_bits_per_pixel == 1)
+ /* pad to byte boundary: */
+ ss->sio.scan_pixels_per_line =
+ (ss->sio.scan_pixels_per_line + 7) & 0xfffffff8;
+
+ ss->sio.scan_lines =
+ (ss->sio.scan_height * ss->sio.scan_y_resolution) / 1200;
+ ss->sio.scan_window_size = ss->sio.scan_lines *
+ ((ss->sio.scan_pixels_per_line * ss->sio.scan_bits_per_pixel) / 8);
+}
/* $NetBSD: ss_scanjet.c,v 1.1 1996/02/18 20:32:49 mycroft Exp $ */
/*
+/* $OpenBSD: ssvar.h,v 1.2 1996/04/19 16:10:26 niklas Exp $ */
+/* $NetBSD: ssvar.h,v 1.1 1996/02/18 20:32:50 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1995 Kenneth Stailey. All rights reserved.
+ * modified for configurable scanner support by Joachim Koenig
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Kenneth Stailey.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * SCSI scanner interface description
+ */
+
+/*
+ * Special handlers for impractically different scanner types.
+ * Register NULL for a function if you want to try the real SCSI code
+ * (with quirks table)
+ */
+struct ss_special {
+ int (*set_params)();
+ int (*trigger_scanner)();
+ int (*get_params)();
+ void (*minphys)(); /* some scanners only send line-multiples */
+ int (*read)();
+ int (*rewind_scanner)();
+ int (*load_adf)();
+ int (*unload_adf)();
+};
+
+/*
+ * ss_softc has to be declared here, because the device dependant
+ * modules include it
+ */
+struct ss_softc {
+ struct device sc_dev;
+
+ int flags;
+#define SSF_TRIGGERED 0x01 /* read operation has been primed */
+#define SSF_LOADED 0x02 /* parameters loaded */
+ struct scsi_link *sc_link; /* contains our targ, lun, etc. */
+ struct scan_io sio;
+ struct buf buf_queue; /* the queue of pending IO operations */
+ u_int quirks; /* scanner is only mildly twisted */
+#define SS_Q_GET_BUFFER_SIZE 0x0001 /* poll for available data in ssread() */
+/* truncate to byte boundry is assumed by default unless one of these is set */
+#define SS_Q_PAD_TO_BYTE 0x0002 /* pad monochrome data to byte boundary */
+#define SS_Q_PAD_TO_WORD 0x0004 /* pad monochrome data to word boundary */
+#define SS_Q_THRESHOLD_FOLLOWS_BRIGHTNESS 0x0008
+ struct ss_special *special; /* special handlers for spec. devices */
+};
+
+/*
+ * define the special attach routines if configured
+ */
+void mustek_attach __P((struct ss_softc *, struct scsibus_attach_args *));
+void scanjet_attach __P((struct ss_softc *, struct scsibus_attach_args *));
/* $NetBSD: ssvar.h,v 1.1 1996/02/18 20:32:50 mycroft Exp $ */
/*
-/* $NetBSD: st.c,v 1.54 1995/10/13 20:01:08 gwr Exp $ */
+/* $OpenBSD: st.c,v 1.9 1996/04/19 16:10:28 niklas Exp $ */
+/* $NetBSD: st.c,v 1.62 1996/03/05 00:15:23 thorpej Exp $ */
/*
* Copyright (c) 1994 Charles Hannum. All rights reserved.
{0, 0, 0}, /* minor 8-11 */
{0, 0, 0} /* minor 12-15 */
}}},
+#if 0
{{T_SEQUENTIAL, T_REMOV,
- "WANGTEK ", "5150ES SCSI FA15\0""01 A", "????"}, {0, 0, {
- {0, ST_Q_IGNORE_LOADS, 0}, /* minor 0-3 */
+ "EXABYTE ", "EXB-8200 ", ""}, {0, 12, {
+ {0, 0, 0}, /* minor 0-3 */
{0, 0, 0}, /* minor 4-7 */
{0, 0, 0}, /* minor 8-11 */
{0, 0, 0} /* minor 12-15 */
}}},
-#if 0
+#endif
{{T_SEQUENTIAL, T_REMOV,
- "EXABYTE ", "EXB-8200 ", ""}, {0, 12, {
- {0, 0, 0}, /* minor 0-3 */
+ "WANGTEK ", "5150ES SCSI FA15\0""01 A", "????"}, {0, 0, {
+ {0, ST_Q_IGNORE_LOADS, 0}, /* minor 0-3 */
{0, 0, 0}, /* minor 4-7 */
{0, 0, 0}, /* minor 8-11 */
{0, 0, 0} /* minor 12-15 */
}}},
-#endif
};
#define NOEJECT 0
* the drive. We cannot use interrupts yet, so the
* request must specify this.
*/
- printf(": %s", st->quirkdata ? "rogue, " : "");
+ printf("\n");
+ printf("%s: %s", st->sc_dev.dv_xname, st->quirkdata ? "rogue, " : "");
if (scsi_test_unit_ready(sc_link,
SCSI_AUTOCONF | SCSI_SILENT | SCSI_IGNORE_MEDIA_CHANGE) ||
st_mode_sense(st,
-/* $NetBSD: uk.c,v 1.13 1995/03/24 20:17:15 glass Exp $ */
+/* $OpenBSD: uk.c,v 1.2 1996/04/19 16:10:30 niklas Exp $ */
+/* $NetBSD: uk.c,v 1.14 1996/03/05 00:15:33 thorpej Exp $ */
/*
* Copyright (c) 1994 Charles Hannum. All rights reserved.
sc_link->device_softc = uk;
sc_link->openings = 1;
- printf(": unknown device\n");
+ printf("\n");
+ printf("%s: unknown device\n", uk->sc_dev.dv_xname);
}
/*
* System call numbers.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from NetBSD: syscalls.master,v 1.30 1995/11/22 23:07:29 cgd Exp
+ * created from OpenBSD
*/
#define SYS_syscall 0
/* 169 is compat_10 osemsys */
/* 170 is compat_10 omsgsys */
/* 171 is compat_10 oshmsys */
+#define SYS_ntp_gettime 175
#define SYS_ntp_adjtime 176
-#define SYS_ntp_gettime 177
#define SYS_setgid 181
#define SYS_setegid 182
#define SYS_seteuid 183
* System call argument lists.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from NetBSD: syscalls.master,v 1.30 1995/11/22 23:07:29 cgd Exp
+ * created from OpenBSD
*/
#define syscallarg(x) union { x datum; register_t pad; }
syscallarg(int) a4;
};
-struct sys_ntp_adjtime_args {
+struct ntp_gettime_args {
syscallarg(struct timex *) tp;
};
-struct sys_ntp_gettime_args {
- syscallarg(struct ntptimeval *) tp;
+struct ntp_adjtime_args {
+ syscallarg(struct timex *) tp;
};
struct sys_setgid_args {
int compat_10_sys_shmsys __P((struct proc *, void *, register_t *));
#else
#endif
-int sys_ntp_adjtime __P((struct proc *, void *, register_t *));
-int sys_ntp_gettime __P((struct proc *, void *, register_t *));
+#ifdef NTP
+int ntp_gettime __P((struct proc *, void *, register_t *));
+int ntp_adjtime __P((struct proc *, void *, register_t *));
+#else
+#endif
int sys_setgid __P((struct proc *, void *, register_t *));
int sys_setegid __P((struct proc *, void *, register_t *));
int sys_seteuid __P((struct proc *, void *, register_t *));
* (Modifications made here may easily be lost!)
*
* Created from the file:
- * NetBSD: vnode_if.src,v 1.9 1996/02/09 14:45:38 mycroft Exp
+ * OpenBSD
* by the script:
- * NetBSD: vnode_if.sh,v 1.9 1996/02/29 20:58:22 cgd Exp
+ * OpenBSD
*/
/*
-/* $OpenBSD: mfs_vnops.c,v 1.2 1996/02/27 07:15:48 niklas Exp $ */
-/* $NetBSD: mfs_vnops.c,v 1.6 1996/02/09 22:31:30 christos Exp $ */
+/* $OpenBSD: mfs_vnops.c,v 1.3 1996/04/19 16:10:41 niklas Exp $ */
+/* $NetBSD: mfs_vnops.c,v 1.7 1996/02/21 00:06:45 cgd Exp $ */
/*
* Copyright (c) 1989, 1993
} */ *ap = v;
register struct mfsnode *mfsp = VTOMFS(ap->a_vp);
- printf("tag VT_MFS, pid %d, base %d, size %d\n", mfsp->mfs_pid,
- (unsigned int) mfsp->mfs_baseoff, mfsp->mfs_size);
+ printf("tag VT_MFS, pid %d, base %p, size %d\n", mfsp->mfs_pid,
+ mfsp->mfs_baseoff, mfsp->mfs_size);
return (0);
}
-/* $NetBSD: dir.h,v 1.6 1995/06/15 23:22:49 cgd Exp $ */
+/* $OpenBSD: dir.h,v 1.2 1996/04/19 16:10:44 niklas Exp $ */
+/* $NetBSD: dir.h,v 1.8 1996/03/09 19:42:41 scottr Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
-/* $OpenBSD: vm_glue.c,v 1.12 1996/04/19 06:45:31 niklas Exp $ */
+/* $OpenBSD: vm_glue.c,v 1.13 1996/04/19 16:10:47 niklas Exp $ */
/* $NetBSD: vm_glue.c,v 1.53 1996/02/18 22:53:43 mycroft Exp $ */
/*
-/* $OpenBSD: vm_mmap.c,v 1.4 1996/03/03 17:45:32 niklas Exp $ */
-/* $NetBSD: vm_mmap.c,v 1.45 1996/02/10 00:08:10 christos Exp $ */
+/* $OpenBSD: vm_mmap.c,v 1.5 1996/04/19 16:10:48 niklas Exp $ */
+/* $NetBSD: vm_mmap.c,v 1.46 1996/02/28 22:39:13 gwr Exp $ */
/*
* Copyright (c) 1988 University of Utah.
addr) == 1) {
rv = KERN_NO_SPACE;
} else {
- vm_object_prefer(object, foff, addr);
+#ifdef PMAP_PREFER
+ PMAP_PREFER(foff, addr);
+#endif
rv = vm_map_insert(map, NULL,
(vm_offset_t)0,
*addr, *addr+size);
/*
* vm_map_insert() may fail if
- * vm_object_prefer() has altered
+ * PMAP_PREFER() has altered
* the initial address.
* If so, we start again.
*/
if (rv == KERN_SUCCESS &&
(mmapdebug & MDB_MAPIT)) {
vm_offset_t paddr = *addr;
- vm_object_prefer(object, foff, &paddr);
+#ifdef PMAP_PREFER
+ PMAP_PREFER(foff, &paddr);
+#endif
if (paddr != *addr)
printf(
"vm_mmap: pmap botch! "
-/* $OpenBSD: vm_object.c,v 1.3 1996/03/03 17:45:34 niklas Exp $ */
-/* $NetBSD: vm_object.c,v 1.33 1996/02/10 00:08:11 christos Exp $ */
+/* $OpenBSD: vm_object.c,v 1.4 1996/04/19 16:10:51 niklas Exp $ */
+/* $NetBSD: vm_object.c,v 1.34 1996/02/28 22:35:35 gwr Exp $ */
/*
* Copyright (c) 1991, 1993
return(TRUE);
}
-/*
- * vm_object_prefer:
- *
- * Return optimal virtual address for new mapping of this object.
- *
- * The object must *not* be locked.
- */
-void
-vm_object_prefer(object, offset, addr)
- register vm_object_t object;
- register vm_offset_t offset;
- register vm_offset_t *addr;
-{
- register vm_page_t p;
- register vm_offset_t paddr;
-
-#ifdef PMAP_PREFER
- if (object == NULL)
- goto first_map;
-
- /*
- * Look for the first page that the pmap layer has something
- * to say about. Since an object maps a contiguous range of
- * virutal addresses, this will determine the preferred origin
- * of the proposed mapping.
- */
- vm_object_lock(object);
- for (p = object->memq.tqh_first; p != NULL; p = p->listq.tqe_next) {
- if (p->flags & (PG_FAKE | PG_FICTITIOUS))
- continue;
- paddr = PMAP_PREFER(VM_PAGE_TO_PHYS(p), *addr+p->offset-offset);
- if (paddr == (vm_offset_t)-1)
- continue;
- *addr = paddr - (p->offset - offset);
- vm_object_unlock(object);
- return;
- }
- vm_object_unlock(object);
-
-first_map:
- /*
- * No physical page attached; ask for a preferred address based
- * only on the given virtual address.
- */
- paddr = PMAP_PREFER((vm_offset_t)-1, *addr);
- if (paddr != (vm_offset_t)-1)
- *addr = paddr;
-
-#endif
-}
/*
* vm_object_print: [ debug ]
*/
-/* $NetBSD: vm_user.c,v 1.12 1995/12/05 22:54:39 pk Exp $ */
+/* $OpenBSD: vm_user.c,v 1.3 1996/04/19 16:10:52 niklas Exp $ */
+/* $NetBSD: vm_user.c,v 1.13 1996/02/28 22:39:16 gwr Exp $ */
/*
* Copyright (c) 1991, 1993
if (vm_map_findspace(map, start, size, addr))
result = KERN_NO_SPACE;
else {
- vm_object_prefer(object, poffset, addr);
+#ifdef PMAP_PREFER
+ PMAP_PREFER(poffset, addr);
+#endif
start = *addr;
result = vm_map_insert(map, object, poffset,
start, start + size);