diff options
46 files changed, 15108 insertions, 0 deletions
diff --git a/crypto/openssh/LICENCE b/crypto/openssh/LICENCE new file mode 100644 index 000000000000..e8ab01b9b74f --- /dev/null +++ b/crypto/openssh/LICENCE @@ -0,0 +1,136 @@ +This file is part of the ssh software. + +The licences which components of this software falls under are as +follows. First, we will summarize and say that that all components +are under a BSD licence, or a licence more free than that. + +OpenSSH contains no GPL code. + +1) + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + + [Tatu continues] + * However, I am not implying to give any licenses to any patents or + * copyrights held by third parties, and the software includes parts that + * are not under my direct control. As far as I know, all included + * source code is used in accordance with the relevant license agreements + * and can be used freely for any purpose (the GNU license being the most + * restrictive); see below for details. + + [However, none of that term is relevant at this point in time. All of + these restrictively licenced software components which he talks about + have been removed from OpenSSH, ie. + + - RSA is no longer included, found in the OpenSSL library + - IDEA is no longer included, it's use is depricated + - DES is now external, in the OpenSSL library + - GMP is no longer used, and instead we call BN code from OpenSSL + - Zlib is now external, in a library + - The make-ssh-known-hosts script is no longer included + - TSS has been removed + - MD5 is now external, in the OpenSSL library + - RC4 support has been removed + - Blowfish is now external, in the OpenSSL library + + [The licence continues] + + Note that any information and cryptographic algorithms used in this + software are publicly available on the Internet and at any major + bookstore, scientific library, and patent office worldwide. More + information can be found e.g. at "http://www.cs.hut.fi/crypto". + + The legal status of this program is some combination of all these + permissions and restrictions. Use only at your own responsibility. + You will be responsible for any legal consequences yourself; I am not + making any claims whether possessing or using this is legal or not in + your country, and I am not taking any responsibility on your behalf. + + + NO WARRANTY + + BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY + FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN + OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES + PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED + OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS + TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE + PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, + REPAIR OR CORRECTION. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING + WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR + REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, + INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING + OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED + TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY + YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER + PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGES. + +2) + The 32-bit CRC implementation in crc32.c is due to Gary S. Brown. + Comments in the file indicate it may be used for any purpose without + restrictions: + + * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + +3) + The 32-bit CRC compensation attack detector in deattack.c was + contributed by CORE SDI S.A. under a BSD-style license. See + http://www.core-sdi.com/english/ssh/ for details. + + * Cryptographic attack detector for ssh - source code + * + * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. + * + * All rights reserved. Redistribution and use in source and binary + * forms, with or without modification, are permitted provided that + * this copyright notice is retained. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR + * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS + * SOFTWARE. + * + * Ariel Futoransky <futo@core-sdi.com> + * <http://www.core-sdi.com> + +4) + Remaining components of the software are provided under a standard + 2-term BSD licence with the following names as copyright holders: + + Markus Friedl + Theo de Raadt + Niels Provos + Dug Song + Aaron Campbell + + * 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. + * + * 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. diff --git a/crypto/openssh/auth-options.c b/crypto/openssh/auth-options.c new file mode 100644 index 000000000000..da6965266af3 --- /dev/null +++ b/crypto/openssh/auth-options.c @@ -0,0 +1,223 @@ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * RSA-based authentication. This code determines whether to admit a login + * based on RSA authentication. This file also contains functions to check + * validity of the host key. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#include "includes.h" +RCSID("$OpenBSD: auth-options.c,v 1.4 2000/09/07 21:13:36 markus Exp $"); + +#include "ssh.h" +#include "packet.h" +#include "xmalloc.h" +#include "match.h" + +/* Flags set authorized_keys flags */ +int no_port_forwarding_flag = 0; +int no_agent_forwarding_flag = 0; +int no_x11_forwarding_flag = 0; +int no_pty_flag = 0; + +/* "command=" option. */ +char *forced_command = NULL; + +/* "environment=" options. */ +struct envstring *custom_environment = NULL; + +/* return 1 if access is granted, 0 if not. side effect: sets key option flags */ +int +auth_parse_options(struct passwd *pw, char *options, unsigned long linenum) +{ + const char *cp; + if (!options) + return 1; + while (*options && *options != ' ' && *options != '\t') { + cp = "no-port-forwarding"; + if (strncmp(options, cp, strlen(cp)) == 0) { + packet_send_debug("Port forwarding disabled."); + no_port_forwarding_flag = 1; + options += strlen(cp); + goto next_option; + } + cp = "no-agent-forwarding"; + if (strncmp(options, cp, strlen(cp)) == 0) { + packet_send_debug("Agent forwarding disabled."); + no_agent_forwarding_flag = 1; + options += strlen(cp); + goto next_option; + } + cp = "no-X11-forwarding"; + if (strncmp(options, cp, strlen(cp)) == 0) { + packet_send_debug("X11 forwarding disabled."); + no_x11_forwarding_flag = 1; + options += strlen(cp); + goto next_option; + } + cp = "no-pty"; + if (strncmp(options, cp, strlen(cp)) == 0) { + packet_send_debug("Pty allocation disabled."); + no_pty_flag = 1; + options += strlen(cp); + goto next_option; + } + cp = "command=\""; + if (strncmp(options, cp, strlen(cp)) == 0) { + int i; + options += strlen(cp); + forced_command = xmalloc(strlen(options) + 1); + i = 0; + while (*options) { + if (*options == '"') + break; + if (*options == '\\' && options[1] == '"') { + options += 2; + forced_command[i++] = '"'; + continue; + } + forced_command[i++] = *options++; + } + if (!*options) { + debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + packet_send_debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + continue; + } + forced_command[i] = 0; + packet_send_debug("Forced command: %.900s", forced_command); + options++; + goto next_option; + } + cp = "environment=\""; + if (strncmp(options, cp, strlen(cp)) == 0) { + int i; + char *s; + struct envstring *new_envstring; + options += strlen(cp); + s = xmalloc(strlen(options) + 1); + i = 0; + while (*options) { + if (*options == '"') + break; + if (*options == '\\' && options[1] == '"') { + options += 2; + s[i++] = '"'; + continue; + } + s[i++] = *options++; + } + if (!*options) { + debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + packet_send_debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + continue; + } + s[i] = 0; + packet_send_debug("Adding to environment: %.900s", s); + debug("Adding to environment: %.900s", s); + options++; + new_envstring = xmalloc(sizeof(struct envstring)); + new_envstring->s = s; + new_envstring->next = custom_environment; + custom_environment = new_envstring; + goto next_option; + } + cp = "from=\""; + if (strncmp(options, cp, strlen(cp)) == 0) { + int mname, mip; + char *patterns = xmalloc(strlen(options) + 1); + int i; + options += strlen(cp); + i = 0; + while (*options) { + if (*options == '"') + break; + if (*options == '\\' && options[1] == '"') { + options += 2; + patterns[i++] = '"'; + continue; + } + patterns[i++] = *options++; + } + if (!*options) { + debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + packet_send_debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + continue; + } + patterns[i] = 0; + options++; + /* + * Deny access if we get a negative + * match for the hostname or the ip + * or if we get not match at all + */ + mname = match_hostname(get_canonical_hostname(), + patterns, strlen(patterns)); + mip = match_hostname(get_remote_ipaddr(), + patterns, strlen(patterns)); + xfree(patterns); + if (mname == -1 || mip == -1 || + (mname != 1 && mip != 1)) { + log("Authentication tried for %.100s with correct key but not from a permitted host (host=%.200s, ip=%.200s).", + pw->pw_name, get_canonical_hostname(), + get_remote_ipaddr()); + packet_send_debug("Your host '%.200s' is not permitted to use this key for login.", + get_canonical_hostname()); + /* key invalid for this host, reset flags */ + no_agent_forwarding_flag = 0; + no_port_forwarding_flag = 0; + no_pty_flag = 0; + no_x11_forwarding_flag = 0; + while (custom_environment) { + struct envstring *ce = custom_environment; + custom_environment = ce->next; + xfree(ce->s); + xfree(ce); + } + if (forced_command) { + xfree(forced_command); + forced_command = NULL; + } + /* deny access */ + return 0; + } + /* Host name matches. */ + goto next_option; + } +next_option: + /* + * Skip the comma, and move to the next option + * (or break out if there are no more). + */ + if (!*options) + fatal("Bugs in auth-options.c option processing."); + if (*options == ' ' || *options == '\t') + break; /* End of options. */ + if (*options != ',') + goto bad_option; + options++; + /* Process the next option. */ + } + /* grant access */ + return 1; + +bad_option: + log("Bad options in %.100s file, line %lu: %.50s", + SSH_USER_PERMITTED_KEYS, linenum, options); + packet_send_debug("Bad options in %.100s file, line %lu: %.50s", + SSH_USER_PERMITTED_KEYS, linenum, options); + /* deny access */ + return 0; +} diff --git a/crypto/openssh/auth-options.h b/crypto/openssh/auth-options.h new file mode 100644 index 000000000000..9044d98bea87 --- /dev/null +++ b/crypto/openssh/auth-options.h @@ -0,0 +1,25 @@ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Functions to interface with the SSH_AUTHENTICATION_FD socket. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ +#ifndef AUTH_OPTIONS_H +#define AUTH_OPTIONS_H +/* Flags that may be set in authorized_keys options. */ +extern int no_port_forwarding_flag; +extern int no_agent_forwarding_flag; +extern int no_x11_forwarding_flag; +extern int no_pty_flag; +extern char *forced_command; +extern struct envstring *custom_environment; + +/* return 1 if access is granted, 0 if not. side effect: sets key option flags */ +int auth_parse_options(struct passwd *pw, char *options, unsigned long linenum); +#endif diff --git a/crypto/openssh/sftp-server.8 b/crypto/openssh/sftp-server.8 new file mode 100644 index 000000000000..9811a3b4266c --- /dev/null +++ b/crypto/openssh/sftp-server.8 @@ -0,0 +1,56 @@ +.\" $OpenBSD: sftp-server.8,v 1.2 2000/09/07 20:27:53 deraadt Exp $ +.\" +.\" Copyright (c) 2000 Markus Friedl. 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. +.\" +.\" 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. +.\" +.Dd August 30, 2000 +.Dt SFTP-SERVER 8 +.Os +.Sh NAME +.Nm sftp-server +.Nd SFTP server subsystem +.Sh SYNOPSIS +.Nm sftp-server +.Sh DESCRIPTION +.Nm +is a program that speaks the server side of SFTP protocol +to stdout and expects client requests from stdin. +.Nm +is not intended to be called directly, but from +.Xr sshd 8 +using the +.Cm Subsystem +option. +See +.Xr sshd 8 +for more information. +.Sh HISTORY +.Nm +first appeared in +.Ox 2.8 . +.Sh AUTHOR +Markus Friedl <markus@openbsd.org> +.Sh SEE ALSO +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-keygen 1 , +.Xr sshd 8 , diff --git a/crypto/openssh/sftp-server.c b/crypto/openssh/sftp-server.c new file mode 100644 index 000000000000..018a03cc2098 --- /dev/null +++ b/crypto/openssh/sftp-server.c @@ -0,0 +1,1068 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * + * 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 "includes.h" +RCSID("$OpenBSD: sftp-server.c,v 1.6 2000/09/07 20:27:53 deraadt Exp $"); + +#include "ssh.h" +#include "buffer.h" +#include "bufaux.h" +#include "getput.h" +#include "xmalloc.h" + +/* version */ +#define SSH_FILEXFER_VERSION 2 + +/* client to server */ +#define SSH_FXP_INIT 1 +#define SSH_FXP_OPEN 3 +#define SSH_FXP_CLOSE 4 +#define SSH_FXP_READ 5 +#define SSH_FXP_WRITE 6 +#define SSH_FXP_LSTAT 7 +#define SSH_FXP_FSTAT 8 +#define SSH_FXP_SETSTAT 9 +#define SSH_FXP_FSETSTAT 10 +#define SSH_FXP_OPENDIR 11 +#define SSH_FXP_READDIR 12 +#define SSH_FXP_REMOVE 13 +#define SSH_FXP_MKDIR 14 +#define SSH_FXP_RMDIR 15 +#define SSH_FXP_REALPATH 16 +#define SSH_FXP_STAT 17 +#define SSH_FXP_RENAME 18 + +/* server to client */ +#define SSH_FXP_VERSION 2 +#define SSH_FXP_STATUS 101 +#define SSH_FXP_HANDLE 102 +#define SSH_FXP_DATA 103 +#define SSH_FXP_NAME 104 +#define SSH_FXP_ATTRS 105 + +/* portable open modes */ +#define SSH_FXF_READ 0x01 +#define SSH_FXF_WRITE 0x02 +#define SSH_FXF_APPEND 0x04 +#define SSH_FXF_CREAT 0x08 +#define SSH_FXF_TRUNC 0x10 +#define SSH_FXF_EXCL 0x20 + +/* attributes */ +#define SSH_FXA_HAVE_SIZE 0x01 +#define SSH_FXA_HAVE_UGID 0x02 +#define SSH_FXA_HAVE_PERM 0x04 +#define SSH_FXA_HAVE_TIME 0x08 + +/* status messages */ +#define SSH_FX_OK 0x00 +#define SSH_FX_EOF 0x01 +#define SSH_FX_NO_SUCH_FILE 0x02 +#define SSH_FX_PERMISSION_DENIED 0x03 +#define SSH_FX_FAILURE 0x04 +#define SSH_FX_BAD_MESSAGE 0x05 +#define SSH_FX_NO_CONNECTION 0x06 +#define SSH_FX_CONNECTION_LOST 0x07 + + +/* helper */ +#define get_int() buffer_get_int(&iqueue); +#define get_string(lenp) buffer_get_string(&iqueue, lenp); +#define TRACE log + +/* input and output queue */ +Buffer iqueue; +Buffer oqueue; + +/* portable attibutes, etc. */ + +typedef struct Attrib Attrib; +typedef struct Stat Stat; + +struct Attrib +{ + u_int32_t flags; + u_int32_t size_high; + u_int32_t size_low; + u_int64_t size; + u_int32_t uid; + u_int32_t gid; + u_int32_t perm; + u_int32_t atime; + u_int32_t mtime; +}; + +struct Stat +{ + char *name; + char *long_name; + Attrib attrib; +}; + +int +errno_to_portable(int unixerrno) +{ + int ret = 0; + switch (unixerrno) { + case 0: + ret = SSH_FX_OK; + break; + case ENOENT: + case ENOTDIR: + case EBADF: + case ELOOP: + ret = SSH_FX_NO_SUCH_FILE; + break; + case EPERM: + case EACCES: + case EFAULT: + ret = SSH_FX_PERMISSION_DENIED; + break; + case ENAMETOOLONG: + case EINVAL: + ret = SSH_FX_BAD_MESSAGE; + break; + default: + ret = SSH_FX_FAILURE; + break; + } + return ret; +} + +int +flags_from_portable(int pflags) +{ + int flags = 0; + if (pflags & SSH_FXF_READ && + pflags & SSH_FXF_WRITE) { + flags = O_RDWR; + } else if (pflags & SSH_FXF_READ) { + flags = O_RDONLY; + } else if (pflags & SSH_FXF_WRITE) { + flags = O_WRONLY; + } + if (pflags & SSH_FXF_CREAT) + flags |= O_CREAT; + if (pflags & SSH_FXF_TRUNC) + flags |= O_TRUNC; + if (pflags & SSH_FXF_EXCL) + flags |= O_EXCL; + return flags; +} + +void +attrib_clear(Attrib *a) +{ + a->flags = 0; + a->size_low = 0; + a->size_high = 0; + a->size = 0; + a->uid = 0; + a->gid = 0; + a->perm = 0; + a->atime = 0; + a->mtime = 0; +} + +Attrib * +decode_attrib(Buffer *b) +{ + static Attrib a; + attrib_clear(&a); + a.flags = buffer_get_int(b); + if (a.flags & SSH_FXA_HAVE_SIZE) { + a.size_high = buffer_get_int(b); + a.size_low = buffer_get_int(b); + a.size = (((u_int64_t) a.size_high) << 32) + a.size_low; + } + if (a.flags & SSH_FXA_HAVE_UGID) { + a.uid = buffer_get_int(b); + a.gid = buffer_get_int(b); + } + if (a.flags & SSH_FXA_HAVE_PERM) { + a.perm = buffer_get_int(b); + } + if (a.flags & SSH_FXA_HAVE_TIME) { + a.atime = buffer_get_int(b); + a.mtime = buffer_get_int(b); + } + return &a; +} + +void +encode_attrib(Buffer *b, Attrib *a) +{ + buffer_put_int(b, a->flags); + if (a->flags & SSH_FXA_HAVE_SIZE) { + buffer_put_int(b, a->size_high); + buffer_put_int(b, a->size_low); + } + if (a->flags & SSH_FXA_HAVE_UGID) { + buffer_put_int(b, a->uid); + buffer_put_int(b, a->gid); + } + if (a->flags & SSH_FXA_HAVE_PERM) { + buffer_put_int(b, a->perm); + } + if (a->flags & SSH_FXA_HAVE_TIME) { + buffer_put_int(b, a->atime); + buffer_put_int(b, a->mtime); + } +} + +Attrib * +stat_to_attrib(struct stat *st) +{ + static Attrib a; + attrib_clear(&a); + a.flags = 0; + a.flags |= SSH_FXA_HAVE_SIZE; + a.size = st->st_size; + a.size_low = a.size; + a.size_high = (u_int32_t) (a.size >> 32); + a.flags |= SSH_FXA_HAVE_UGID; + a.uid = st->st_uid; + a.gid = st->st_gid; + a.flags |= SSH_FXA_HAVE_PERM; + a.perm = st->st_mode; + a.flags |= SSH_FXA_HAVE_TIME; + a.atime = st->st_atime; + a.mtime = st->st_mtime; + return &a; +} + +Attrib * +get_attrib(void) +{ + return decode_attrib(&iqueue); +} + +/* handle handles */ + +typedef struct Handle Handle; +struct Handle { + int use; + DIR *dirp; + int fd; + char *name; +}; +enum { + HANDLE_UNUSED, + HANDLE_DIR, + HANDLE_FILE +}; +Handle handles[100]; + +void +handle_init(void) +{ + int i; + for(i = 0; i < sizeof(handles)/sizeof(Handle); i++) + handles[i].use = HANDLE_UNUSED; +} + +int +handle_new(int use, char *name, int fd, DIR *dirp) +{ + int i; + for(i = 0; i < sizeof(handles)/sizeof(Handle); i++) { + if (handles[i].use == HANDLE_UNUSED) { + handles[i].use = use; + handles[i].dirp = dirp; + handles[i].fd = fd; + handles[i].name = name; + return i; + } + } + return -1; +} + +int +handle_is_ok(int i, int type) +{ + return i >= 0 && i < sizeof(handles)/sizeof(Handle) && handles[i].use == type; +} + +int +handle_to_string(int handle, char **stringp, int *hlenp) +{ + char buf[1024]; + if (stringp == NULL || hlenp == NULL) + return -1; + snprintf(buf, sizeof buf, "%d", handle); + *stringp = xstrdup(buf); + *hlenp = strlen(*stringp); + return 0; +} + +int +handle_from_string(char *handle, u_int hlen) +{ +/* XXX OVERFLOW ? */ + char *ep; + long lval = strtol(handle, &ep, 10); + int val = lval; + if (*ep != '\0') + return -1; + if (handle_is_ok(val, HANDLE_FILE) || + handle_is_ok(val, HANDLE_DIR)) + return val; + return -1; +} + +char * +handle_to_name(int handle) +{ + if (handle_is_ok(handle, HANDLE_DIR)|| + handle_is_ok(handle, HANDLE_FILE)) + return handles[handle].name; + return NULL; +} + +DIR * +handle_to_dir(int handle) +{ + if (handle_is_ok(handle, HANDLE_DIR)) + return handles[handle].dirp; + return NULL; +} + +int +handle_to_fd(int handle) +{ + if (handle_is_ok(handle, HANDLE_FILE)) + return handles[handle].fd; + return -1; +} + +int +handle_close(int handle) +{ + int ret = -1; + if (handle_is_ok(handle, HANDLE_FILE)) { + ret = close(handles[handle].fd); + handles[handle].use = HANDLE_UNUSED; + } else if (handle_is_ok(handle, HANDLE_DIR)) { + ret = closedir(handles[handle].dirp); + handles[handle].use = HANDLE_UNUSED; + } else { + errno = ENOENT; + } + return ret; +} + +int +get_handle(void) +{ + char *handle; + int val; + u_int hlen; + handle = get_string(&hlen); + val = handle_from_string(handle, hlen); + xfree(handle); + return val; +} + +/* send replies */ + +void +send_msg(Buffer *m) +{ + int mlen = buffer_len(m); + buffer_put_int(&oqueue, mlen); + buffer_append(&oqueue, buffer_ptr(m), mlen); + buffer_consume(m, mlen); +} + +void +send_status(u_int32_t id, u_int32_t error) +{ + Buffer msg; + TRACE("sent status id %d error %d", id, error); + buffer_init(&msg); + buffer_put_char(&msg, SSH_FXP_STATUS); + buffer_put_int(&msg, id); + buffer_put_int(&msg, error); + send_msg(&msg); + buffer_free(&msg); +} +void +send_data_or_handle(char type, u_int32_t id, char *data, int dlen) +{ + Buffer msg; + buffer_init(&msg); + buffer_put_char(&msg, type); + buffer_put_int(&msg, id); + buffer_put_string(&msg, data, dlen); + send_msg(&msg); + buffer_free(&msg); +} + +void +send_data(u_int32_t id, char *data, int dlen) +{ + TRACE("sent data id %d len %d", id, dlen); + send_data_or_handle(SSH_FXP_DATA, id, data, dlen); +} + +void +send_handle(u_int32_t id, int handle) +{ + char *string; + int hlen; + handle_to_string(handle, &string, &hlen); + TRACE("sent handle id %d handle %d", id, handle); + send_data_or_handle(SSH_FXP_HANDLE, id, string, hlen); + xfree(string); +} + +void +send_names(u_int32_t id, int count, Stat *stats) +{ + Buffer msg; + int i; + buffer_init(&msg); + buffer_put_char(&msg, SSH_FXP_NAME); + buffer_put_int(&msg, id); + buffer_put_int(&msg, count); + TRACE("sent names id %d count %d", id, count); + for (i = 0; i < count; i++) { + buffer_put_cstring(&msg, stats[i].name); + buffer_put_cstring(&msg, stats[i].long_name); + encode_attrib(&msg, &stats[i].attrib); + } + send_msg(&msg); + buffer_free(&msg); +} + +void +send_attrib(u_int32_t id, Attrib *a) +{ + Buffer msg; + TRACE("sent attrib id %d have 0x%x", id, a->flags); + buffer_init(&msg); + buffer_put_char(&msg, SSH_FXP_ATTRS); + buffer_put_int(&msg, id); + encode_attrib(&msg, a); + send_msg(&msg); + buffer_free(&msg); +} + +/* parse incoming */ + +void +process_init(void) +{ + Buffer msg; + int version = buffer_get_int(&iqueue); + + TRACE("client version %d", version); + buffer_init(&msg); + buffer_put_char(&msg, SSH_FXP_VERSION); + buffer_put_int(&msg, SSH_FILEXFER_VERSION); + send_msg(&msg); + buffer_free(&msg); +} + +void +process_open(void) +{ + u_int32_t id, pflags; + Attrib *a; + char *name; + int handle, fd, flags, mode, status = SSH_FX_FAILURE; + + id = get_int(); + name = get_string(NULL); + pflags = get_int(); + a = get_attrib(); + flags = flags_from_portable(pflags); + mode = (a->flags & SSH_FXA_HAVE_PERM) ? a->perm : 0666; + TRACE("open id %d name %s flags %d mode 0%o", id, name, pflags, mode); + fd = open(name, flags, mode); + if (fd < 0) { + status = errno_to_portable(errno); + } else { + handle = handle_new(HANDLE_FILE, xstrdup(name), fd, NULL); + if (handle < 0) { + close(fd); + } else { + send_handle(id, handle); + status = SSH_FX_OK; + } + } + if (status != SSH_FX_OK) + send_status(id, status); + xfree(name); +} + +void +process_close(void) +{ + u_int32_t id; + int handle, ret, status = SSH_FX_FAILURE; + + id = get_int(); + handle = get_handle(); + TRACE("close id %d handle %d", id, handle); + ret = handle_close(handle); + status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK; + send_status(id, status); +} + +void +process_read(void) +{ + char buf[64*1024]; + u_int32_t id, off_high, off_low, len; + int handle, fd, ret, status = SSH_FX_FAILURE; + u_int64_t off; + + id = get_int(); + handle = get_handle(); + off_high = get_int(); + off_low = get_int(); + len = get_int(); + + off = (((u_int64_t) off_high) << 32) + off_low; + TRACE("read id %d handle %d off %qd len %d", id, handle, off, len); + if (len > sizeof buf) { + len = sizeof buf; + log("read change len %d", len); + } + fd = handle_to_fd(handle); + if (fd >= 0) { + if (lseek(fd, off, SEEK_SET) < 0) { + error("process_read: seek failed"); + status = errno_to_portable(errno); + } else { + ret = read(fd, buf, len); + if (ret < 0) { + status = errno_to_portable(errno); + } else if (ret == 0) { + status = SSH_FX_EOF; + } else { + send_data(id, buf, ret); + status = SSH_FX_OK; + } + } + } + if (status != SSH_FX_OK) + send_status(id, status); +} + +void +process_write(void) +{ + u_int32_t id, off_high, off_low; + u_int64_t off; + u_int len; + int handle, fd, ret, status = SSH_FX_FAILURE; + char *data; + + id = get_int(); + handle = get_handle(); + off_high = get_int(); + off_low = get_int(); + data = get_string(&len); + + off = (((u_int64_t) off_high) << 32) + off_low; + TRACE("write id %d handle %d off %qd len %d", id, handle, off, len); + fd = handle_to_fd(handle); + if (fd >= 0) { + if (lseek(fd, off, SEEK_SET) < 0) { + status = errno_to_portable(errno); + error("process_write: seek failed"); + } else { +/* XXX ATOMICIO ? */ + ret = write(fd, data, len); + if (ret == -1) { + error("process_write: write failed"); + status = errno_to_portable(errno); + } else if (ret == len) { + status = SSH_FX_OK; + } else { + log("nothing at all written"); + } + } + } + send_status(id, status); + xfree(data); +} + +void +process_do_stat(int do_lstat) +{ + Attrib *a; + struct stat st; + u_int32_t id; + char *name; + int ret, status = SSH_FX_FAILURE; + + id = get_int(); + name = get_string(NULL); + TRACE("%sstat id %d name %s", do_lstat ? "l" : "", id, name); + ret = do_lstat ? lstat(name, &st) : stat(name, &st); + if (ret < 0) { + status = errno_to_portable(errno); + } else { + a = stat_to_attrib(&st); + send_attrib(id, a); + status = SSH_FX_OK; + } + if (status != SSH_FX_OK) + send_status(id, status); + xfree(name); +} + +void +process_stat(void) +{ + process_do_stat(0); +} + +void +process_lstat(void) +{ + process_do_stat(1); +} + +void +process_fstat(void) +{ + Attrib *a; + struct stat st; + u_int32_t id; + int fd, ret, handle, status = SSH_FX_FAILURE; + + id = get_int(); + handle = get_handle(); + TRACE("fstat id %d handle %d", id, handle); + fd = handle_to_fd(handle); + if (fd >= 0) { + ret = fstat(fd, &st); + if (ret < 0) { + status = errno_to_portable(errno); + } else { + a = stat_to_attrib(&st); + send_attrib(id, a); + status = SSH_FX_OK; + } + } + if (status != SSH_FX_OK) + send_status(id, status); +} + +struct timeval * +attrib_to_tv(Attrib *a) +{ + static struct timeval tv[2]; + tv[0].tv_sec = a->atime; + tv[0].tv_usec = 0; + tv[1].tv_sec = a->mtime; + tv[1].tv_usec = 0; + return tv; +} + +void +process_setstat(void) +{ + Attrib *a; + u_int32_t id; + char *name; + int ret; + int status = SSH_FX_OK; + + id = get_int(); + name = get_string(NULL); + a = get_attrib(); + TRACE("setstat id %d name %s", id, name); + if (a->flags & SSH_FXA_HAVE_PERM) { + ret = chmod(name, a->perm & 0777); + if (ret == -1) + status = errno_to_portable(errno); + } + if (a->flags & SSH_FXA_HAVE_TIME) { + ret = utimes(name, attrib_to_tv(a)); + if (ret == -1) + status = errno_to_portable(errno); + } + send_status(id, status); + xfree(name); +} + +void +process_fsetstat(void) +{ + Attrib *a; + u_int32_t id; + int handle, fd, ret; + int status = SSH_FX_OK; + + id = get_int(); + handle = get_handle(); + a = get_attrib(); + TRACE("fsetstat id %d handle %d", id, handle); + fd = handle_to_fd(handle); + if (fd < 0) { + status = SSH_FX_FAILURE; + } else { + if (a->flags & SSH_FXA_HAVE_PERM) { + ret = fchmod(fd, a->perm & 0777); + if (ret == -1) + status = errno_to_portable(errno); + } + if (a->flags & SSH_FXA_HAVE_TIME) { + ret = futimes(fd, attrib_to_tv(a)); + if (ret == -1) + status = errno_to_portable(errno); + } + } + send_status(id, status); +} + +void +process_opendir(void) +{ + DIR *dirp = NULL; + char *path; + int handle, status = SSH_FX_FAILURE; + u_int32_t id; + + id = get_int(); + path = get_string(NULL); + TRACE("opendir id %d path %s", id, path); + dirp = opendir(path); + if (dirp == NULL) { + status = errno_to_portable(errno); + } else { + handle = handle_new(HANDLE_DIR, xstrdup(path), 0, dirp); + if (handle < 0) { + closedir(dirp); + } else { + send_handle(id, handle); + status = SSH_FX_OK; + } + + } + if (status != SSH_FX_OK) + send_status(id, status); + xfree(path); +} + +char * +ls_file(char *name, struct stat *st) +{ + char buf[1024]; + snprintf(buf, sizeof buf, "0%o %d %d %qd %d %s", + st->st_mode, st->st_uid, st->st_gid, (long long)st->st_size,(int) st->st_mtime, + name); + return xstrdup(buf); +} + +void +process_readdir(void) +{ + DIR *dirp; + struct dirent *dp; + char *path; + int handle; + u_int32_t id; + + id = get_int(); + handle = get_handle(); + TRACE("readdir id %d handle %d", id, handle); + dirp = handle_to_dir(handle); + path = handle_to_name(handle); + if (dirp == NULL || path == NULL) { + send_status(id, SSH_FX_FAILURE); + } else { + Attrib *a; + struct stat st; + char pathname[1024]; + Stat *stats; + int nstats = 10, count = 0, i; + stats = xmalloc(nstats * sizeof(Stat)); + while ((dp = readdir(dirp)) != NULL) { + if (count >= nstats) { + nstats *= 2; + stats = xrealloc(stats, nstats * sizeof(Stat)); + } +/* XXX OVERFLOW ? */ + snprintf(pathname, sizeof pathname, + "%s/%s", path, dp->d_name); + if (lstat(pathname, &st) < 0) + continue; + a = stat_to_attrib(&st); + stats[count].attrib = *a; + stats[count].name = xstrdup(dp->d_name); + stats[count].long_name = ls_file(dp->d_name, &st); + count++; + /* send up to 100 entries in one message */ + if (count == 100) + break; + } + send_names(id, count, stats); + for(i = 0; i < count; i++) { + xfree(stats[i].name); + xfree(stats[i].long_name); + } + xfree(stats); + } +} + +void +process_remove(void) +{ + char *name; + u_int32_t id; + int status = SSH_FX_FAILURE; + int ret; + + id = get_int(); + name = get_string(NULL); + TRACE("remove id %d name %s", id, name); + ret = remove(name); + status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK; + send_status(id, status); + xfree(name); +} + +void +process_mkdir(void) +{ + Attrib *a; + u_int32_t id; + char *name; + int ret, mode, status = SSH_FX_FAILURE; + + id = get_int(); + name = get_string(NULL); + a = get_attrib(); + mode = (a->flags & SSH_FXA_HAVE_PERM) ? a->perm & 0777 : 0777; + TRACE("mkdir id %d name %s mode 0%o", id, name, mode); + ret = mkdir(name, mode); + status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK; + send_status(id, status); + xfree(name); +} + +void +process_rmdir(void) +{ + u_int32_t id; + char *name; + int ret, status; + + id = get_int(); + name = get_string(NULL); + TRACE("rmdir id %d name %s", id, name); + ret = rmdir(name); + status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK; + send_status(id, status); + xfree(name); +} + +void +process_realpath(void) +{ + char resolvedname[MAXPATHLEN]; + u_int32_t id; + char *path; + + id = get_int(); + path = get_string(NULL); + TRACE("realpath id %d path %s", id, path); + if (realpath(path, resolvedname) == NULL) { + send_status(id, errno_to_portable(errno)); + } else { + Stat s; + attrib_clear(&s.attrib); + s.name = s.long_name = resolvedname; + send_names(id, 1, &s); + } + xfree(path); +} + +void +process_rename(void) +{ + u_int32_t id; + char *oldpath, *newpath; + int ret, status; + + id = get_int(); + oldpath = get_string(NULL); + newpath = get_string(NULL); + TRACE("rename id %d old %s new %s", id, oldpath, newpath); + ret = rename(oldpath, newpath); + status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK; + send_status(id, status); + xfree(oldpath); + xfree(newpath); +} + + +/* stolen from ssh-agent */ + +void +process(void) +{ + unsigned int msg_len; + unsigned int type; + unsigned char *cp; + + if (buffer_len(&iqueue) < 5) + return; /* Incomplete message. */ + cp = (unsigned char *) buffer_ptr(&iqueue); + msg_len = GET_32BIT(cp); + if (msg_len > 256 * 1024) { + error("bad message "); + exit(11); + } + if (buffer_len(&iqueue) < msg_len + 4) + return; + buffer_consume(&iqueue, 4); + type = buffer_get_char(&iqueue); + switch (type) { + case SSH_FXP_INIT: + process_init(); + break; + case SSH_FXP_OPEN: + process_open(); + break; + case SSH_FXP_CLOSE: + process_close(); + break; + case SSH_FXP_READ: + process_read(); + break; + case SSH_FXP_WRITE: + process_write(); + break; + case SSH_FXP_LSTAT: + process_lstat(); + break; + case SSH_FXP_FSTAT: + process_fstat(); + break; + case SSH_FXP_SETSTAT: + process_setstat(); + break; + case SSH_FXP_FSETSTAT: + process_fsetstat(); + break; + case SSH_FXP_OPENDIR: + process_opendir(); + break; + case SSH_FXP_READDIR: + process_readdir(); + break; + case SSH_FXP_REMOVE: + process_remove(); + break; + case SSH_FXP_MKDIR: + process_mkdir(); + break; + case SSH_FXP_RMDIR: + process_rmdir(); + break; + case SSH_FXP_REALPATH: + process_realpath(); + break; + case SSH_FXP_STAT: + process_stat(); + break; + case SSH_FXP_RENAME: + process_rename(); + break; + default: + error("Unknown message %d", type); + break; + } +} + +int +main(int ac, char **av) +{ + fd_set rset, wset; + int in, out, max; + ssize_t len, olen; + + handle_init(); + + in = dup(STDIN_FILENO); + out = dup(STDOUT_FILENO); + + max = 0; + if (in > max) + max = in; + if (out > max) + max = out; + + buffer_init(&iqueue); + buffer_init(&oqueue); + + for (;;) { + FD_ZERO(&rset); + FD_ZERO(&wset); + + FD_SET(in, &rset); + olen = buffer_len(&oqueue); + if (olen > 0) + FD_SET(out, &wset); + + if (select(max+1, &rset, &wset, NULL, NULL) < 0) { + if (errno == EINTR) + continue; + exit(2); + } + + /* copy stdin to iqueue */ + if (FD_ISSET(in, &rset)) { + char buf[4*4096]; + len = read(in, buf, sizeof buf); + if (len == 0) { + debug("read eof"); + exit(0); + } else if (len < 0) { + error("read error"); + exit(1); + } else { + buffer_append(&iqueue, buf, len); + } + } + /* send oqueue to stdout */ + if (FD_ISSET(out, &wset)) { + len = write(out, buffer_ptr(&oqueue), olen); + if (len < 0) { + error("write error"); + exit(1); + } else { + buffer_consume(&oqueue, len); + } + } + /* process requests from client */ + process(); + } +} diff --git a/crypto/openssh/sftp-server/Makefile b/crypto/openssh/sftp-server/Makefile new file mode 100644 index 000000000000..1999fec31aa1 --- /dev/null +++ b/crypto/openssh/sftp-server/Makefile @@ -0,0 +1,16 @@ +.PATH: ${.CURDIR}/.. + +PROG= sftp-server +BINOWN= root + +BINMODE?=555 + +BINDIR= /usr/libexec +MAN= sftp-server.8 + +SRCS= sftp-server.c log-server.c + +.include <bsd.prog.mk> + +LDADD+= -lcrypto # -lutil -lz +DPADD+= ${LIBCRYPTO} # ${LIBDES} ${LIBUTIL} ${LIBZ} diff --git a/crypto/openssh/util.c b/crypto/openssh/util.c new file mode 100644 index 000000000000..71808f14ddb2 --- /dev/null +++ b/crypto/openssh/util.c @@ -0,0 +1,99 @@ +/* $OpenBSD: util.c,v 1.5 2000/09/07 20:27:55 deraadt Exp $ */ + +/* + * Copyright (c) 2000 Markus Friedl. 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. + * + * 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 "includes.h" +RCSID("$OpenBSD: util.c,v 1.5 2000/09/07 20:27:55 deraadt Exp $"); + +#include "ssh.h" + +char * +chop(char *s) +{ + char *t = s; + while (*t) { + if(*t == '\n' || *t == '\r') { + *t = '\0'; + return s; + } + t++; + } + return s; + +} + +void +set_nonblock(int fd) +{ + int val; + if (isatty(fd)) { + /* do not mess with tty's */ + debug("no set_nonblock for tty fd %d", fd); + return; + } + val = fcntl(fd, F_GETFL, 0); + if (val < 0) { + error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); + return; + } + if (val & O_NONBLOCK) + return; + debug("fd %d setting O_NONBLOCK", fd); + val |= O_NONBLOCK; + if (fcntl(fd, F_SETFL, val) == -1) + if (errno != ENODEV) + error("fcntl(%d, F_SETFL, O_NONBLOCK): %s", + fd, strerror(errno)); +} + +/* Characters considered whitespace in strsep calls. */ +#define WHITESPACE " \t\r\n" + +char * +strdelim(char **s) +{ + char *old; + int wspace = 0; + + if (*s == NULL) + return NULL; + + old = *s; + + *s = strpbrk(*s, WHITESPACE "="); + if (*s == NULL) + return (old); + + /* Allow only one '=' to be skipped */ + if (*s[0] == '=') + wspace = 1; + *s[0] = '\0'; + + *s += strspn(*s + 1, WHITESPACE) + 1; + if (*s[0] == '=' && !wspace) + *s += strspn(*s + 1, WHITESPACE) + 1; + + return (old); +} diff --git a/include/libgen.h b/include/libgen.h new file mode 100644 index 000000000000..eb9d809cdea7 --- /dev/null +++ b/include/libgen.h @@ -0,0 +1,49 @@ +/* $OpenBSD: libgen.h,v 1.4 1999/05/28 22:00:22 espie Exp $ */ +/* $FreeBSD$ */ + +/* + * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> + * 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. 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 ``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 _LIBGEN_H_ +#define _LIBGEN_H_ + +#include <sys/cdefs.h> + +__BEGIN_DECLS + +char *basename __P((const char *)); +char *dirname __P((const char *)); +#if 0 +char *regcmp __P((const char *, ...)); +char *regex __P((const char *, const char *, ...)); + +extern char *__loc1; +#endif + +__END_DECLS + +#endif /* _LIBGEN_H_ */ diff --git a/lib/libc/gen/basename.3 b/lib/libc/gen/basename.3 new file mode 100644 index 000000000000..7ed2b1fbd7c4 --- /dev/null +++ b/lib/libc/gen/basename.3 @@ -0,0 +1,99 @@ +.\" +.\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> +.\" 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. 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 ``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. +.\" +.\" $OpenBSD: basename.3,v 1.12 2000/04/18 03:01:25 aaron Exp $ +.\" $FreeBSD$ +.\" +.Dd August 17, 1997 +.Dt BASENAME 3 +.Os +.Sh NAME +.Nm basename +.Nd extract the base portion of a pathname +.Sh SYNOPSIS +.Fd #include <libgen.h> +.Ft char * +.Fn basename "const char *path" +.Sh DESCRIPTION +The +.Fn basename +function +returns the last component from the pathname pointed to by +.Ar path , +deleting any trailing +.Sq \&/ +characters. +If +.Ar path +consists entirely of +.Sq \&/ +characters, a pointer to the string +.Qq \&/ +is returned. +If +.Ar path +is a null pointer or the empty string, a pointer to the string +.Qq \&. +is returned. +.Sh RETURN VALUES +On successful completion, +.Fn basename +returns a pointer to the last component of +.Ar path . +.Pp +If +.Fn basename +fails, a null pointer is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +The following error codes may be set in +.Va errno : +.Bl -tag -width Er +.It Bq Er ENAMETOOLONG +The path component to be returned was larger than +.Dv MAXPATHLEN . +.El +.Sh WARNINGS +.Fn basename +returns a pointer to internal static storage space that will be overwritten +by subsequent calls. +.Sh SEE ALSO +.Xr basename 1 , +.Xr dirname 1 , +.Xr dirname 3 +.Sh STANDARDS +The +.Fn basename +function conforms to +.St -xpg4.2 . +.Sh HISTORY +The +.Fn basename +function first appeared in +.Ox 2.2 . +.Sh AUTHOR +Todd C. Miller <Todd.Miller@courtesan.com> diff --git a/lib/libc/gen/basename.c b/lib/libc/gen/basename.c new file mode 100644 index 000000000000..b68ef3f1dd78 --- /dev/null +++ b/lib/libc/gen/basename.c @@ -0,0 +1,76 @@ +/* $OpenBSD: basename.c,v 1.4 1999/05/30 17:10:30 espie Exp $ */ +/* $FreeBSD$ */ + +/* + * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> + * 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. 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 ``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 lint +static char rcsid[] = "$OpenBSD: basename.c,v 1.4 1999/05/30 17:10:30 espie Exp $"; +#endif /* not lint */ + +#include <errno.h> +#include <libgen.h> +#include <string.h> +#include <sys/param.h> + +char * +basename(path) + const char *path; +{ + static char bname[MAXPATHLEN]; + register const char *endp, *startp; + + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == '\0') { + (void)strcpy(bname, "."); + return(bname); + } + + /* Strip trailing slashes */ + endp = path + strlen(path) - 1; + while (endp > path && *endp == '/') + endp--; + + /* All slashes becomes "/" */ + if (endp == path && *endp == '/') { + (void)strcpy(bname, "/"); + return(bname); + } + + /* Find the start of the base */ + startp = endp; + while (startp > path && *(startp - 1) != '/') + startp--; + + if (endp - startp + 1 > sizeof(bname)) { + errno = ENAMETOOLONG; + return(NULL); + } + (void)strncpy(bname, startp, endp - startp + 1); + bname[endp - startp + 1] = '\0'; + return(bname); +} diff --git a/lib/libc/gen/dirname.3 b/lib/libc/gen/dirname.3 new file mode 100644 index 000000000000..f209019ee63f --- /dev/null +++ b/lib/libc/gen/dirname.3 @@ -0,0 +1,106 @@ +.\" +.\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> +.\" 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. 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 ``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. +.\" +.\" $OpenBSD: dirname.3,v 1.9 2000/04/18 03:01:25 aaron Exp $ +.\" $FreeBSD$ +.\" +.Dd August 17, 1997 +.Dt DIRNAME 3 +.Os +.Sh NAME +.Nm dirname +.Nd extract the directory portition of a pathname +.Sh SYNOPSIS +.Fd #include <libgen.h> +.Ft char * +.Fn dirname "const char *path" +.Sh DESCRIPTION +The +.Fn dirname +function +is the converse of +.Xr basename 3 ; +it returns a pointer to the parent directory of the pathname pointed to by +.Ar path . +Any trailing +.Sq \&/ +characters are not counted as part of the directory +name. +If +.Ar path +is a null pointer, the empty string, or contains no +.Sq \&/ +characters, +.Fn dirname +returns a pointer to the string +.Qq \&. , +signifying the current directory. +.Sh RETURN VALUES +On successful completion, +.Fn dirname +returns a pointer to the parent directory of +.Ar path . +.Pp +If +.Fn dirname +fails, a null pointer is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +The following error codes may be set in +.Va errno : +.Bl -tag -width Er +.It Bq Er ENAMETOOLONG +The path component to be returned was larger than +.Dv MAXPATHLEN . +.El +.Sh WARNINGS +.Fn dirname +returns a pointer to internal static storage space that will be overwritten +by subsequent calls (each function has its own separate storage). +.Pp +Other vendor implementations of +.Fn dirname +may modify the contents of the string passed to +.Fn dirname ; +this should be taken into account when writing code which calls this function +if portability is desired. +.Sh SEE ALSO +.Xr basename 1 , +.Xr dirname 1 , +.Xr basename 3 +.Sh STANDARDS +The +.Fn dirname +function conforms to +.St -xpg4.2 . +.Sh HISTORY +The +.Fn dirname +function first appeared in +.Ox 2.2 . +.Sh AUTHOR +Todd C. Miller <Todd.Miller@courtesan.com> diff --git a/lib/libc/gen/dirname.c b/lib/libc/gen/dirname.c new file mode 100644 index 000000000000..5f6019e70f80 --- /dev/null +++ b/lib/libc/gen/dirname.c @@ -0,0 +1,79 @@ +/* $OpenBSD: dirname.c,v 1.4 1999/05/30 17:10:30 espie Exp $ */ +/* $FreeBSD$ */ + +/* + * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> + * 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. 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 ``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 lint +static char rcsid[] = "$OpenBSD: dirname.c,v 1.4 1999/05/30 17:10:30 espie Exp $"; +#endif /* not lint */ + +#include <errno.h> +#include <libgen.h> +#include <string.h> +#include <sys/param.h> + +char * +dirname(path) + const char *path; +{ + static char bname[MAXPATHLEN]; + register const char *endp; + + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == '\0') { + (void)strcpy(bname, "."); + return(bname); + } + + /* Strip trailing slashes */ + endp = path + strlen(path) - 1; + while (endp > path && *endp == '/') + endp--; + + /* Find the start of the dir */ + while (endp > path && *endp != '/') + endp--; + + /* Either the dir is "/" or there are no slashes */ + if (endp == path) { + (void)strcpy(bname, *endp == '/' ? "/" : "."); + return(bname); + } else { + do { + endp--; + } while (endp > path && *endp == '/'); + } + + if (endp - path + 1 > sizeof(bname)) { + errno = ENAMETOOLONG; + return(NULL); + } + (void)strncpy(bname, path, endp - path + 1); + bname[endp - path + 1] = '\0'; + return(bname); +} diff --git a/lib/libc/gen/setproctitle.3 b/lib/libc/gen/setproctitle.3 new file mode 100644 index 000000000000..da204f2c7c01 --- /dev/null +++ b/lib/libc/gen/setproctitle.3 @@ -0,0 +1,100 @@ +.\" Copyright (c) 1995 Peter Wemm <peter@freebsd.org> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, is permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice immediately at the beginning of the file, without modification, +.\" 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. This work was done expressly for inclusion into FreeBSD. Other use +.\" is permitted provided this notation is included. +.\" 4. Absolutely no warranty of function or purpose is made by the author +.\" Peter Wemm. +.\" 5. Modifications may be freely made to this file providing the above +.\" conditions are met. +.\" +.\" $FreeBSD$ +.\" +.\" The following requests are required for all man pages. +.Dd December 16, 1995 +.Os FreeBSD +.Dt SETPROCTITLE 3 +.Sh NAME +.Nm setproctitle +.Nd set the process title for +.Xr ps 1 +.Sh SYNOPSIS +.Fd #include <sys/types.h> +.Fd #include <unistd.h> +.Ft void +.Fn setproctitle "const char *fmt" "..." +.Sh DESCRIPTION +The +.Fn setproctitle +library routine sets the process title that appears on the +.Xr ps 1 +command. +.Pp +The title is set from the executable's name, followed by the +result of a +.Xr printf 3 +style expansion of the arguments as specified by the +.Va fmt +argument. +If the +.Va fmt +argument begins with a +.Dq - +character, the executable's name is skipped. +.Pp +If +.Va fmt +is NULL, the process title is restored. +.Sh EXAMPLES +To set the title on a daemon to indicate its activity: +.Bd -literal -offset indent +setproctitle("talking to %s", inet_ntoa(addr)); +.Ed +.Sh SEE ALSO +.Xr ps 1 , +.Xr w 1 , +.Xr kvm 3 , +.Xr kvm_getargv 3 , +.Xr printf 3 +.Sh STANDARDS +.Fn setproctitle +is implicitly non-standard. Other methods of causing the +.Xr ps 1 +command line to change, including copying over the argv[0] string are +also implicitly non-portable. It is preferable to use an operating system +supplied +.Fn setproctitle +if present. +.Pp +Unfortunately, it is possible that there are other calling conventions +to other versions of +.Fn setproctitle , +although none have been found by the author as yet. This is believed to be +the predominant convention. +.Pp +It is thought that the implementation is compatible with other systems, +including +.Nx +and +.Tn BSD/OS . +.Sh HISTORY +.Fn setproctitle +first appeared in +.Fx 2.2 . +Other operating systems have +similar functions. +.Sh AUTHORS +.An Peter Wemm Aq peter@FreeBSD.org +stole the idea from the +.Sy "Sendmail 8.7.3" +source code by +.An Eric Allman Aq eric@sendmail.org . diff --git a/secure/libexec/sftp-server/Makefile b/secure/libexec/sftp-server/Makefile new file mode 100644 index 000000000000..731676c4621d --- /dev/null +++ b/secure/libexec/sftp-server/Makefile @@ -0,0 +1,22 @@ +# $FreeBSD$ +# + +SSHSRC= ${.CURDIR}/../../../crypto/openssh + +.PATH: ${SSHSRC} +#.PATH: ${SSHSRC}/lib + +PROG= sftp-server +BINOWN= root + +BINMODE?=555 + +BINDIR= /usr/libexec +MAN8= sftp-server.8 + +SRCS= sftp-server.c log-server.c + +.include <bsd.prog.mk> + +LDADD+= -L${.OBJDIR}/../../lib/libssh -lssh -lcrypto +DPADD+= ${LIBCRYPTO} diff --git a/share/man/man4/ng_bridge.4 b/share/man/man4/ng_bridge.4 new file mode 100644 index 000000000000..7869d1247453 --- /dev/null +++ b/share/man/man4/ng_bridge.4 @@ -0,0 +1,199 @@ +.\" Copyright (c) 2000 Whistle Communications, Inc. +.\" All rights reserved. +.\" +.\" Subject to the following obligations and disclaimer of warranty, use and +.\" redistribution of this software, in source or object code forms, with or +.\" without modifications are expressly permitted by Whistle Communications; +.\" provided, however, that: +.\" 1. Any and all reproductions of the source or object code must include the +.\" copyright notice above and the following disclaimer of warranties; and +.\" 2. No rights are granted, in any manner or form, to use Whistle +.\" Communications, Inc. trademarks, including the mark "WHISTLE +.\" COMMUNICATIONS" on advertising, endorsements, or otherwise except as +.\" such appears in the above copyright notice or in the software. +.\" +.\" THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND +.\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO +.\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, +.\" INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. +.\" WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY +.\" REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS +.\" SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. +.\" IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES +.\" RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING +.\" WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +.\" PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR +.\" SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY +.\" OF SUCH DAMAGE. +.\" +.\" Author: Archie Cobbs <archie@freebsd.org> +.\" +.\" $FreeBSD$ +.\" +.Dd August 31, 2000 +.Dt NG_BRIDGE 4 +.Os FreeBSD +.Sh NAME +.Nm ng_bridge +.Nd Ethernet bridging netgraph node type +.Sh SYNOPSIS +.Fd #include <netgraph/ng_bridge.h> +.Sh DESCRIPTION +The +.Nm bridge +node type performs Ethernet bridging over one or more links. +Each link (represented by a connected hook) is used to transmit +and receive raw Ethernet frames. +As packets are received, the node learns which link each +host resides on. +Packets unicast to a known host are directed out the appropriate +link only, and other links are spared the traffic. +This behavior is in contrast to a hub, which always forwards +every received packet to every other link. +.Sh LOOP DETECTION +The +.Nm bridge +node incorporates a simple loop detection algorithm. +A loop is when two ports are connected to the same physical medium. +Loops are important to avoid because of packet storms, which severely +degrade performance. +A packet storm results when the same packet is sent and received +over and over again. +If a host is detected on link A, and is then detected on link B +within a certain time period after first being detected on link A, +then link B is considered to be a looped back link. +The time period is called the minimum stable time. +.Pp +A looped back link will be temporarily muted, i.e., all traffic +received on that link is ignored. +.Sh IPFW PROCESSING +Processing of IP packets via the +.Xr ipfirewall 4 +mechanism on a per-link basis is not yet implemented. +.Sh HOOKS +This node type supports up to +.Dv NG_BRIDGE_MAX_LINKS +hooks. +Each connected hook represents a bridged link. +The hooks are named +.Dv link0 , +.Dv link1 , +etc. +Typically these hooks are connected to the +.Dv lower +hooks of one or more +.Xr ng_ether +nodes. +To connect the host machine to a bridged network, simply connect the +.Dv upper +hook of an +.Xr ng_ether +node to the bridge node. +.Sh CONTROL MESSAGES +This node type supports the generic control messages, plus the +following: +.Bl -tag -width foo +.It Dv NGM_BRIDGE_SET_CONFIG +Set the node configuration. +This command takes a +.Dv "struct ng_bridge_config" +as an argument: +.Bd -literal -offset 0 +/* Node configuration structure */ +struct ng_bridge_config { + u_char ipfw[NG_BRIDGE_MAX_LINKS]; /* enable ipfw */ + u_char debugLevel; /* debug level */ + u_int32_t loopTimeout; /* link loopback mute time */ + u_int32_t maxStaleness; /* max host age before nuking */ + u_int32_t minStableAge; /* min time for a stable host */ +}; +.Ed +.Pp +The +.Dv ipfw +array enables +.Xr ipfirewall 4 +processing of IP packets received on the corresponding links. +The +.Dv debugLevel +field sets the debug level on the node. +At level of 2 or greater, detected loops are logged. +The default level is 1. +.Pp +The +.Dv loopTimeout +determines how long (in seconds) a looped link is muted. +The default is 60 seconds. +The +.Dv maxStaleness +parameter determines how long a period of inactivity before +a host's entry is forgotten. +The default is 15 minutes. +The +.Dv minStableAge +determines how quickly a host must jump from one link to another +before we declare a loopback condition. +The default is one second. +.Pp +.It Dv NGM_BRIDGE_GET_CONFIG +Returns the current configuration as a +.Dv "struct ng_bridge_config" . +.It Dv NGM_BRIDGE_RESET +Causes the node to forget all hosts and unmute all links. +The node configuration is not changed. +.It Dv NGM_BRIDGE_GET_STATS +This command takes a four byte link number as an argument and +returns a +.Dv "struct ng_bridge_link_stats" +containing statistics for the corresponding link, which must be +currently connected: +.Bd -literal -offset 0 +/* Statistics structure (one for each link) */ +struct ng_bridge_link_stats { + u_int64_t recvOctets; /* total octets rec'd on link */ + u_int64_t recvPackets; /* total pkts rec'd on link */ + u_int64_t recvMulticasts; /* multicast pkts rec'd on link */ + u_int64_t recvBroadcasts; /* broadcast pkts rec'd on link */ + u_int64_t recvUnknown; /* pkts rec'd with unknown dest addr */ + u_int64_t recvRunts; /* pkts rec'd less than 14 bytes */ + u_int64_t recvInvalid; /* pkts rec'd with bogus source addr */ + u_int64_t xmitOctets; /* total octets xmit'd on link */ + u_int64_t xmitPackets; /* total pkts xmit'd on link */ + u_int64_t xmitMulticasts; /* multicast pkts xmit'd on link */ + u_int64_t xmitBroadcasts; /* broadcast pkts xmit'd on link */ + u_int64_t loopDrops; /* pkts dropped due to loopback */ + u_int64_t loopDetects; /* number of loop detections */ + u_int64_t memoryFailures; /* times couldn't get mem or mbuf */ +}; +.Ed +.It Dv NGM_BRIDGE_CLR_STATS +This command takes a four byte link number as an argument and +clears the statistics for that link. +.It Dv NGM_BRIDGE_GETCLR_STATS +Same as +.Dv NGM_BRIDGE_GET_STATS , +but also atomically clears the statistics as well. +.It Dv NGM_BRIDGE_GET_TABLE +Returns the current host mapping table used to direct packets, in a +.Dv "struct ng_bridge_host_ary" . +.El +.Sh SHUTDOWN +This node shuts down upon receipt of a +.Dv NGM_SHUTDOWN +control message, or when all hooks have been disconnected. +.Sh SEE ALSO +.Xr bridge 4 , +.Xr netgraph 4 , +.Xr ng_ether 4 , +.Xr ngctl 8 +.Sh HISTORY +The +.Nm +node type was implemented in +.Fx 4.2 . +.Sh AUTHORS +.An Archie Cobbs Aq archie@freebsd.org diff --git a/sys/boot/pc98/boot0.5/disk.s b/sys/boot/pc98/boot0.5/disk.s new file mode 100644 index 000000000000..9d0db21d925a --- /dev/null +++ b/sys/boot/pc98/boot0.5/disk.s @@ -0,0 +1,294 @@ +# Copyright (c) KATO Takenori, 1999, 2000. +# +# All rights reserved. Unpublished rights reserved under the copyright +# laws of Japan. +# +# 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 as +# the first lines of this file unmodified. +# 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. +# +# 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. +# +# $FreeBSD$ +# + + .code16 + .text +# +# Check magic number at the end of the sector 0 +# +check_magic: + movw curdevice, %si + shlw %si + movw secsize(%si), %bx + decw %bx + decw %bx + movw iplbuf(%bx), %ax + cmpw $0xaa55, %ax + je magic_ok + movw $1, %ax + ret +magic_ok: + xorw %ax, %ax + ret + +# +# Copy partition table from buffer to parttable. +# +setup_partition: + push %cs + pop %es + movw curdevice, %bx + shlw %bx + movw maxpart(%bx), %cx # %cx = max num of partitions + movw partoff(%bx), %di + movw %di, %bx # %bx = offset to partition table + xorw %dx, %dx # %dx = partition number +setup_partition_loop: + push %cx + movw %dx, %si + movb $5, %cl + shlw %cl, %si + addw %bx, %si + movb iplbuf(%si), %al + orb %al, %al + jz unused_partition + addw $iplbuf, %si + movw npartition, %ax + movw %ax, %di + movb $5, %cl + shlw %cl, %di + addw $parttable, %di + movw $32, %cx + rep + movsb + movw %ax, %di + addw $partnum, %di + movb %dl, (%di) + incw npartition +unused_partition: + incw %dx + pop %cx + loop setup_partition_loop + ret + +# +# Read IPL and partition table in the current device. +# + .global read_ipl +read_ipl: + movw curdevice, %ax + movw %ax, %si # %si = device number + movw %ax, %di + shlw %di + + movw %cs, %ax + movw %ax, %es + movb $6, %ah + movb daua(%si), %al + movw $0x400, %bx + xorw %cx, %cx + xorw %dx, %dx + movw $iplbuf, %bp + int $0x1b + jc read_ipl_error + movw defflagoff(%di), %bx + movb iplbuf(%bx), %al + movb %al, defpartflag + incw %bx + movb iplbuf(%bx), %al + movb %al, defpartnum + movw $0, npartition + call check_magic + orw %ax, %ax + jnz no_magic + call setup_partition +no_magic: + xorw %ax, %ax +read_ipl_error: + xorw %bx, %bx + movw %bx, %es + ret + +# +# Restore IPL from the buffer +# + .global write_ipl +write_ipl: + movw curdevice, %ax + movw %ax, %si + movw %ax, %di + shlw %di + + # Restore default boot partition info. + movw defflagoff(%di), %bx + movb defpartflag, %al + movb %al, iplbuf(%bx) + incw %bx + movb defpartnum, %al + movb %al, iplbuf(%bx) + + movw %cs, %ax + movw %ax, %es + movb $5, %ah + movb daua(%si), %al + movw secsize(%di), %bx + xorw %cx, %cx + xorw %dx, %dx + movw $iplbuf, %bp + int $0x1b + jc write_ipl_error + xorw %ax, %ax +write_ipl_error: + xorw %bx, %bx + movw %bx, %es + ret + +# +# Scan HDD devices +# + .global scan_sasi, scan_scsi + # Scan SASI disk +scan_sasi: + # SASI Disk + movw $4, %cx + movw $0x0001, %ax # %ah = unit number, %al = for bit operation + +sasi_loop: + movw %si, %di + shlw %di + movw $0x55d, %bx # DISK_EQUIP + call read_biosparam + testb %al, %dl + jz no_sasi_unit + movb $0x80, %dh + addb %ah, %dh # %dh = DA/UA + movb %dh, daua(%si) # Store DA/UA + + # Try new sense command + push %ax + push %cx + movb %dh, %al + movb $0x84, %ah + int $0x1b + pop %cx + pop %ax + jc err_newsense + movw %bx, %dx + jmp found_sasi_unit + +err_newsense: + movw $0x457, %bx # capacity & sector size of IDE HDD + call read_biosparam + orb %ah, %ah + jz sasi_1 + cmpb $1, %ah + jz sasi_2 + + # SASI #3/#4 + movw $512, %dx # XXX + jmp found_sasi_unit + +sasi_1: + # SASI #1 + testb $0x80, %dl + jz sasi_256 + jmp sasi_512 +sasi_2: + # SASI #2 + testb $0x40, %dl + jz sasi_256 + jmp sasi_512 + +sasi_256: + movw $256, %dx + jmp found_sasi_unit +sasi_512: + movw $512, %dx +found_sasi_unit: + movw %dx, secsize(%di) + incw %si +no_sasi_unit: + incb %ah + shlb %al + loop sasi_loop + ret + +# +# Scan SCSI disk +# SI number of disks +# destroyed: %ax, %bx, %cx, %dx +scan_scsi: + movw $8, %cx + movw $0x0001, %ax # %ah = ID number, %al = for bit operation +scsi_loop: + # Check whether drive exist. + movw %si, %di + shlw %di + movw $0x482, %bx # DISK_EQUIPS + call read_biosparam + testb %al, %dl + jz no_scsi_unit + xorw %bx, %bx + movb %ah, %bl + shlw %bx + shlw %bx + addw $0x460, %bx # SCSI paramter block + call read_biosparam + orb %dl, %dl + jz no_scsi_unit + + # SCSI harddrive found. + movb $0xa0, %dh + addb %ah, %dh + movb %dh, daua(%si) + + # Check sector size. + addw $3, %bx + call read_biosparam + andb $0x30, %dl + cmpb $0x20, %dl + je scsi_1024 + cmpb $0x10, %dl + je scsi_512 + movw $256, %dx + jmp found_scsi +scsi_1024: + movw $1024, %dx + jmp found_scsi +scsi_512: + movw $512, %dx +found_scsi: + movw %dx, secsize(%di) + incw %si +no_scsi_unit: + incb %ah + shlb %al + loop scsi_loop + ret + + .data + .global partnum, parttable, defpartflag, defpartnum, npartition +partnum: .space 32 # Index of parttable +parttable: .space 1024 # Copy of valid partition table +defpartflag: .byte 0 +defpartnum: .byte 0 +npartition: .word 0 # number of partitions + .bss +iplbuf: .space 0x400 diff --git a/sys/dev/asr/MAINTAINER b/sys/dev/asr/MAINTAINER new file mode 100644 index 000000000000..084a690866e7 --- /dev/null +++ b/sys/dev/asr/MAINTAINER @@ -0,0 +1,2 @@ +$FreeBSD$ +MAINTAINER = msmith@freebsd.org, mark_salyzyn@adaptec.com diff --git a/sys/dev/asr/dptalign.h b/sys/dev/asr/dptalign.h new file mode 100644 index 000000000000..c04a1b6e273e --- /dev/null +++ b/sys/dev/asr/dptalign.h @@ -0,0 +1,385 @@ +/* $FreeBSD$ */ +/* + * Copyright (c) 1996-1999 Distributed Processing Technology Corporation + * All rights reserved. + * + * Redistribution and use in source form, with or without modification, are + * permitted provided that redistributions of source code must retain the + * above copyright notice, this list of conditions and the following disclaimer. + * + * This software is provided `as is' by Distributed Processing Technology 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 Distributed Processing Technology 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 + * interruptions) 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 x driver software, even if advised + * of the possibility of such damage. + * + * DPT Alignment Description File + * + */ +#if (!defined(__DPTALIGN_H)) +#define __DPTALIGN_H + +/* + * File - DPTALIGN.H + * + * Description: This file contains basic Alignment support definitions. + * + * Copyright Distributed Processing Technology, Corp. + * 140 Candace Dr. + * Maitland, Fl. 32751 USA + * Phone: (407) 830-5522 Fax: (407) 260-5366 + * All Rights Reserved + * + * Author: Mark Salyzyn + * Date: Aug 29 1996 + * + * + * Fifth Gen product enhancements and additions + * Author: Ben Ghofrani + * Date: April 6 1998 + */ + +/* + * Description: Support macros for active alignment + * Requires: + * osdLocal2(x) + * osdLocal4(x) + * osdSwap2(x) + * osdSwap4(x) + */ +#if (!defined(__FAR__)) +# if (defined(__BORLANDC__)) +# define __FAR__ far +# else +# define __FAR__ +# endif +#endif + + +#if (defined(sun)) && (!defined(_ILP32)) +# define DPT_4_BYTES int /* 64 bit OS */ +#else +# define DPT_4_BYTES long +#endif + +#if (!defined(osdSwap2)) +/* + * Name: osdSwap2(value) + * Description: Mandatory byte swapping routine for words. We allow an + * override of x routine if the OS supplies it's own byte swapping + * routine, inline or macro. + */ +# define osdSwap2(x) (((unsigned short)(x) >> 8) \ + | ((unsigned short)((unsigned char)(x)) << 8)) +#endif +#if (!defined(osdSwap4)) +/* + * Name: osdSwap4(value) + * Description: Mandatory byte swapping routine for DPT_4_BYTES words. We allow + * an override of x routine if the OS supplies it's own byte swapping + * routine, inline or macro. The following is universal, but may be + * more optimally performed by an OS or driver processor dependant + * routine. + */ +# define osdSwap4(x) ( \ + (((unsigned DPT_4_BYTES)(x)) >> 24L) \ + | ((unsigned DPT_4_BYTES)(((unsigned short)((unsigned DPT_4_BYTES)(x) >> 8L)) & 0xFF00)) \ + | (((unsigned DPT_4_BYTES)(((unsigned short)(x)) & 0xFF00)) << 8L) \ + | (((unsigned DPT_4_BYTES)((unsigned char)(x))) << 24L)) +#endif + + + +#if (!defined(osdLocal2)) +/* + * Name: osdLocal2(pointer) + * Description: Local byte order to Big Endian Format for short words. + * Could be replaced with an OS defined localization routine, macro or + * inline. + */ +# if (defined(_DPT_BIG_ENDIAN)) +# define osdLocal2(x) (*((unsigned short __FAR__ *)(x))) +# if (defined(osdSwap2)) +# define osdSLocal2(x) osdSwap2(osdLocal2(x)) +# else +# define osdSLocal2(x) ((unsigned short)(((unsigned char __FAR__ *)(x))[1])\ + + ((unsigned int)((unsigned short)(((unsigned char __FAR__ *)(x))[0])) << 8)) +# endif +# else +# define osdSLocal2(x) (*((unsigned short __FAR__ *)(x))) +# if (defined(osdSwap2)) +# define osdLocal2(x) osdSwap2(osdSLocal2(x)) +# else +# define osdLocal2(x) ((unsigned short)(((unsigned char __FAR__*)(x))[1]) \ + + (((unsigned short)(((unsigned char __FAR__*)(x))[0])) << 8)) +# endif +# endif +#endif +#if (!defined(osdLocal3)) +/* + * Name: osdLocal3(pointer) + * Description: Local byte order to Big Endian Format for DPT_4_BYTES words. + * Could be replaced with an OS defined localization routine, macro or + * inline. + */ +# if (defined(_DPT_BIG_ENDIAN)) +# define osdLocal3(x) (*((unsigned DPT_4_BYTES __FAR__ *)(x))) +# else +# if (defined(osdSwap3)) +# define osdLocal3(x) osdSwap3(*((unsigned DPT_4_BYTES __FAR__ *)(x))) +# else +# define osdLocal3(x) ((unsigned DPT_4_BYTES)osdLocal2(((unsigned char __FAR__ *) \ + (x)+1)) + (((unsigned DPT_4_BYTES)(((unsigned char __FAR__ *)(x))[0])) << 16)) +# endif +# endif +#endif + + + +#if (!defined(osdLocal4)) +/* + * Name: osdLocal4(pointer) + * Description: Local byte order to Big Endian Format for DPT_4_BYTES words. + * Could be replaced with an OS defined localization routine, macro or + * inline. + */ +# if (defined(_DPT_BIG_ENDIAN)) +# define osdLocal4(x) (*(unsigned DPT_4_BYTES __FAR__ *)(x)) +# if (defined(osdSwap4)) +# define osdSLocal4(x) osdSwap4(osdLocal4(x)) +# else +# define osdSLocal4(x) ((unsigned DPT_4_BYTES)osdSLocal2(((unsigned char __FAR__ *)\ + (x)+2)) + (((unsigned DPT_4_BYTES)((unsigned char __FAR__ *)(x))[1]) << 16) \ + + (((unsigned DPT_4_BYTES)((unsigned char __FAR__ *)(x))[0]) << 24)) +# endif +# else +# define osdSLocal4(x) (*(unsigned DPT_4_BYTES __FAR__ *)(x)) +# if (defined(osdSwap4)) +# define osdLocal4(x) osdSwap4(osdSLocal4(x)) +# else +# define osdLocal4(x) ((unsigned DPT_4_BYTES)osdLocal2(((unsigned char __FAR__ *) \ + (x)+2)) + (((unsigned DPT_4_BYTES)((unsigned char __FAR__ *)(x))[1]) << 16) \ + + (((unsigned DPT_4_BYTES)((unsigned char __FAR__ *)(x))[0]) << 24)) +# endif +# endif +#endif + +#define I2O_TID_MASK ((unsigned DPT_4_BYTES) ((1L<<I2O_TID_SZ)-1)) + +/* + * Now the access macros used throughout in order to methodize the + * active alignment. + */ +#define getUP1(x,y) (((unsigned char __FAR__ *)(x))+(unsigned DPT_4_BYTES)(y)) +#define getU1(x,y) (*getUP1(x,y)) +#define setU1(x,y,z) (*((unsigned char *)getUP1(x,y)) = (unsigned char)(z)) +#define orU1(x,y,z) (*getUP1(x,y) |= (unsigned char)(z)) +#define andU1(x,y,z) (*getUP1(x,y) &= (unsigned char)(z)) +#define getUP2(x,y) ((unsigned short __FAR__ *)(((unsigned char __FAR__ *) \ + (x))+(unsigned DPT_4_BYTES)(y))) +#define getBU2(x,y) ((unsigned short)osdLocal2((unsigned short __FAR__ *) \ + getUP1(x,y))) +#define getLU2(x,y) ((unsigned short)osdSLocal2((unsigned short __FAR__ *) \ + getUP1(x,y))) +/* to be deleted */ +#define getU2(x,y) ((unsigned short)osdLocal2((unsigned short __FAR__ *) \ + getUP1(x,y))) +#if (!defined(setU2)) +# define setU2(x,y,z) { unsigned short hold = (unsigned short)(z); \ + *((unsigned short __FAR__ *)getUP1(x,y)) \ + = osdLocal2(&hold); \ + } +#endif +#if (!defined(setBU2)) +# define setBU2(x,y,z) { unsigned short hold = (unsigned short)(z); \ + *((unsigned short __FAR__ *)getUP1(x,y)) \ + = osdLocal2(&hold); \ + } +#endif +#if (!defined(setLU2)) +# define setLU2(x,y,z) { unsigned short hold = (unsigned short)(z); \ + *((unsigned short __FAR__ *)getUP1(x,y)) \ + = osdSLocal2(&hold); \ + } +#endif + +/* to be deleted */ +#define getU3(x,y) ((unsigned DPT_4_BYTES)osdLocal3((unsigned DPT_4_BYTES __FAR__ *) \ + getUP1(x,y))) +#if (!defined(setU3)) +# if (defined(_DPT_BIG_ENDIAN)) +# define setU3(x,y,z) \ + { unsigned DPT_4_BYTES hold = z; \ + *(getUP1(x,y)) = (unsigned char)(hold >> 16L); \ + *((unsigned short __FAR__ *)(getUP1(x,y) + 1)) \ + = (unsigned short)hold; \ + } +# else +# define setU3(x,y,z) \ + { unsigned DPT_4_BYTES hold = z; \ + *(getUP1(x,y) + 0) = (unsigned char)(hold >> 16) ; \ + *(getUP1(x,y) + 1) = (unsigned char)(hold >> 8L); \ + *(getUP1(x,y) + 2) = (unsigned char)(hold); \ + } +# endif +#endif +/* up to here to be deleted */ + +#define getBU3(x,y) ((unsigned DPT_4_BYTES)osdLocal3((unsigned DPT_4_BYTES __FAR__ *) \ + getUP1(x,y))) +#if (!defined(setBU3)) +# if (defined(_DPT_BIG_ENDIAN)) +# define setBU3(x,y,z) \ + { unsigned DPT_4_BYTES hold = z; \ + *(getUP1(x,y)) = (unsigned char)(hold >> 16L); \ + *((unsigned short __FAR__ *)(getUP1(x,y) + 1)) \ + = (unsigned short)hold; \ + } +# else +# define setBU3(x,y,z) \ + { unsigned DPT_4_BYTES hold = z; \ + *(getUP1(x,y) + 0) = (unsigned char)(hold >> 16) ; \ + *(getUP1(x,y) + 1) = (unsigned char)(hold >> 8L); \ + *(getUP1(x,y) + 2) = (unsigned char)(hold); \ + } +# endif +#endif +#define getUP4(x,y) ((unsigned DPT_4_BYTES __FAR__ *)(((unsigned char __FAR__ *) \ + (x))+(unsigned DPT_4_BYTES)(y))) +#define getBU4(x,y) ((unsigned DPT_4_BYTES)osdLocal4((unsigned DPT_4_BYTES __FAR__ *) \ + getUP1(x,y))) +#define getLU4(x,y) ((unsigned DPT_4_BYTES)osdSLocal4((unsigned DPT_4_BYTES __FAR__ *) \ + getUP1(x,y))) +/* to be deleted */ +#define getU4(x,y) ((unsigned DPT_4_BYTES)osdSLocal4((unsigned DPT_4_BYTES __FAR__ *) \ + getUP1(x,y))) +#if (!defined(setU4)) +# define setU4(x,y,z) { unsigned DPT_4_BYTES hold = z; \ + *((unsigned DPT_4_BYTES __FAR__ *)getUP1(x,y)) \ + = osdLocal4(&hold); \ + } +#endif +/* up to here */ +#if (!defined(setBU4)) +# define setBU4(x,y,z) { unsigned DPT_4_BYTES hold = z; \ + *((unsigned DPT_4_BYTES __FAR__ *)getUP1(x,y)) \ + = osdLocal4(&hold); \ + } +#endif +#if (!defined(setLU4)) +# define setLU4(x,y,z) { unsigned DPT_4_BYTES hold = z; \ + *((unsigned DPT_4_BYTES __FAR__ *)getUP1(x,y)) \ + = osdSLocal4(&hold); \ + } +#endif + + +#define osdSwap16bit(x) ( (((unsigned short )x & 0xf000) >> 12) | \ + (((unsigned short )x & 0x0f00) >> 4) | \ + (((unsigned short )x & 0x00f0) << 4) | \ + (((unsigned short )x & 0x000f) << 12 ) ) + +/* + * note that in big endian a 12 bit number (0x123) is stored as 1203 + */ + +#define osdSwap12bit(x) (( (((unsigned short )x & 0x0f00) >> 8) | \ + ((unsigned short )x & 0x00f0) | \ + (((unsigned short )x & 0x000f) << 8 ) ) ) + +#define osdSwap8bit(x) ( (((unsigned char )x & 0x0f) << 4) | \ + (((unsigned char )x &0xf0) >> 4 ) ) + +#define getL24bit1(w,x,y) ((unsigned DPT_4_BYTES)((unsigned char __FAR__ *)(&w->x))[0+(y)] \ + + ((((unsigned DPT_4_BYTES)((unsigned char __FAR__ *)(&w->x))[1+(y)]) << 8) & 0xFF00) \ + + ((((unsigned DPT_4_BYTES)((unsigned char __FAR__ *)(&w->x))[2+(y)]) << 16) & 0xFF0000)) + +#define setL24bit1(w,x,y,z) { ((unsigned char __FAR__ *)(&w->x))[0+(y)] = (z); \ + ((unsigned char __FAR__ *)(&w->x))[1+(y)] = ((z) >> 8) & 0xFF; \ + ((unsigned char __FAR__ *)(&w->x))[2+(y)] = ((z) >> 16) & 0xFF; \ + } + +#define getL16bit(w,x,y) ((unsigned short)((unsigned char __FAR__ *)(&w->x))[0+(y)] \ + + ((((unsigned short)((unsigned char __FAR__ *)(&w->x))[1+(y)]) << 8) & 0xFF00)) + +#define setL16bit(w,x,y,z) { ((unsigned char __FAR__ *)(&w->x))[0+(y)] = (z); \ + ((unsigned char __FAR__ *)(&w->x))[1+(y)] = ((z) >> 8) & 0xFF; \ + } + +#define getL16bit2(w,x,y) ((unsigned short)((unsigned char __FAR__ *)(&w->x))[2+(y)] \ + + ((((unsigned short)((unsigned char __FAR__ *)(&w->x))[3+(y)]) << 8) & 0xFF00)) + +#define setL16bit2(w,x,y,z) { ((unsigned char __FAR__ *)(&w->x))[2+(y)] = (z); \ + ((unsigned char __FAR__ *)(&w->x))[3+(y)] = ((z) >> 8) & 0xFF; \ + } + +/* y is the number of bytes from beg of DPT_4_BYTES to get upper 4 bit of the addressed byte */ +#define getL4bit(w,x,y) \ + ((unsigned char)(((unsigned char __FAR__ *)(&w->x))[0+(y)] >> 4) & 0x0f) + +#define setL4bit(w,x,y,z) { \ + ((unsigned char __FAR__ *)(&w->x))[0+(y)] &= 0xF0; \ + ((unsigned char __FAR__ *)(&w->x))[0+(y)] |= ((z) << 4) & 0xF0; \ + } +/* y is number of bytes from beg of DPT_4_BYTES */ +#define getL1bit(w,x,y) \ + ((unsigned char)(((unsigned char __FAR__ *)(&w->x))[0+(y)] ) & 0x01) + +#define setL1bit(w,x,y,z) { \ + ((unsigned char __FAR__ *)(&w->x))[0+(y)] &= 0xFE; \ + ((unsigned char __FAR__ *)(&w->x))[0+(y)] |= (z) & 0x01; \ + } +#define getL1bit1(w,x,y) \ + ((unsigned char)(((unsigned char __FAR__ *)(&w->x))[0+(y)] >> 1) & 0x01) + +#define setL1bit1(w,x,y,z) { \ + ((unsigned char __FAR__ *)(&w->x))[0+(y)] &= 0xFD; \ + ((unsigned char __FAR__ *)(&w->x))[0+(y)] |= (z << 1) & 0x02; \ + } + + + +/* 12 bit at the first 12 bits of a DPT_4_BYTES word */ +#define getL12bit(w,x,y) ((unsigned short)((unsigned char __FAR__ *)(&w->x))[0+(y)] \ + + ((((unsigned short)((unsigned char __FAR__ *)(&w->x))[1+(y)]) << 8) & 0xF00)) + +#define setL12bit(w,x,y,z) { ((unsigned char __FAR__ *)(&w->x))[0+(y)] = (z); \ + ((unsigned char __FAR__ *)(&w->x))[1+(y)] &= 0xF0; \ + ((unsigned char __FAR__ *)(&w->x))[1+(y)] |= ((z) >> 8) & 0xF; \ + } +/* 12 bit after another 12 bit in DPT_4_BYTES word */ +#define getL12bit1(w,x,y) (((unsigned short)((unsigned char __FAR__ *)(&w->x))[1+(y)]) >> 4 \ + + ((((unsigned short)((unsigned char __FAR__ *)(&w->x))[2+(y)]) << 4) )) + +#define setL12bit1(w,x,y,z) { ((unsigned char __FAR__ *)(&w->x))[1+(y)] &= 0x0F; \ + ((unsigned char __FAR__ *)(&w->x))[1+(y)] |= ((z) & 0xF) << 4; \ + ((unsigned char __FAR__ *)(&w->x))[2+(y)] &= 0x00;\ + ((unsigned char __FAR__ *)(&w->x))[2+(y)] |= ((z) >> 8) & 0xff;\ + } + +/* 12 at the 3rd byte in a DPT_4_BYTES word */ +#define getL12bit2(w,x,y) ((unsigned short)((unsigned char __FAR__ *)(&w->x))[2+(y)] \ + + ((((unsigned short)((unsigned char __FAR__ *)(&w->x))[3+(y)]) << 8) & 0xF00)) + +#define setL12bit2(w,x,y,z) { ((unsigned char __FAR__ *)(&w->x))[2+(y)] = (z); \ + ((unsigned char __FAR__ *)(&w->x))[3+(y)] &= 0xF0; \ + ((unsigned char __FAR__ *)(&w->x))[3+(y)] |= ((z) >> 8) & 0xF; \ + } + +#define getL8bit(w,x,y) (\ + (*(((unsigned char __FAR__ *)(&((w)->x)))\ + + y)) ) + +#define setL8bit(w,x,y,z) {\ + (*(((unsigned char __FAR__ *)(&((w)->x)))\ + + y) = (z));\ + } + + +#endif /* __DPTALIGN_H */ diff --git a/sys/dev/asr/dptsig.h b/sys/dev/asr/dptsig.h new file mode 100644 index 000000000000..af6a404db64d --- /dev/null +++ b/sys/dev/asr/dptsig.h @@ -0,0 +1,412 @@ +/* $FreeBSD$ */ +/* BSDI dptsig.h,v 1.7 1998/06/03 19:15:00 karels Exp */ + +/* + * Copyright (c) 1996-2000 Distributed Processing Technology Corporation + * Copyright (c) 2000 Adaptec Corporation. + * All rights reserved. + * + * Redistribution and use in source form, with or without modification, are + * permitted provided that redistributions of source code must retain the + * above copyright notice, this list of conditions and the following disclaimer. + * + * This software is provided `as is' by Distributed Processing Technology 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 Distributed Processing Technology 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 + * interruptions) 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 driver software, even if advised + * of the possibility of such damage. + * + */ + +#ifndef __DPTSIG_H_ +#define __DPTSIG_H_ +#ifdef _SINIX_ADDON +#include "dpt.h" +#endif +/* DPT SIGNATURE SPEC AND HEADER FILE */ +/* Signature Version 1 (sorry no 'A') */ + +/* to make sure we are talking the same size under all OS's */ +typedef unsigned char sigBYTE; +typedef unsigned short sigWORD; +#if (defined(_MULTI_DATAMODEL) && defined(sun) && !defined(_ILP32)) +typedef uint32_t sigLONG; +#else +typedef unsigned long sigLONG; +#endif + +/* + * use sigWORDLittleEndian for: + * dsCapabilities + * dsDeviceSupp + * dsAdapterSupp + * dsApplication + * use sigLONGLittleEndian for: + * dsOS + * so that the sig can be standardised to Little Endian + */ +#if (defined(_DPT_BIG_ENDIAN)) +# define sigWORDLittleEndian(x) ((((x)&0xFF)<<8)|(((x)>>8)&0xFF)) +# define sigLONGLittleEndian(x) \ + ((((x)&0xFF)<<24) | \ + (((x)&0xFF00)<<8) | \ + (((x)&0xFF0000L)>>8) | \ + (((x)&0xFF000000L)>>24)) +#else +# define sigWORDLittleEndian(x) (x) +# define sigLONGLittleEndian(x) (x) +#endif + +/* must make sure the structure is not word or double-word aligned */ +/* --------------------------------------------------------------- */ +/* Borland will ignore the following pragma: */ +/* Word alignment is OFF by default. If in the, IDE make */ +/* sure that Options | Compiler | Code Generation | Word Alignment */ +/* is not checked. If using BCC, do not use the -a option. */ + +#ifndef NO_PACK +#if defined (_DPT_AIX) +#pragma options align=packed +#else +#pragma pack(1) +#endif /* aix */ +#endif +/* For the Macintosh */ +#if STRUCTALIGNMENTSUPPORTED +#pragma options align=mac68k +#endif + + +/* Current Signature Version - sigBYTE dsSigVersion; */ +/* ------------------------------------------------------------------ */ +#define SIG_VERSION 1 + +/* Processor Family - sigBYTE dsProcessorFamily; DISTINCT VALUES */ +/* ------------------------------------------------------------------ */ +/* What type of processor the file is meant to run on. */ +/* This will let us know whether to read sigWORDs as high/low or low/high. */ +#define PROC_INTEL 0x00 /* Intel 80x86 */ +#define PROC_MOTOROLA 0x01 /* Motorola 68K */ +#define PROC_MIPS4000 0x02 /* MIPS RISC 4000 */ +#define PROC_MIPS PROC_MIPS4000 /* MIPS RISC */ +#define PROC_ALPHA 0x03 /* DEC Alpha */ +#define PROC_POWERPC 0x04 /* IBM Power PC */ +#define PROC_i960 0x05 /* Intel i960 */ +#define PROC_ULTRASPARC 0x06 /* SPARC processor */ + +/* Specific Minimim Processor - sigBYTE dsProcessor; FLAG BITS */ +/* ------------------------------------------------------------------ */ +/* Different bit definitions dependent on processor_family */ + +/* PROC_INTEL: */ +#define PROC_8086 0x01 /* Intel 8086 */ +#define PROC_286 0x02 /* Intel 80286 */ +#define PROC_386 0x04 /* Intel 80386 */ +#define PROC_486 0x08 /* Intel 80486 */ +#define PROC_PENTIUM 0x10 /* Intel 586 aka P5 aka Pentium */ +#define PROC_SEXIUM 0x20 /* Intel 686 aka P6 aka Pentium Pro or MMX */ + +/* PROC_i960: */ +#define PROC_960RX 0x01 /* Intel 80960RP/RD */ +#define PROC_960HX 0x02 /* Intel 80960HA/HD/HT */ +#define PROC_960RN 0x03 /* Intel 80960RN/RM */ +#define PROC_960RS 0x04 /* Intel 80960RS */ + +/* PROC_MOTOROLA: */ +#define PROC_68000 0x01 /* Motorola 68000 */ +#define PROC_68010 0x02 /* Motorola 68010 */ +#define PROC_68020 0x04 /* Motorola 68020 */ +#define PROC_68030 0x08 /* Motorola 68030 */ +#define PROC_68040 0x10 /* Motorola 68040 */ + +/* PROC_POWERPC */ +#define PROC_PPC601 0x01 /* PowerPC 601 */ +#define PROC_PPC603 0x02 /* PowerPC 603 */ +#define PROC_PPC604 0x04 /* PowerPC 604 */ + +/* PROC_MIPS */ +#define PROC_R4000 0x01 /* MIPS R4000 */ +#define PROC_RM7000 0x02 /* MIPS RM7000 */ + +/* Filetype - sigBYTE dsFiletype; DISTINCT VALUES */ +/* ------------------------------------------------------------------ */ +#define FT_EXECUTABLE 0 /* Executable Program */ +#define FT_SCRIPT 1 /* Script/Batch File??? */ +#define FT_HBADRVR 2 /* HBA Driver */ +#define FT_OTHERDRVR 3 /* Other Driver */ +#define FT_IFS 4 /* Installable Filesystem Driver */ +#define FT_ENGINE 5 /* DPT Engine */ +#define FT_COMPDRVR 6 /* Compressed Driver Disk */ +#define FT_LANGUAGE 7 /* Foreign Language file */ +#define FT_FIRMWARE 8 /* Downloadable or actual Firmware */ +#define FT_COMMMODL 9 /* Communications Module */ +#define FT_INT13 10 /* INT 13 style HBA Driver */ +#define FT_HELPFILE 11 /* Help file */ +#define FT_LOGGER 12 /* Event Logger */ +#define FT_INSTALL 13 /* An Install Program */ +#define FT_LIBRARY 14 /* Storage Manager Real-Mode Calls */ +#define FT_RESOURCE 15 /* Storage Manager Resource File */ +#define FT_MODEM_DB 16 /* Storage Manager Modem Database */ + +/* Filetype flags - sigBYTE dsFiletypeFlags; FLAG BITS */ +/* ------------------------------------------------------------------ */ +#define FTF_DLL 0x01 /* Dynamic Link Library */ +#define FTF_NLM 0x02 /* Netware Loadable Module */ +#define FTF_OVERLAYS 0x04 /* Uses overlays */ +#define FTF_DEBUG 0x08 /* Debug version */ +#define FTF_TSR 0x10 /* TSR */ +#define FTF_SYS 0x20 /* DOS Loadable driver */ +#define FTF_PROTECTED 0x40 /* Runs in protected mode */ +#define FTF_APP_SPEC 0x80 /* Application Specific */ +#define FTF_ROM (FTF_SYS|FTF_TSR) /* Special Case */ + +/* OEM - sigBYTE dsOEM; DISTINCT VALUES */ +/* ------------------------------------------------------------------ */ +#define OEM_DPT 0 /* DPT */ +#define OEM_ATT 1 /* ATT */ +#define OEM_NEC 2 /* NEC */ +#define OEM_ALPHA 3 /* Alphatronix */ +#define OEM_AST 4 /* AST */ +#define OEM_OLIVETTI 5 /* Olivetti */ +#define OEM_SNI 6 /* Siemens/Nixdorf */ +#define OEM_SUN 7 /* SUN Microsystems */ +#define OEM_ADAPTEC 8 /* Adaptec */ + +/* Operating System - sigLONG dsOS; FLAG BITS */ +/* ------------------------------------------------------------------ */ +#define OS_DOS 0x00000001 /* PC/MS-DOS */ +#define OS_WINDOWS 0x00000002 /* Microsoft Windows 3.x */ +#define OS_WINDOWS_NT 0x00000004 /* Microsoft Windows NT */ +#define OS_OS2M 0x00000008 /* OS/2 1.2.x,MS 1.3.0,IBM 1.3.x - Monolithic */ +#define OS_OS2L 0x00000010 /* Microsoft OS/2 1.301 - LADDR */ +#define OS_OS22x 0x00000020 /* IBM OS/2 2.x */ +#define OS_NW286 0x00000040 /* Novell NetWare 286 */ +#define OS_NW386 0x00000080 /* Novell NetWare 386 */ +#define OS_GEN_UNIX 0x00000100 /* Generic Unix */ +#define OS_SCO_UNIX 0x00000200 /* SCO Unix */ +#define OS_ATT_UNIX 0x00000400 /* ATT Unix */ +#define OS_UNIXWARE 0x00000800 /* USL Unix */ +#define OS_INT_UNIX 0x00001000 /* Interactive Unix */ +#define OS_SOLARIS 0x00002000 /* SunSoft Solaris */ +#define OS_QNX 0x00004000 /* QNX for Tom Moch */ +#define OS_NEXTSTEP 0x00008000 /* NeXTSTEP/OPENSTEP/MACH */ +#define OS_BANYAN 0x00010000 /* Banyan Vines */ +#define OS_OLIVETTI_UNIX 0x00020000/* Olivetti Unix */ +#define OS_MAC_OS 0x00040000 /* Mac OS */ +#define OS_WINDOWS_95 0x00080000 /* Microsoft Windows '95 */ +#define OS_NW4x 0x00100000 /* Novell Netware 4.x */ +#define OS_BSDI_UNIX 0x00200000 /* BSDi Unix BSD/OS 2.0 and up */ +#define OS_AIX_UNIX 0x00400000 /* AIX Unix */ +#define OS_FREE_BSD 0x00800000 /* FreeBSD Unix */ +#define OS_LINUX 0x01000000 /* Linux */ +#define OS_DGUX_UNIX 0x02000000 /* Data General Unix */ +#define OS_SINIX_N 0x04000000 /* SNI SINIX-N */ +#define OS_PLAN9 0x08000000 /* ATT Plan 9 */ +#define OS_TSX 0x10000000 /* SNH TSX-32 */ +#define OS_WINDOWS_98 0x20000000 /* Microsoft Windows '98 */ + +#define OS_OTHER 0x80000000 /* Other */ + +/* Capabilities - sigWORD dsCapabilities; FLAG BITS */ +/* ------------------------------------------------------------------ */ +#define CAP_RAID0 0x0001 /* RAID-0 */ +#define CAP_RAID1 0x0002 /* RAID-1 */ +#define CAP_RAID3 0x0004 /* RAID-3 */ +#define CAP_RAID5 0x0008 /* RAID-5 */ +#define CAP_SPAN 0x0010 /* Spanning */ +#define CAP_PASS 0x0020 /* Provides passthrough */ +#define CAP_OVERLAP 0x0040 /* Passthrough supports overlapped commands */ +#define CAP_ASPI 0x0080 /* Supports ASPI Command Requests */ +#define CAP_ABOVE16MB 0x0100 /* ISA Driver supports greater than 16MB */ +#define CAP_EXTEND 0x8000 /* Extended info appears after description */ +#ifdef SNI_MIPS +#define CAP_CACHEMODE 0x1000 /* dpt_force_cache is set in driver */ +#endif + +/* Devices Supported - sigWORD dsDeviceSupp; FLAG BITS */ +/* ------------------------------------------------------------------ */ +#define DEV_DASD 0x0001 /* DASD (hard drives) */ +#define DEV_TAPE 0x0002 /* Tape drives */ +#define DEV_PRINTER 0x0004 /* Printers */ +#define DEV_PROC 0x0008 /* Processors */ +#define DEV_WORM 0x0010 /* WORM drives */ +#define DEV_CDROM 0x0020 /* CD-ROM drives */ +#define DEV_SCANNER 0x0040 /* Scanners */ +#define DEV_OPTICAL 0x0080 /* Optical Drives */ +#define DEV_JUKEBOX 0x0100 /* Jukebox */ +#define DEV_COMM 0x0200 /* Communications Devices */ +#define DEV_OTHER 0x0400 /* Other Devices */ +#define DEV_ALL 0xFFFF /* All SCSI Devices */ + +/* Adapters Families Supported - sigWORD dsAdapterSupp; FLAG BITS */ +/* ------------------------------------------------------------------ */ +#define ADF_2001 0x0001 /* PM2001 */ +#define ADF_2012A 0x0002 /* PM2012A */ +#define ADF_PLUS_ISA 0x0004 /* PM2011,PM2021 */ +#define ADF_PLUS_EISA 0x0008 /* PM2012B,PM2022 */ +#define ADF_SC3_ISA 0x0010 /* PM2021 */ +#define ADF_SC3_EISA 0x0020 /* PM2022,PM2122, etc */ +#define ADF_SC3_PCI 0x0040 /* SmartCache III PCI */ +#define ADF_SC4_ISA 0x0080 /* SmartCache IV ISA */ +#define ADF_SC4_EISA 0x0100 /* SmartCache IV EISA */ +#define ADF_SC4_PCI 0x0200 /* SmartCache IV PCI */ +#define ADF_SC5_PCI 0x0400 /* Fifth Generation I2O products */ +/* + * Combinations of products + */ +#define ADF_ALL_2000 (ADF_2001|ADF_2012A) +#define ADF_ALL_PLUS (ADF_PLUS_ISA|ADF_PLUS_EISA) +#define ADF_ALL_SC3 (ADF_SC3_ISA|ADF_SC3_EISA|ADF_SC3_PCI) +#define ADF_ALL_SC4 (ADF_SC4_ISA|ADF_SC4_EISA|ADF_SC4_PCI) +#define ADF_ALL_SC5 (ADF_SC5_PCI) +/* All EATA Cacheing Products */ +#define ADF_ALL_CACHE (ADF_ALL_PLUS|ADF_ALL_SC3|ADF_ALL_SC4) +/* All EATA Bus Mastering Products */ +#define ADF_ALL_MASTER (ADF_2012A|ADF_ALL_CACHE) +/* All EATA Adapter Products */ +#define ADF_ALL_EATA (ADF_2001|ADF_ALL_MASTER) +#define ADF_ALL ADF_ALL_EATA + +/* Application - sigWORD dsApplication; FLAG BITS */ +/* ------------------------------------------------------------------ */ +#define APP_DPTMGR 0x0001 /* DPT Storage Manager */ +#define APP_ENGINE 0x0002 /* DPT Engine */ +#define APP_SYTOS 0x0004 /* Sytron Sytos Plus */ +#define APP_CHEYENNE 0x0008 /* Cheyenne ARCServe + ARCSolo */ +#define APP_MSCDEX 0x0010 /* Microsoft CD-ROM extensions */ +#define APP_NOVABACK 0x0020 /* NovaStor Novaback */ +#define APP_AIM 0x0040 /* Archive Information Manager */ + +/* Requirements - sigBYTE dsRequirements; FLAG BITS */ +/* ------------------------------------------------------------------ */ +#define REQ_SMARTROM 0x01 /* Requires SmartROM to be present */ +#define REQ_DPTDDL 0x02 /* Requires DPTDDL.SYS to be loaded */ +#define REQ_HBA_DRIVER 0x04 /* Requires an HBA driver to be loaded */ +#define REQ_ASPI_TRAN 0x08 /* Requires an ASPI Transport Modules */ +#define REQ_ENGINE 0x10 /* Requires a DPT Engine to be loaded */ +#define REQ_COMM_ENG 0x20 /* Requires a DPT Communications Engine */ + +/* ------------------------------------------------------------------ */ +/* Requirements - sigWORD dsFirmware; FLAG BITS */ +/* ------------------------------------------------------------------ */ +#define dsFirmware dsApplication +#define FW_DNLDSIZE0 0x0000 /* 0..2 DownLoader Size - NONE */ +#define FW_DNLDSIZE16 0x0001 /* 0..2 DownLoader Size 16K */ +#define FW_DNLDSIZE32 0x0002 /* 0..2 DownLoader Size 32K */ +#define FW_DNLDSIZE64 0x0004 /* 0..2 DownLoader Size 64K */ + +#define FW_LOAD_BTM 0x2000 /* 13 Load Offset (1=Btm, 0=Top) */ +#define FW_LOAD_TOP 0x0000 /* 13 Load Offset (1=Btm, 0=Top) */ +#define FW_SIG_VERSION1 0x0000 /* 15..14 Version Bits 0=Ver1 */ + +/* + 0..2 Downloader Size (Value * 16K) + 3 + + 4 + 5 + 6 + 7 + + 8 + 9 + 10 + 11 + + 12 + 13 Load Offset (1=BTM 0=TOP) + 14..15 F/W Sig Version (0=Ver1) +*/ + +/* ------------------------------------------------------------------ */ +/* ------------------------------------------------------------------ */ +/* ------------------------------------------------------------------ */ + +/* + * You may adjust dsDescription_size with an override to a value less than + * 50 so that the structure allocates less real space. + */ +#if (!defined(dsDescription_size)) +# define dsDescription_size 50 +#endif + +typedef struct dpt_sig { + char dsSignature[6]; /* ALWAYS "dPtSiG" */ + sigBYTE dsSigVersion; /* signature version (currently 1) */ + sigBYTE dsProcessorFamily; /* what type of processor */ + sigBYTE dsProcessor; /* precise processor */ + sigBYTE dsFiletype; /* type of file */ + sigBYTE dsFiletypeFlags; /* flags to specify load type, etc. */ + sigBYTE dsOEM; /* OEM file was created for */ + sigLONG dsOS; /* which Operating systems */ + sigWORD dsCapabilities; /* RAID levels, etc. */ + sigWORD dsDeviceSupp; /* Types of SCSI devices supported */ + sigWORD dsAdapterSupp; /* DPT adapter families supported */ + sigWORD dsApplication; /* applications file is for */ + sigBYTE dsRequirements; /* Other driver dependencies */ + sigBYTE dsVersion; /* 1 */ + sigBYTE dsRevision; /* 'J' */ + sigBYTE dsSubRevision; /* '9' ' ' if N/A */ + sigBYTE dsMonth; /* creation month */ + sigBYTE dsDay; /* creation day */ + sigBYTE dsYear; /* creation year since 1980 (1993=13) */ + /* description (NULL terminated) */ + char dsDescription[dsDescription_size]; +} dpt_sig_S; +/* 32 bytes minimum - with no description. Put NULL at description[0] */ +/* 81 bytes maximum - with 49 character description plus NULL. */ + +#if defined __bsdi__ +#ifndef PACK +#define PACK __attribute__ ((packed)) +#endif +typedef struct dpt_sig_Packed { + char dsSignature[6] PACK; /* ALWAYS "dPtSiG" */ + sigBYTE dsSigVersion PACK; /* signature version (currently 1) */ + sigBYTE dsProcessorFamily PACK; /* what type of processor */ + sigBYTE dsProcessor PACK; /* precise processor */ + sigBYTE dsFiletype PACK; /* type of file */ + sigBYTE dsFiletypeFlags PACK; /* flags to specify load type, etc. */ + sigBYTE dsOEM PACK; /* OEM file was created for */ + sigLONG dsOS PACK; /* which Operating systems */ + sigWORD dsCapabilities PACK; /* RAID levels, etc. */ + sigWORD dsDeviceSupp PACK; /* Types of SCSI devices supported */ + sigWORD dsAdapterSupp PACK; /* DPT adapter families supported */ + sigWORD dsApplication PACK; /* applications file is for */ + sigBYTE dsRequirements PACK; /* Other driver dependencies */ + sigBYTE dsVersion PACK; /* 1 */ + sigBYTE dsRevision PACK; /* 'J' */ + sigBYTE dsSubRevision PACK; /* '9' ' ' if N/A */ + sigBYTE dsMonth PACK; /* creation month */ + sigBYTE dsDay PACK; /* creation day */ + sigBYTE dsYear PACK; /* creation year since 1980 (1993=13) */ + /* description (NULL terminated) */ + char dsDescription[dsDescription_size] PACK; +} dpt_sig_S_Packed; +#define PACKED_SIG_SIZE sizeof(dpt_sig_S_Packed) +#endif +/* This line added at Roycroft's request */ +/* Microsoft's NT compiler gets confused if you do a pack and don't */ +/* restore it. */ + +#ifndef NO_UNPACK +#if defined (_DPT_AIX) +#pragma options align=reset +#elif defined (UNPACK_FOUR) +#pragma pack(4) +#else +#pragma pack() +#endif /* aix */ +#endif +/* For the Macintosh */ +#if STRUCTALIGNMENTSUPPORTED +#pragma options align=reset +#endif + +#endif diff --git a/sys/dev/asr/i2oadptr.h b/sys/dev/asr/i2oadptr.h new file mode 100644 index 000000000000..d2ec6a975674 --- /dev/null +++ b/sys/dev/asr/i2oadptr.h @@ -0,0 +1,402 @@ +/* $FreeBSD$ */ +/**************************************************************** + * Copyright (c) 1996-2000 Distributed Processing Technology Corporation + * Copyright (c) 2000 Adaptec Corproation. + * All rights reserved. + * + * Copyright 1999 I2O Special Interest Group (I2O SIG). All rights reserved. + * All rights reserved + * + * TERMS AND CONDITIONS OF USE + * + * Redistribution and use in source form, with or without modification, are + * permitted provided that redistributions of source code must retain the + * above copyright notice, this list of conditions and the following disclaimer. + * + * This software is provided `as is' by Distributed Processing Technology 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 Distributed Processing Technology 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 + * interruptions) 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 driver software, even if advised + * of the possibility of such damage. + * + * This header file, and any modifications of this header file, are provided + * contingent upon your agreement and adherence to the here-listed terms and + * conditions. By accepting and/or using this header file, you agree to abide + * by these terms and conditions and that these terms and conditions will be + * construed and governed in accordance with the laws of the State of California, + * without reference to conflict-of-law provisions. If you do not agree + * to these terms and conditions, please delete this file, and any copies, + * permanently, without making any use thereof. + * + * THIS HEADER FILE IS PROVIDED FREE OF CHARGE ON AN AS-IS BASIS WITHOUT + * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. I2O SIG DOES NOT WARRANT THAT THIS HEADER FILE WILL MEET THE + * USER'S REQUIREMENTS OR THAT ITS OPERATION WILL BE UNINTERRUPTED OR + * ERROR-FREE. + * + * I2O SIG DISCLAIMS ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF + * ANY PROPRIETARY RIGHTS, RELATING TO THE IMPLEMENTATION OF THE I2O + * SPECIFICATIONS. I2O SIG DOES NOT WARRANT OR REPRESENT THAT SUCH + * IMPLEMENTATIONS WILL NOT INFRINGE SUCH RIGHTS. + * + * THE USER OF THIS HEADER FILE SHALL HAVE NO RECOURSE TO I2O SIG FOR ANY + * ACTUAL OR CONSEQUENTIAL DAMAGES INCLUDING, BUT NOT LIMITED TO, LOST DATA + * OR LOST PROFITS ARISING OUT OF THE USE OR INABILITY TO USE THIS PROGRAM. + * + * I2O SIG grants the user of this header file a license to copy, distribute, + * and modify it, for any purpose, under the following terms. Any copying, + * distribution, or modification of this header file must not delete or alter + * the copyright notice of I2O SIG or any of these Terms and Conditions. + * + * Any distribution of this header file must not include a charge for the + * header file (unless such charges are strictly for the physical acts of + * copying or transferring copies). However, distribution of a product in + * which this header file is embedded may include a charge so long as any + * such charge does not include any charge for the header file itself. + * + * Any modification of this header file constitutes a derivative work based + * on this header file. Any distribution of such derivative work: (1) must + * include prominent notices that the header file has been changed from the + * original, together with the dates of any changes; (2) automatically includes + * this same license to the original header file from I2O SIG, without any + * restriction thereon from the distributing user; and (3) must include a + * grant of license of the modified file under the same terms and conditions + * as these Terms and Conditions. + * + * The I2O SIG Web site can be found at: http://www.i2osig.org + * + * The I2O SIG encourages you to deposit derivative works based on this + * header file at the I2O SIG Web site. Furthermore, to become a Registered + * Developer of the I2O SIG, sign up at the Web site or call 415.750.8352 + * (United States). + ****************************************************************/ + +#if !defined(I2O_ADPTR_HDR) +#define I2O_ADPTR_HDR + +#if ((defined(KERNEL) || defined(_KERNEL)) && defined(__FreeBSD__)) +# if (KERN_VERSION < 3) +# include "i386/pci/i2omsg.h" +# else +# include "dev/asr/i2omsg.h" +# endif +#else +# include "i2omsg.h" /* Include the Base Message file */ +#endif + + +#define I2OADPTR_REV 1_5_1 /* Header file revision string */ + + +/***************************************************************************** + * + * i2oadptr.h -- I2O Adapter Class Message defintion file + * + * + * Revision History: + * + * 1.5.d 03/06/97 - First definition for spec. draft version 1.5d. + * 1.5.1 05/02/97 - Corrections from review cycle: + * 1) Remove "SCSI" from function definition comment. + * 2) Add revision string. + * 3) Convert tabs to spaces. + * 4) New disclaimer. + * + * + * + *****************************************************************************/ + +/* + NOTES: + + Gets, reads, receives, etc. are all even numbered functions. + Sets, writes, sends, etc. are all odd numbered functions. + Functions that both send and receive data can be either but an attempt is made + to use the function number that indicates the greater transfer amount. + Functions that do not send or receive data use odd function numbers. + + Some functions are synonyms like read, receive and send, write. + + All common functions will have a code of less than 0x80. + Unique functions to a class will start at 0x80. + Executive Functions start at 0xA0. + + Utility Message function codes range from 0 - 0x1f + Base Message function codes range from 0x20 - 0xfe + Private Message function code is 0xff. +*/ + + +PRAGMA_ALIGN_PUSH + +PRAGMA_PACK_PUSH + +/* + Bus Adapter Class specific functions +*/ + +#define I2O_HBA_ADAPTER_RESET 0x85 +#define I2O_HBA_BUS_QUIESCE 0x8b +#define I2O_HBA_BUS_RESET 0x87 +#define I2O_HBA_BUS_SCAN 0x89 + + +/* + Detailed Status Codes for HBA operations + + Note: + The 16-bit Detailed Status Code field for HBA operations is divided + into two separate 8-bit fields. The lower 8 bits are reserved. The + upper 8 bits are used to report Adapter Status information. The + definitions for these two fields, however, will be consistent with + the standard reply message frame structure declaration, which treats + this as a single 16-bit field. In addition, the values used will be + consistent with the Adapter Status codes defined for the SCSI + Peripheral class. Theses codes are based on CAM-1. In other words, + these definitions are a subset of the SCSI peripheral class codes. + Where applicable, "SCSI" has been removed from the definition. +*/ + + +#define I2O_HBA_DSC_MASK 0xFF00 + +#define I2O_HBA_DSC_SUCCESS 0x0000 +#define I2O_HBA_DSC_ADAPTER_BUSY 0x0500 +#define I2O_HBA_DSC_COMMAND_TIMEOUT 0x0B00 +#define I2O_HBA_DSC_COMPLETE_WITH_ERROR 0x0400 +#define I2O_HBA_DSC_FUNCTION_UNAVAILABLE 0x3A00 +#define I2O_HBA_DSC_NO_ADAPTER 0x1100 +#define I2O_HBA_DSC_PARITY_ERROR_FAILURE 0x0F00 +#define I2O_HBA_DSC_PATH_INVALID 0x0700 +#define I2O_HBA_DSC_PROVIDE_FAILURE 0x1600 +#define I2O_HBA_DSC_QUEUE_FROZEN 0x4000 +#define I2O_HBA_DSC_REQUEST_ABORTED 0x0200 +#define I2O_HBA_DSC_REQUEST_INVALID 0x0600 +#define I2O_HBA_DSC_REQUEST_LENGTH_ERROR 0x1500 +#define I2O_HBA_DSC_REQUEST_TERMINATED 0x1800 +#define I2O_HBA_DSC_RESOURCE_UNAVAILABLE 0x3400 +#define I2O_HBA_DSC_BUS_BUSY 0x3F00 +#define I2O_HBA_DSC_BUS_RESET 0x0E00 +#define I2O_HBA_DSC_ID_INVALID 0x3900 +#define I2O_HBA_DSC_SEQUENCE_FAILURE 0x1400 +#define I2O_HBA_DSC_UNABLE_TO_ABORT 0x0300 +#define I2O_HBA_DSC_UNABLE_TO_TERMINATE 0x0900 +#define I2O_HBA_DSC_UNACKNOWLEDGED_EVENT 0x3500 +#define I2O_HBA_DSC_UNEXPECTED_BUS_FREE 0x1300 + + + +/****************************************************************************/ + +/* Bus Adapter Parameter Groups */ + +/****************************************************************************/ + + +#define I2O_HBA_CONTROLLER_INFO_GROUP_NO 0x0000 +#define I2O_HBA_HISTORICAL_STATS_GROUP_NO 0x0100 +#define I2O_HBA_SCSI_CONTROLLER_INFO_GROUP_NO 0x0200 +#define I2O_HBA_SCSI_BUS_PORT_INFO_GROUP_NO 0x0201 +#define I2O_HBA_FCA_CONTROLLER_INFO_GROUP_NO 0x0300 +#define I2O_HBA_FCA_PORT_INFO_GROUP_NO 0x0301 + + +/* - 0000h - HBA Controller Information Parameter Group */ + +/* Bus Type */ + +#define I2O_HBA_BUS_TYPE_GENERIC 0x00 +#define I2O_HBA_BUS_TYPE_SCSI 0x01 +#define I2O_HBA_BUS_TYPE_FCA 0x10 + + +typedef struct _I2O_HBA_CONTROLLER_INFO_SCALAR { + U8 BusType; + U8 BusState; + U16 Reserved2; + U8 BusName[12]; +} I2O_HBA_CONTROLLER_INFO_SCALAR, *PI2O_HBA_CONTROLLER_INFO_SCALAR; + + +/* - 0100h - HBA Historical Stats Parameter Group */ + +typedef struct _I2O_HBA_HIST_STATS_SCALAR { + U32 TimeLastPoweredUp; + U32 TimeLastReset; +} I2O_HBA_HIST_STATS_SCALAR, *PI2O_HBA_HIST_STATS_SCALAR; + + +/* - 0200h - HBA SCSI Controller Information Parameter Group */ + +/* SCSI Type */ + +#define I2O_SCSI_TYPE_UNKNOWN 0x00 +#define I2O_SCSI_TYPE_SCSI_1 0x01 +#define I2O_SCSI_TYPE_SCSI_2 0x02 +#define I2O_SCSI_TYPE_SCSI_3 0x03 + +/* Protection Management */ + +#define I2O_SCSI_PORT_PROT_OTHER 0x00 +#define I2O_SCSI_PORT_PROT_UNKNOWN 0x01 +#define I2O_SCSI_PORT_PROT_UNPROTECTED 0x02 +#define I2O_SCSI_PORT_PROT_PROTECTED 0x03 +#define I2O_SCSI_PORT_PROT_SCC 0x04 + +/* Settings */ + +#define I2O_SCSI_PORT_PARITY_FLAG 0x01 +#define I2O_SCSI_PORT_PARITY_DISABLED 0x00 +#define I2O_SCSI_PORT_PARITY_ENABLED 0x01 + +#define I2O_SCSI_PORT_SCAN_ORDER_FLAG 0x02 +#define I2O_SCSI_PORT_SCAN_LOW_TO_HIGH 0x00 +#define I2O_SCSI_PORT_SCAN_HIGH_TO_LOW 0x02 + +#define I2O_SCSI_PORT_IID_FLAG 0x04 +#define I2O_SCSI_PORT_IID_DEFAULT 0x00 +#define I2O_SCSI_PORT_IID_SPECIFIED 0x04 + +#define I2O_SCSI_PORT_SCAM_FLAG 0x08 +#define I2O_SCSI_PORT_SCAM_DISABLED 0x00 +#define I2O_SCSI_PORT_SCAM_ENABLED 0x08 + +#define I2O_SCSI_PORT_TYPE_FLAG 0x80 +#define I2O_SCSI_PORT_TYPE_PARALLEL 0x00 +#define I2O_SCSI_PORT_TYPE_SERIAL 0x80 + +typedef struct _I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR { + U8 SCSIType; + U8 ProtectionManagement; + U8 Settings; + U8 Reserved1; + U32 InitiatorID; + U64 ScanLun0Only; + U16 DisableDevice; + U8 MaxOffset; + U8 MaxDataWidth; + U64 MaxSyncRate; +} I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR, *PI2O_HBA_SCSI_CONTROLLER_INFO_SCALAR; + + +/* - 0201h - HBA SCSI Bus Port Information Parameter Group */ + +/* NOTE: Refer to the SCSI Peripheral Class Bus Port Information Parameter + Group field definitions for HBA SCSI Bus Port field definitions. + */ + +typedef struct _I2O_HBA_SCSI_BUS_PORT_INFO_SCALAR { + U8 PhysicalInterface; + U8 ElectricalInterface; + U8 Isochronous; + U8 ConnectorType; + U8 ConnectorGender; + U8 Reserved1; + U16 Reserved2; + U32 MaxNumberDevices; + U32 DeviceIdBegin; + U32 DeviceIdEnd; + U8 LunBegin[8]; + U8 LunEnd[8]; +} I2O_HBA_SCSI_BUS_PORT_INFO_SCALAR, *PI2O_HBA_SCSI_BUS_PORT_INFO_SCALAR; + + +/* - 0300h - HBA FCA Controller Information Parameters Group defines */ + +/* SCSI Type */ + +#define I2O_FCA_TYPE_UNKNOWN 0x00 +#define I2O_FCA_TYPE_FCAL 0x01 + +typedef struct _I2O_HBA_FCA_CONTROLLER_INFO_SCALAR { + U8 FcaType; + U8 Reserved1; + U16 Reserved2; +} I2O_HBA_FCA_CONTROLLER_INFO_SCALAR, *PI2O_HBA_FCA_CONTROLLER_INFO_SCALAR; + + +/* - 0301h - HBA FCA Port Information Parameters Group defines */ + +typedef struct _I2O_HBA_FCA_PORT_INFO_SCALAR { + U32 Reserved4; +} I2O_HBA_FCA_PORT_INFO_SCALAR, *PI2O_HBA_FCA_PORT_INFO_SCALAR; + + +/****************************************************************************/ + +/* I2O Bus Adapter Class Specific Message Definitions */ + +/****************************************************************************/ + + +/****************************************************************************/ + +/* I2O Bus Adapter Class Reply Message Frame */ + +typedef struct _I2O_HBA_REPLY_MESSAGE_FRAME { + I2O_SINGLE_REPLY_MESSAGE_FRAME StdReplyFrame; +} I2O_HBA_REPLY_MESSAGE_FRAME, *PI2O_HBA_REPLY_MESSAGE_FRAME; + + +/****************************************************************************/ + +/* I2O HBA Adapter Reset Message Frame */ + +typedef struct _I2O_HBA_ADAPTER_RESET_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +} I2O_HBA_ADAPTER_RESET_MESSAGE, *PI2O_HBA_ADAPTER_RESET_MESSAGE; + + +/****************************************************************************/ + +/* I2O HBA Bus Quiesce Message Frame */ + +typedef U32 I2O_HBQ_FLAGS; + +#define I2O_HBQ_FLAG_NORMAL 0x0000 +#define I2O_HBQ_FLAG_QUIESCE 0x0001 + +typedef struct _I2O_HBA_BUS_QUIESCE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + I2O_HBQ_FLAGS Flags; +} I2O_HBA_BUS_QUIESCE_MESSAGE, *PI2O_HBA_BUS_QUIESCE_MESSAGE; + + +/****************************************************************************/ + +/* I2O HBA Bus Reset Message Frame */ + +typedef struct _I2O_HBA_BUS_RESET_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +} I2O_HBA_BUS_RESET_MESSAGE, *PI2O_HBA_BUS_RESET_MESSAGE; + + +/****************************************************************************/ + +/* I2O HBA Bus Scan Message Frame */ + +/* NOTE: SCSI-2 8-bit scalar LUN goes into offset 1 of Lun arrays */ + +typedef struct _I2O_HBA_BUS_SCAN_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +} I2O_HBA_BUS_SCAN_MESSAGE, *PI2O_HBA_BUS_SCAN_MESSAGE; + + +PRAGMA_PACK_POP + +PRAGMA_ALIGN_POP + +#endif /* I2O_ADPTR_HDR */ + + diff --git a/sys/dev/asr/i2obscsi.h b/sys/dev/asr/i2obscsi.h new file mode 100644 index 000000000000..72957724b274 --- /dev/null +++ b/sys/dev/asr/i2obscsi.h @@ -0,0 +1,495 @@ +/* $FreeBSD$ */ +/**************************************************************** + * Copyright (c) 1996-2000 Distributed Processing Technology Corporation + * Copyright (c) 2000 Adaptec Corporation. + * All rights reserved. + * + * Copyright 1999 I2O Special Interest Group (I2O SIG). All rights reserved. + * All rights reserved + * + * TERMS AND CONDITIONS OF USE + * + * Redistribution and use in source form, with or without modification, are + * permitted provided that redistributions of source code must retain the + * above copyright notice, this list of conditions and the following disclaimer. + * + * This software is provided `as is' by Distributed Processing Technology 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 Distributed Processing Technology 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 + * interruptions) 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 driver software, even if advised + * of the possibility of such damage. + * + * This header file, and any modifications of this header file, are provided + * contingent upon your agreement and adherence to the here-listed terms and + * conditions. By accepting and/or using this header file, you agree to abide + * by these terms and conditions and that these terms and conditions will be + * construed and governed in accordance with the laws of the State of California, + * without reference to conflict-of-law provisions. If you do not agree + * to these terms and conditions, please delete this file, and any copies, + * permanently, without making any use thereof. + * + * THIS HEADER FILE IS PROVIDED FREE OF CHARGE ON AN AS-IS BASIS WITHOUT + * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. I2O SIG DOES NOT WARRANT THAT THIS HEADER FILE WILL MEET THE + * USER'S REQUIREMENTS OR THAT ITS OPERATION WILL BE UNINTERRUPTED OR + * ERROR-FREE. + * + * I2O SIG DISCLAIMS ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF + * ANY PROPRIETARY RIGHTS, RELATING TO THE IMPLEMENTATION OF THE I2O + * SPECIFICATIONS. I2O SIG DOES NOT WARRANT OR REPRESENT THAT SUCH + * IMPLEMENTATIONS WILL NOT INFRINGE SUCH RIGHTS. + * + * THE USER OF THIS HEADER FILE SHALL HAVE NO RECOURSE TO I2O SIG FOR ANY + * ACTUAL OR CONSEQUENTIAL DAMAGES INCLUDING, BUT NOT LIMITED TO, LOST DATA + * OR LOST PROFITS ARISING OUT OF THE USE OR INABILITY TO USE THIS PROGRAM. + * + * I2O SIG grants the user of this header file a license to copy, distribute, + * and modify it, for any purpose, under the following terms. Any copying, + * distribution, or modification of this header file must not delete or alter + * the copyright notice of I2O SIG or any of these Terms and Conditions. + * + * Any distribution of this header file must not include a charge for the + * header file (unless such charges are strictly for the physical acts of + * copying or transferring copies). However, distribution of a product in + * which this header file is embedded may include a charge so long as any + * such charge does not include any charge for the header file itself. + * + * Any modification of this header file constitutes a derivative work based + * on this header file. Any distribution of such derivative work: (1) must + * include prominent notices that the header file has been changed from the + * original, together with the dates of any changes; (2) automatically includes + * this same license to the original header file from I2O SIG, without any + * restriction thereon from the distributing user; and (3) must include a + * grant of license of the modified file under the same terms and conditions + * as these Terms and Conditions. + * + * The I2O SIG Web site can be found at: http://www.i2osig.org + * + * The I2O SIG encourages you to deposit derivative works based on this + * header file at the I2O SIG Web site. Furthermore, to become a Registered + * Developer of the I2O SIG, sign up at the Web site or call 415.750.8352 + * (United States). + ****************************************************************/ + +#if !defined(I2O_BASE_SCSI_HDR) +#define I2O_BASE_SCSI_HDR + +#if ((defined(KERNEL) || defined(_KERNEL)) && defined(__FreeBSD__)) +# if (KERN_VERSION < 3) +# include "i386/pci/i2omsg.h" /* Include the Base Message file */ +# else +# include "dev/asr/i2omsg.h" +# endif +#else +# include "i2omsg.h" /* Include the Base Message file */ +#endif + + +#define I2OBSCSI_REV 1_5_1 /* Header file revision string */ + + + +/***************************************************************************** + * + * I2OBSCSI.h -- I2O Base SCSI Device Class Message defintion file + * + * This file contains information presented in Chapter 6, Section 6 & 7 of + * the I2O Specification. + * + * Revision History: (Revision History tracks the revision number of the I2O + * specification) + * + * .92 - First marked revsion used for Proof of Concept. + * .93 - Change to match the rev .93 of the spec. + * .95 - Updated to Rev .95 of 2/5/96. + * 1.00 - Checked and Updated against spec version 1.00 4/9/96. + * 1.xx - Updated to the 1.x version of the I2O Specification on 11/11/96. + * 1.xx - 11/14/96 + * 1) Removed duplicate device type definitions. + * 2) Added "DSC" to Detailed Status Code definitions. + * 3) Changed SCSI-3 LUN fields from U64 to U8 array. + * 1.xx 11/15/96 - Added #pragma statments for i960. + * 1.xx 11/20/96 - Changed duplicate Bus Scan structure to Bus Reset. + * 1.xx 12/05/96 - Added Auto Request Sense flag definition. + * 1.5d 03/06/97 - Update for spec. draft version 1.5d. + * 1) Converted SCSI bus adapter class to generic in i2oadptr.h. + * 2) Fixed DSC reference: changed from _BUS_SCAN to _BUS_RESET. + * 1.5d 03/031/97 - Made AutoSense flag definition consistent with spec. + * 1.5d 04/11/97 - Corrections from review cycle: + * 1) Corrected typo in I2O_SCSI_PERIPHERAL_TYPE_PARALLEL. + * 2) Corrected typo in I2O_SCSI_PORT_CONN_UNSHIELDED_P_HD. + * 1.5.1 05/02/97 - Corrections from review cycle: + * 1) Remove #include for i2omstor.h. + * 2) Add revision string. + * 3) Convert tabs to spaces. + * 4) New disclaimer. + * + *****************************************************************************/ + +/* + NOTES: + + Gets, reads, receives, etc. are all even numbered functions. + Sets, writes, sends, etc. are all odd numbered functions. + Functions that both send and receive data can be either but an attempt is made + to use the function number that indicates the greater transfer amount. + Functions that do not send or receive data use odd function numbers. + + Some functions are synonyms like read, receive and send, write. + + All common functions will have a code of less than 0x80. + Unique functions to a class will start at 0x80. + Executive Functions start at 0xA0. + + Utility Message function codes range from 0 - 0x1f + Base Message function codes range from 0x20 - 0xfe + Private Message function code is 0xff. +*/ + +PRAGMA_ALIGN_PUSH + +PRAGMA_PACK_PUSH + +/* + SCSI Peripheral Class specific functions + + Although the names are SCSI Peripheral class specific, the values + assigned are common with other classes when applicable. +*/ + +#define I2O_SCSI_DEVICE_RESET 0x27 +#define I2O_SCSI_SCB_ABORT 0x83 +#define I2O_SCSI_SCB_EXEC 0x81 + +/* + Detailed Status Codes for SCSI operations + + The 16-bit Detailed Status Code field for SCSI operations is divided + into two separate 8-bit fields. The lower 8 bits are used to report + Device Status information. The upper 8 bits are used to report + Adapter Status information. The definitions for these two fields, + however, will be consistent with the standard reply message frame + structure declaration, which treats this as a single 16-bit field. +*/ + + +/* SCSI Device Completion Status Codes (defined by SCSI-2/3)*/ + +#define I2O_SCSI_DEVICE_DSC_MASK 0x00FF + +#define I2O_SCSI_DSC_SUCCESS 0x0000 +#define I2O_SCSI_DSC_CHECK_CONDITION 0x0002 +#define I2O_SCSI_DSC_BUSY 0x0008 +#define I2O_SCSI_DSC_RESERVATION_CONFLICT 0x0018 +#define I2O_SCSI_DSC_COMMAND_TERMINATED 0x0022 +#define I2O_SCSI_DSC_TASK_SET_FULL 0x0028 +#define I2O_SCSI_DSC_ACA_ACTIVE 0x0030 + +/* SCSI Adapter Status Codes (based on CAM-1) */ + +#define I2O_SCSI_HBA_DSC_MASK 0xFF00 + +#define I2O_SCSI_HBA_DSC_SUCCESS 0x0000 + +#define I2O_SCSI_HBA_DSC_REQUEST_ABORTED 0x0200 +#define I2O_SCSI_HBA_DSC_UNABLE_TO_ABORT 0x0300 +#define I2O_SCSI_HBA_DSC_COMPLETE_WITH_ERROR 0x0400 +#define I2O_SCSI_HBA_DSC_ADAPTER_BUSY 0x0500 +#define I2O_SCSI_HBA_DSC_REQUEST_INVALID 0x0600 +#define I2O_SCSI_HBA_DSC_PATH_INVALID 0x0700 +#define I2O_SCSI_HBA_DSC_DEVICE_NOT_PRESENT 0x0800 +#define I2O_SCSI_HBA_DSC_UNABLE_TO_TERMINATE 0x0900 +#define I2O_SCSI_HBA_DSC_SELECTION_TIMEOUT 0x0A00 +#define I2O_SCSI_HBA_DSC_COMMAND_TIMEOUT 0x0B00 + +#define I2O_SCSI_HBA_DSC_MR_MESSAGE_RECEIVED 0x0D00 +#define I2O_SCSI_HBA_DSC_SCSI_BUS_RESET 0x0E00 +#define I2O_SCSI_HBA_DSC_PARITY_ERROR_FAILURE 0x0F00 +#define I2O_SCSI_HBA_DSC_AUTOSENSE_FAILED 0x1000 +#define I2O_SCSI_HBA_DSC_NO_ADAPTER 0x1100 +#define I2O_SCSI_HBA_DSC_DATA_OVERRUN 0x1200 +#define I2O_SCSI_HBA_DSC_UNEXPECTED_BUS_FREE 0x1300 +#define I2O_SCSI_HBA_DSC_SEQUENCE_FAILURE 0x1400 +#define I2O_SCSI_HBA_DSC_REQUEST_LENGTH_ERROR 0x1500 +#define I2O_SCSI_HBA_DSC_PROVIDE_FAILURE 0x1600 +#define I2O_SCSI_HBA_DSC_BDR_MESSAGE_SENT 0x1700 +#define I2O_SCSI_HBA_DSC_REQUEST_TERMINATED 0x1800 + +#define I2O_SCSI_HBA_DSC_IDE_MESSAGE_SENT 0x3300 +#define I2O_SCSI_HBA_DSC_RESOURCE_UNAVAILABLE 0x3400 +#define I2O_SCSI_HBA_DSC_UNACKNOWLEDGED_EVENT 0x3500 +#define I2O_SCSI_HBA_DSC_MESSAGE_RECEIVED 0x3600 +#define I2O_SCSI_HBA_DSC_INVALID_CDB 0x3700 +#define I2O_SCSI_HBA_DSC_LUN_INVALID 0x3800 +#define I2O_SCSI_HBA_DSC_SCSI_TID_INVALID 0x3900 +#define I2O_SCSI_HBA_DSC_FUNCTION_UNAVAILABLE 0x3A00 +#define I2O_SCSI_HBA_DSC_NO_NEXUS 0x3B00 +#define I2O_SCSI_HBA_DSC_SCSI_IID_INVALID 0x3C00 +#define I2O_SCSI_HBA_DSC_CDB_RECEIVED 0x3D00 +#define I2O_SCSI_HBA_DSC_LUN_ALREADY_ENABLED 0x3E00 +#define I2O_SCSI_HBA_DSC_BUS_BUSY 0x3F00 + +#define I2O_SCSI_HBA_DSC_QUEUE_FROZEN 0x4000 + + +/****************************************************************************/ + +/* SCSI Peripheral Device Parameter Groups */ + +/****************************************************************************/ + + +/* SCSI Configuration and Operating Structures and Defines */ + + +#define I2O_SCSI_DEVICE_INFO_GROUP_NO 0x0000 +#define I2O_SCSI_DEVICE_BUS_PORT_INFO_GROUP_NO 0x0001 + + +/* - 0000h - SCSI Device Information Parameters Group defines */ + +/* Device Type */ + +#define I2O_SCSI_DEVICE_TYPE_DIRECT 0x00 +#define I2O_SCSI_DEVICE_TYPE_SEQUENTIAL 0x01 +#define I2O_SCSI_DEVICE_TYPE_PRINTER 0x02 +#define I2O_SCSI_DEVICE_TYPE_PROCESSOR 0x03 +#define I2O_SCSI_DEVICE_TYPE_WORM 0x04 +#define I2O_SCSI_DEVICE_TYPE_CDROM 0x05 +#define I2O_SCSI_DEVICE_TYPE_SCANNER 0x06 +#define I2O_SCSI_DEVICE_TYPE_OPTICAL 0x07 +#define I2O_SCSI_DEVICE_TYPE_MEDIA_CHANGER 0x08 +#define I2O_SCSI_DEVICE_TYPE_COMM 0x09 +#define I2O_SCSI_DEVICE_GRAPHICS_1 0x0A +#define I2O_SCSI_DEVICE_GRAPHICS_2 0x0B +#define I2O_SCSI_DEVICE_TYPE_ARRAY_CONT 0x0C +#define I2O_SCSI_DEVICE_TYPE_SES 0x0D +#define I2O_SCSI_DEVICE_TYPE_UNKNOWN 0x1F + +/* Flags */ + +#define I2O_SCSI_PERIPHERAL_TYPE_FLAG 0x01 +#define I2O_SCSI_PERIPHERAL_TYPE_PARALLEL 0x00 +#define I2O_SCSI_PERIPHERAL_TYPE_SERIAL 0x01 + +#define I2O_SCSI_RESERVED_FLAG 0x02 + +#define I2O_SCSI_DISCONNECT_FLAG 0x04 +#define I2O_SCSI_DISABLE_DISCONNECT 0x00 +#define I2O_SCSI_ENABLE_DISCONNECT 0x04 + +#define I2O_SCSI_MODE_MASK 0x18 +#define I2O_SCSI_MODE_SET_DATA 0x00 +#define I2O_SCSI_MODE_SET_DEFAULT 0x08 +#define I2O_SCSI_MODE_SET_SAFEST 0x10 + +#define I2O_SCSI_DATA_WIDTH_MASK 0x60 +#define I2O_SCSI_DATA_WIDTH_8 0x00 +#define I2O_SCSI_DATA_WIDTH_16 0x20 +#define I2O_SCSI_DATA_WIDTH_32 0x40 + +#define I2O_SCSI_SYNC_NEGOTIATION_FLAG 0x80 +#define I2O_SCSI_DISABLE_SYNC_NEGOTIATION 0x00 +#define I2O_SCSI_ENABLE_SYNC_NEGOTIATION 0x80 + + +/* - 0001h - SCSI Device Bus Port Info Parameters Group defines */ + +/* Physical */ + +#define I2O_SCSI_PORT_PHYS_OTHER 0x01 +#define I2O_SCSI_PORT_PHYS_UNKNOWN 0x02 +#define I2O_SCSI_PORT_PHYS_PARALLEL 0x03 +#define I2O_SCSI_PORT_PHYS_FIBRE_CHANNEL 0x04 +#define I2O_SCSI_PORT_PHYS_SERIAL_P1394 0x05 +#define I2O_SCSI_PORT_PHYS_SERIAL_SSA 0x06 + +/* Electrical */ + +#define I2O_SCSI_PORT_ELEC_OTHER 0x01 +#define I2O_SCSI_PORT_ELEC_UNKNOWN 0x02 +#define I2O_SCSI_PORT_ELEC_SINGLE_ENDED 0x03 +#define I2O_SCSI_PORT_ELEC_DIFFERENTIAL 0x04 +#define I2O_SCSI_PORT_ELEC_LOW_VOLT_DIFF 0x05 +#define I2O_SCSI_PORT_ELEC_OPTICAL 0x06 + +/* Isochronous */ + +#define I2O_SCSI_PORT_ISOC_NO 0x00 +#define I2O_SCSI_PORT_ISOC_YES 0x01 +#define I2O_SCSI_PORT_ISOC_UNKNOWN 0x02 + +/* Connector Type */ + +#define I2O_SCSI_PORT_CONN_OTHER 0x01 +#define I2O_SCSI_PORT_CONN_UNKNOWN 0x02 +#define I2O_SCSI_PORT_CONN_NONE 0x03 +#define I2O_SCSI_PORT_CONN_SHIELDED_A_HD 0x04 +#define I2O_SCSI_PORT_CONN_UNSHIELDED_A_HD 0x05 +#define I2O_SCSI_PORT_CONN_SHIELDED_A_LD 0x06 +#define I2O_SCSI_PORT_CONN_UNSHIELDED_A_LD 0x07 +#define I2O_SCSI_PORT_CONN_SHIELDED_P_HD 0x08 +#define I2O_SCSI_PORT_CONN_UNSHIELDED_P_HD 0x09 +#define I2O_SCSI_PORT_CONN_SCA_I 0x0A +#define I2O_SCSI_PORT_CONN_SCA_II 0x0B +#define I2O_SCSI_PORT_CONN_FC_DB9 0x0C +#define I2O_SCSI_PORT_CONN_FC_FIBRE 0x0D +#define I2O_SCSI_PORT_CONN_FC_SCA_II_40 0x0E +#define I2O_SCSI_PORT_CONN_FC_SCA_II_20 0x0F +#define I2O_SCSI_PORT_CONN_FC_BNC 0x10 + +/* Connector Gender */ + +#define I2O_SCSI_PORT_CONN_GENDER_OTHER 0x01 +#define I2O_SCSI_PORT_CONN_GENDER_UNKOWN 0x02 +#define I2O_SCSI_PORT_CONN_GENDER_FEMALE 0x03 +#define I2O_SCSI_PORT_CONN_GENDER_MALE 0x04 + + +/* SCSI Device Group 0000h - Device Information Parameter Group */ + +typedef struct _I2O_SCSI_DEVICE_INFO_SCALAR { + U8 DeviceType; + U8 Flags; + U16 Reserved2; + U32 Identifier; + U8 LunInfo[8]; /* SCSI-2 8-bit scalar LUN goes into offset 1 */ + U32 QueueDepth; + U8 Reserved1a; + U8 NegOffset; + U8 NegDataWidth; + U8 Reserved1b; + U64 NegSyncRate; + +} I2O_SCSI_DEVICE_INFO_SCALAR, *PI2O_SCSI_DEVICE_INFO_SCALAR; + + +/* SCSI Device Group 0001h - Bus Port Information Parameter Group */ + +typedef struct _I2O_SCSI_BUS_PORT_INFO_SCALAR { + U8 PhysicalInterface; + U8 ElectricalInterface; + U8 Isochronous; + U8 ConnectorType; + U8 ConnectorGender; + U8 Reserved1; + U16 Reserved2; + U32 MaxNumberDevices; +} I2O_SCSI_BUS_PORT_INFO_SCALAR, *PI2O_SCSI_BUS_PORT_INFO_SCALAR; + + + +/****************************************************************************/ + +/* I2O SCSI Peripheral Event Indicator Assignment */ + +#define I2O_SCSI_EVENT_SCSI_SMART 0x00000010 + + +/****************************************************************************/ + +/* SCSI Peripheral Class Specific Message Definitions */ + +/****************************************************************************/ + + +/****************************************************************************/ + +/* I2O SCSI Peripheral Successful Completion Reply Message Frame */ + +typedef struct _I2O_SCSI_SUCCESS_REPLY_MESSAGE_FRAME { + I2O_SINGLE_REPLY_MESSAGE_FRAME StdReplyFrame; + U32 TransferCount; +} I2O_SCSI_SUCCESS_REPLY_MESSAGE_FRAME, *PI2O_SCSI_SUCCESS_REPLY_MESSAGE_FRAME; + + +/****************************************************************************/ + +/* I2O SCSI Peripheral Error Report Reply Message Frame */ + +#ifdef _WIN64 +#define I2O_SCSI_SENSE_DATA_SZ 44 +#else +#define I2O_SCSI_SENSE_DATA_SZ 40 +#endif + +typedef struct _I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME { + I2O_SINGLE_REPLY_MESSAGE_FRAME StdReplyFrame; + U32 TransferCount; + U32 AutoSenseTransferCount; + U8 SenseData[I2O_SCSI_SENSE_DATA_SZ]; +} I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME, *PI2O_SCSI_ERROR_REPLY_MESSAGE_FRAME; + + +/****************************************************************************/ + +/* I2O SCSI Device Reset Message Frame */ + +typedef struct _I2O_SCSI_DEVICE_RESET_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +} I2O_SCSI_DEVICE_RESET_MESSAGE, *PI2O_SCSI_DEVICE_RESET_MESSAGE; + + +/****************************************************************************/ + +/* I2O SCSI Control Block Abort Message Frame */ + +typedef struct _I2O_SCSI_SCB_ABORT_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + I2O_TRANSACTION_CONTEXT TransactionContextToAbort; +} I2O_SCSI_SCB_ABORT_MESSAGE, *PI2O_SCSI_SCB_ABORT_MESSAGE; + + +/****************************************************************************/ + +/* I2O SCSI Control Block Execute Message Frame */ + +#define I2O_SCSI_CDB_LENGTH 16 + +typedef U16 I2O_SCB_FLAGS; + +#define I2O_SCB_FLAG_XFER_DIR_MASK 0xC000 +#define I2O_SCB_FLAG_NO_DATA_XFER 0x0000 +#define I2O_SCB_FLAG_XFER_FROM_DEVICE 0x4000 +#define I2O_SCB_FLAG_XFER_TO_DEVICE 0x8000 + +#define I2O_SCB_FLAG_ENABLE_DISCONNECT 0x2000 + +#define I2O_SCB_FLAG_TAG_TYPE_MASK 0x0380 +#define I2O_SCB_FLAG_NO_TAG_QUEUEING 0x0000 +#define I2O_SCB_FLAG_SIMPLE_QUEUE_TAG 0x0080 +#define I2O_SCB_FLAG_HEAD_QUEUE_TAG 0x0100 +#define I2O_SCB_FLAG_ORDERED_QUEUE_TAG 0x0180 +#define I2O_SCB_FLAG_ACA_QUEUE_TAG 0x0200 + +#define I2O_SCB_FLAG_AUTOSENSE_MASK 0x0060 +#define I2O_SCB_FLAG_DISABLE_AUTOSENSE 0x0000 +#define I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE 0x0020 +#define I2O_SCB_FLAG_SENSE_DATA_IN_BUFFER 0x0060 + +typedef struct _I2O_SCSI_SCB_EXECUTE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U8 CDBLength; + U8 Reserved; + I2O_SCB_FLAGS SCBFlags; + U8 CDB[I2O_SCSI_CDB_LENGTH]; + U32 ByteCount; + I2O_SG_ELEMENT SGL; +} I2O_SCSI_SCB_EXECUTE_MESSAGE, *PI2O_SCSI_SCB_EXECUTE_MESSAGE; + + +PRAGMA_PACK_POP + +PRAGMA_ALIGN_POP + +#endif /* I2O_BASE_SCSI_HDR */ diff --git a/sys/dev/asr/i2odep.h b/sys/dev/asr/i2odep.h new file mode 100644 index 000000000000..0fe2fc18954d --- /dev/null +++ b/sys/dev/asr/i2odep.h @@ -0,0 +1,1296 @@ +/* $FreeBSD$ */ +/**************************************************************************** + * + * Copyright (c) 1996-2000 Distributed Processing Technology Corporation + * Copyright (c) 2000 Adaptec Corporation. + * All rights reserved. + * + * Copyright (c) 1998 I2O Special Interest Group (I2O SIG) + * All rights reserved + * + * Redistribution and use in source form, with or without modification, are + * permitted provided that redistributions of source code must retain the + * above copyright notice, this list of conditions and the following disclaimer. + * + * This software is provided `as is' by Distributed Processing Technology 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 Distributed Processing Technology 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 + * interruptions) 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 driver software, even if advised + * of the possibility of such damage. + * + * This information is provided on an as-is basis without warranty of any + * kind, either express or implied, including but not limited to, implied + * warranties or merchantability and fitness for a particular purpose. I2O SIG + * does not warrant that this program will meet the user's requirements or + * that the operation of these programs will be uninterrupted or error-free. + * The I2O SIG disclaims all liability, including liability for infringement + * of any proprietary rights, relating to implementation of information in + * this specification. The I2O SIG does not warrant or represent that such + * implementations(s) will not infringe such rights. Acceptance and use of + * this program constitutes the user's understanding that he will have no + * recourse to I2O SIG for any actual or consequential damages including, but + * not limited to, loss profits arising out of use or inability to use this + * program. + * + * This information is provided for the purpose of recompilation of the + * driver code provided by Distributed Processing Technology only. It is + * NOT to be used for any other purpose. + * + * To develop other products based upon I2O definitions, it is necessary to + * become a "Registered Developer" of the I2O SIG. This can be done by calling + * 415-750-8352 in the US, or via http://www.i2osig.org. + * + **************************************************************************/ + +/* + * This template provides place holders for architecture and compiler + * dependencies. It should be filled in and renamed as i2odep.h. + * i2odep.h is included by i2otypes.h. <xxx> marks the places to fill. + */ + +#ifndef __INCi2odeph +#define __INCi2odeph + +#define I2ODEP_REV 1_5_4 + +/* + * Pragma macros. These are to assure appropriate alignment between + * host/IOP as defined by the I2O Specification. Each one of the shared + * header files includes these macros. + */ + +#define PRAGMA_ALIGN_PUSH +#define PRAGMA_ALIGN_POP +#define PRAGMA_PACK_PUSH +#define PRAGMA_PACK_POP + +/* Setup the basics */ + +typedef signed char S8; +typedef signed short S16; + +typedef unsigned char U8; +typedef unsigned short U16; + +typedef unsigned long U32; +typedef unsigned short S32; + + +/* Bitfields */ + +#if (defined(__BORLANDC__)) +typedef U16 BF; +#else +typedef U32 BF; +#endif + + +/* VOID */ + +#ifndef __VOID +#if (defined(_DPT_ARC)) +# define VOID void +#else + typedef void VOID; +#endif +#define __VOID +#endif + + +/* Boolean */ + +#ifndef __BOOL +#define __BOOL + +typedef unsigned char BOOL; +#endif + +#if (!defined(__FAR__)) +# if (defined(__BORLANDC__)) +# define __FAR__ far +# else +# define __FAR__ +# endif +#endif + +/* NULL */ + +#if (!defined(NULL)) +# define NULL ((VOID __FAR__ *)0L) +#endif + + +#if (defined(__SPARC__) || defined(__linux__)) +typedef char CHAR; +typedef char *pCHAR; +typedef char INT8; +typedef char *pINT8; +typedef unsigned char UINT8; +typedef unsigned char *pUINT8; +typedef short INT16; +typedef short *pINT16; +typedef unsigned short UINT16; +typedef unsigned short *pUINT16; +typedef long INT32; +typedef long *pINT32; +typedef unsigned long UINT32; +typedef unsigned long *pUINT32; +//typedef SCSI_REQUEST_BLOCK OS_REQUEST_T; +//typedef PSCSI_REQUEST_BLOCK pOS_REQUEST_T; +#define STATIC static +#ifndef __NEAR__ +# if (defined(__BORLANDC__)) +# define __NEAR__ near +# else +# define __NEAR__ +# endif +#endif +#define pVOID void * +#define pBOOLEAN BOOLEAN * +#endif + + +/* + * Copyright (c) 1996-2000 Distributed Processing Technology Corporation + * Copyright (c) 2000 Adaptec Corporation. + * All rights reserved. + */ +/* + * Define some generalized portability macros + * These macros follow the following parameterization: + * _F_getXXX(pointer,primaryElement<,offset>,referredElement) + * _F_setXXX(pointer,primaryElement<,offset>,referredElement,newValue) + * These parameters are shortened to u, w, x, y and z to reduce clutter. + */ +#if (defined(__BORLANDC__)) +# define I2O_TID_MASK ((U16)((1L<<I2O_TID_SZ)-1)) +/* First 12 bits */ +# define _F_getTID(w,x,y) (*((U16 __FAR__ *)(&((w)->x))) & I2O_TID_MASK) +# define _F_setTID(w,x,y,z) (*((U16 __FAR__ *)(&((w)->x)))\ + &= 0xFFFF - I2O_TID_MASK);\ + (*((U16 __FAR__ *)(&((w)->x)))\ + |=(U16)(z)&I2O_TID_MASK) +/* Seconds 12 bits (optimized with the assumption of 12 & 12) */ +# define _F_getTID1(w,x,y) ((*(U16 __FAR__ *)(((U8 __FAR__ *)(&((w)->x)))\ + + (I2O_TID_SZ/8)))\ + >> (I2O_TID_SZ-((I2O_TID_SZ/8)*8))) +# define _F_setTID1(w,x,y,z) ((*((U16 __FAR__ *)(((U8 __FAR__ *)(&((w)->x)))\ + + (I2O_TID_SZ/8)))) &= (0xFFFF >> I2O_TID_SZ));\ + ((*((U16 __FAR__ *)(((U8 __FAR__ *)(&((w)->x)))\ + + (I2O_TID_SZ/8)))) |= (z)\ + << (I2O_TID_SZ-((I2O_TID_SZ/8)*8))) +/* Last 8 bits */ +# define _F_getFunc(w,x,y) (*(((U8 __FAR__ *)(&((w)->x)))\ + + ((I2O_TID_SZ+I2O_TID_SZ)/8))) +# define _F_setFunc(w,x,y,z) (_F_getFunc(w,x,y) = (z)) +# define I2O_SG_COUNT_MASK ((U32)((1L<<I2O_SG_COUNT_SZ)-1)) +/* First 24 bits */ +# define _F_getCount(w,x,y) (*((U32 __FAR__ *)(&((w)->x)))&I2O_SG_COUNT_MASK) +/* + * The following is less efficient because of compiler inefficiencies: + * + * # define _F_setCount(w,x,y,z) *((U16 __FAR__ *)(&((w)->x))) = (U16)(z);\ + * ((U8 __FAR__ *)(&((w)->x)))[2]= (U8)((z)>>16L) + * + * so we will use the apparently more code intensive: + */ +# define _F_setCount(w,x,y,z) (*((U32 __FAR__ *)(&((w)->x)))\ + &= 0xFFFFFFFFL - I2O_SG_COUNT_MASK);\ + (*((U32 __FAR__ *)(&((w)->x)))\ + |= (z) & I2O_SG_COUNT_MASK) +/* Last 8 bits */ +# define _F_getFlags(w,x,y) (*(((U8 __FAR__ *)(&((w)->x)))\ + + (I2O_SG_COUNT_SZ/8))) +# define _F_setFlags(w,x,y,z) (_F_getFlags(w,x,y) = (z)) +/* Other accesses that are simpler */ +# define _F_get1bit(w,x,y,z) ((U8)((w)->z)) +# define _F_set1bit(w,x,y,z,u) ((w)->z = (u)) +# define _F_get1bit1(w,x,y,z) ((U8)((w)->z)) +# define _F_set1bit1(w,x,y,z,u) ((w)->z = (u)) +# define _F_get4bit4(w,x,y,z) ((U8)((w)->z)) +# define _F_set4bit4(w,x,y,z,u) ((w)->z = (u)) +# define _F_get8bit(w,x,y,z) ((U8)((w)->z)) +# define _F_set8bit(w,x,y,z,u) ((w)->z = (u)) +# define _F_get12bit(w,x,y,z) ((U16)((w)->z)) +# define _F_set12bit(w,x,y,z,u) ((w)->z = (u)) +# define _F_get12bit4(w,x,y,z) ((U16)((w)->z)) +# define _F_set12bit4(w,x,y,z,u) ((w)->z = (u)) +# define _F_get16bit(w,x,y,z) ((U16)((w)->z)) +# define _F_set16bit(w,x,y,z,u) ((w)->z = (u)) +#elif (defined(_DPT_BIG_ENDIAN)) +/* First 12 bits */ +# define _F_getTID(w,x,y) getL12bit(w,x,0) +# define _F_setTID(w,x,y,z) setL12bit(w,x,0,z) +# define _F_getTID1(w,x,y) getL12bit1(w,x,0) +# define _F_setTID1(w,x,y,z) setL12bit1(w,x,0,z) +# define _F_getFunc(w,x,y) getL8bit(w,x,3) +# define _F_setFunc(w,x,y,z) setL8bit(w,x,3,z) +# define _F_getCount(w,x,y) getL24bit1(w,x,0) +# define _F_setCount(w,x,y,z) setL24bit1(w,x,0,z) +# define _F_getFlags(w,x,y) getL8bit(w,x,3) +# define _F_setFlags(w,x,y,z) setL8bit(w,x,3,z) +/* Other accesses that are simpler */ +# define _F_get1bit(w,x,y,z) getL1bit(w,x,y) +# define _F_set1bit(w,x,y,z,u) setL1bit(w,x,y,u) +# define _F_get1bit1(w,x,y,z) getL1bit1(w,x,y) +# define _F_set1bit1(w,x,y,z,u) setL1bit1(w,x,y,u) +# define _F_get4bit4(w,x,y,z) getL4bit(w,x,y) +# define _F_set4bit4(w,x,y,z,u) setL4bit(w,x,y,u) +# define _F_get8bit(w,x,y,z) getL8bit(w,x,y) +# define _F_set8bit(w,x,y,z,u) setL8bit(w,x,y,u) +# define _F_get12bit(w,x,y,z) getL12bit(w,x,y) +# define _F_set12bit(w,x,y,z,u) setL12bit(w,x,y,z) +# define _F_get12bit4(w,x,y,z) getL12bit1(w,x,(y)-1) +# define _F_set12bit4(w,x,y,z,u) setL12bit1(w,x,(y)-1,u) +# define _F_get16bit(w,x,y,z) getL16bit(w,x,y) +# define _F_set16bit(w,x,y,z,u) setL16bit(w,x,y,u) +#else +# define _F_getTID(w,x,y) ((U16)((w)->y)) +# define _F_setTID(w,x,y,z) ((w)->y = (z)) +# define _F_getTID1(w,x,y) ((U16)((w)->y)) +# define _F_setTID1(w,x,y,z) ((w)->y = (z)) +# define _F_getFunc(w,x,y) ((U8)((w)->y)) +# define _F_setFunc(w,x,y,z) ((w)->y = (z)) +# define _F_getCount(w,x,y) ((U32)((w)->y)) +# define _F_setCount(w,x,y,z) ((w)->y = (z)) +# define _F_getFlags(w,x,y) ((U8)((w)->y)) +# define _F_setFlags(w,x,y,z) ((w)->y = (z)) +# define _F_get1bit(w,x,y,z) ((U8)((w)->z)) +# define _F_set1bit(w,x,y,z,u) ((w)->z = (u)) +# define _F_get1bit1(w,x,y,z) ((U8)((w)->z)) +# define _F_set1bit1(w,x,y,z,u) ((w)->z = (u)) +# define _F_get4bit4(w,x,y,z) ((U8)((w)->z)) +# define _F_set4bit4(w,x,y,z,u) ((w)->z = (u)) +# define _F_get8bit(w,x,y,z) ((U8)((w)->z)) +# define _F_set8bit(w,x,y,z,u) ((w)->z = (u)) +# define _F_get12bit(w,x,y,z) ((U16)((w)->z)) +# define _F_set12bit(w,x,y,z,u) ((w)->z = (u)) +# define _F_get12bit4(w,x,y,z) ((U16)((w)->z)) +# define _F_set12bit4(w,x,y,z,u) ((w)->z = (u)) +# define _F_get16bit(w,x,y,z) ((U16)((w)->z)) +# define _F_set16bit(w,x,y,z,u) ((w)->z = (u)) +#endif + +/* + * Define some specific portability macros + * These macros follow the following parameterization: + * XXX_getYYY (pointer) + * XXX_setYYY (pointer, newValue) + * These parameters are shortened to x and y to reduce clutter. + */ + +/* + * General SGE + */ +#define I2O_FLAGS_COUNT_getCount(x) _F_getCount(x,Count,Count) +#define I2O_FLAGS_COUNT_setCount(x,y) _F_setCount(x,Count,Count,y) +#define I2O_FLAGS_COUNT_getFlags(x) _F_getFlags(x,Count,Flags) +#define I2O_FLAGS_COUNT_setFlags(x,y) _F_setFlags(x,Count,Flags,y) + +/* + * I2O_SGE_SIMPLE_ELEMENT + */ +#define I2O_SGE_SIMPLE_ELEMENT_getPhysicalAddress(x) \ + getLU4((&(x)->PhysicalAddress),0) +#define I2O_SGE_SIMPLE_ELEMENT_setPhysicalAddress(x,y) \ + setLU4((&(x)->PhysicalAddress),0,y) +/* + * I2O_SGE_LONG_TRANSACTION_ELEMENT + */ +#define I2O_SGE_LONG_TRANSACTION_ELEMENT_getLongElementLength(x)\ + _F_getCount(x,LongElementLength,LongElementLength) +#define I2O_SGE_LONG_TRANSACTION_ELEMENT_setLongElementLength(x,y)\ + _F_setCount(x,LongElementLength,LongElementLength,y) +#define I2O_SGE_LONG_TRANSACTION_ELEMENT_getFlags(x)\ + _F_getFlags(x,LongElementLength,Flags) +#define I2O_SGE_LONG_TRANSACTION_ELEMENT_setFlags(x,y)\ + _F_setFlags(x,LongElementLength,Flags,y) + +/* + * I2O_SGE_LONG_TRANSPORT_ELEMENT + */ +#define I2O_SGE_LONG_TRANSPORT_ELEMENT_getLongElementLength(x)\ + _F_getCount(x,LongElementLength,LongElementLength) +#define I2O_SGE_LONG_TRANSPORT_ELEMENT_setLongElementLength(x,y)\ + _F_setCount(x,LongElementLength,LongElementLength,y) +#define I2O_SGE_LONG_TRANSPORT_ELEMENT_getFlags(x)\ + _F_getFlags(x,LongElementLength,Flags) +#define I2O_SGE_LONG_TRANSPORT_ELEMENT_setFlags(x,y)\ + _F_setFlags(x,LongElementLength,Flags,y) + +/* + * I2O_EXEC_ADAPTER_ASSIGN_MESSAGE + */ +#define I2O_EXEC_ADAPTER_ASSIGN_MESSAGE_getDdmTID(x)\ + _F_getTID(x,DdmTID,DdmTID) +#define I2O_EXEC_ADAPTER_ASSIGN_MESSAGE_setDdmTID(x,y)\ + _F_setTID(x,DDdmTID,DdmTID,y) +#define I2O_EXEC_ADAPTER_ASSIGN_MESSAGE_getOperationFlags(x)\ + _F_getFunc(x,DdmTID,OperationFlags) +#define I2O_EXEC_ADAPTER_ASSIGN_MESSAGE_setOperationFlags(x,y)\ + _F_setFunc(x,DdmTID,OperationFlags,y) + +/* + * I2O_EXEC_BIOS_INFO_SET_MESSAGE + */ +#define I2O_EXEC_BIOS_INFO_SET_MESSAGE_getDeviceTID(x)\ + _F_getTID(x,DeviceTID,DeviceTID) +#define I2O_EXEC_BIOS_INFO_SET_MESSAGE_setDeviceTID(x,y)\ + _F_setTID(x,DeviceTID,DeviceTID,y) +#define I2O_EXEC_BIOS_INFO_SET_MESSAGE_getBiosInfo(x)\ + _F_getFunc(x,DeviceTID,BiosInfo) +#define I2O_EXEC_BIOS_INFO_SET_MESSAGE_setBiosInfo(x,y) \ + _F_setFunc(x,DeviceTID,BiosInfo,y) + +/* + * I2O_ALIAS_CONNECT_SETUP + */ +#define I2O_ALIAS_CONNECT_SETUP_getIOP1AliasForTargetDevice(x)\ + _F_getTID(x,IOP1AliasForTargetDevice,IOP1AliasForTargetDevice) +#define I2O_ALIAS_CONNECT_SETUP_setIOP1AliasForTargetDevice(x,y)\ + _F_setTID(x,IOP1AliasForTargetDevice,IOP1AliasForTargetDevice,y) +#define I2O_ALIAS_CONNECT_SETUP_getIOP2AliasForInitiatorDevice(x)\ + _F_getTID1(x,IOP1AliasForTargetDevice,IOP2AliasForInitiatorDevice) +#define I2O_ALIAS_CONNECT_SETUP_setIOP2AliasForInitiatorDevice(x,y)\ + _F_setTID1(x,IOP1AliasForTargetDevice,IOP2AliasForInitiatorDevice,y) + +/* + * I2O_OBJECT_CONNECT_SETUP + */ +#define I2O_OBJECT_CONNECT_SETUP_getTargetDevice(x)\ + _F_getTID(x,TargetDevice,TargetDevice) +#define I2O_OBJECT_CONNECT_SETUP_setTargetDevice(x,y)\ + _F_setTID(x,TargetDevice,TargetDevice,y) +#define I2O_OBJECT_CONNECT_SETUP_getInitiatorDevice(x)\ + _F_getTID1(x,TargetDevice,InitiatorDevice) +#define I2O_OBJECT_CONNECT_SETUP_setInitiatorDevice(x,y)\ + _F_setTID1(x,TargetDevice,InitiatorDevice,y) +#define I2O_OBJECT_CONNECT_SETUP_getOperationFlags(x)\ + _F_getFunc(x,TargetDevice,OperationFlags) +#define I2O_OBJECT_CONNECT_SETUP_setOperationFlags(x,y)\ + _F_setFunc(x,TargetDevice,OperationFlags,y) + +/* + * I2O_OBJECT_CONNECT_REPLY + */ +#define I2O_OBJECT_CONNECT_REPLY_getTargetDevice(x)\ + _F_getTID(x,TargetDevice,TargetDevice) +#define I2O_OBJECT_CONNECT_REPLY_setTargetDevice(x,y)\ + _F_setTID(x,TargetDevice,TargetDevice,y) +#define I2O_OBJECT_CONNECT_REPLY_getInitiatorDevice(x)\ + _F_getTID1(x,TargetDevice,InitiatorDevice) +#define I2O_OBJECT_CONNECT_REPLY_setInitiatorDevice(x,y)\ + _F_setTID1(x,TargetDevice,InitiatorDevice,y) +#define I2O_OBJECT_CONNECT_REPLY_getReplyStatusCode(x)\ + _F_getFunc(x,TargetDevice,ReplyStatusCode) +#define I2O_OBJECT_CONNECT_REPLY_setReplyStatusCode(x,y)\ + _F_setFunc(x,TargetDevice,ReplyStatusCode,y) + +/* + * I2O_EXEC_DEVICE_ASSIGN_MESSAGE + */ +#define I2O_EXEC_DEVICE_ASSIGN_MESSAGE_getDeviceTID(x)\ + _F_getTID(x,Object.DeviceTID,Object.DeviceTID) +#define I2O_EXEC_DEVICE_ASSIGN_MESSAGE_setDeviceTID(x,y)\ + _F_setTID(x,Object.DeviceTID,Object.DeviceTID,y) +#define I2O_EXEC_DEVICE_ASSIGN_MESSAGE_getIOP_ID(x)\ + _F_getTID1(x,Object.DeviceTID,Object.IOP_ID) +#define I2O_EXEC_DEVICE_ASSIGN_MESSAGE_setIOP_ID(x,y)\ + _F_setTID1(x,Object.DeviceTID,Object.IOP_ID,y) +#define I2O_EXEC_DEVICE_ASSIGN_MESSAGE_getOperationFlags(x)\ + _F_getFunc(x,Object.DeviceTID,Object.OperationFlags) +#define I2O_EXEC_DEVICE_ASSIGN_MESSAGE_setOperationFlags(x,y)\ + _F_setFunc(x,Object.DeviceTID,Object.OperationFlags,y) + +/* + * I2O_EXEC_DEVICE_RELEASE_MESSAGE + */ +#define I2O_EXEC_DEVICE_RELEASE_MESSAGE_getDeviceTID(x)\ + _F_getTID(x,Object.DeviceTID,Object.DeviceTID) +#define I2O_EXEC_DEVICE_RELEASE_MESSAGE_setDeviceTID(x,y)\ + _F_setTID(x,Object.DeviceTID,Object.DeviceTID,y) +#define I2O_EXEC_DEVICE_RELEASE_MESSAGE_getIOP_ID(x)\ + _F_getTID1(x,Object.DeviceTID,Object.IOP_ID) +#define I2O_EXEC_DEVICE_RELEASE_MESSAGE_setIOP_ID(x,y)\ + _F_setTID1(x,Object.DeviceTID,Object.IOP_ID,y) +#define I2O_EXEC_DEVICE_RELEASE_MESSAGE_getOperationFlags(x)\ + _F_getFunc(x,Object.DeviceTID,Object.OperationFlags) +#define I2O_EXEC_DEVICE_RELEASE_MESSAGE_setOperationFlags(x,y)\ + _F_setFunc(x,Object.DeviceTID,Object.OperationFlags,y) + +/* + * I2O_EXEC_IOP_RESET_MESSAGE + */ +#define I2O_EXEC_IOP_RESET_MESSAGE_getTargetAddress(x)\ + _F_getTID(x,TargetAddress,TargetAddress) +#define I2O_EXEC_IOP_RESET_MESSAGE_setTargetAddress(x,y)\ + _F_setTID(x,TargetAddress,TargetAddress,y) +#define I2O_EXEC_IOP_RESET_MESSAGE_getInitiatorAddress(x)\ + _F_getTID1(x,TargetAddress,InitiatorAddress) +#define I2O_EXEC_IOP_RESET_MESSAGE_setInitiatorAddress(x,y)\ + _F_setTID1(x,TargetAddress,InitiatorAddress,y) +#define I2O_EXEC_IOP_RESET_MESSAGE_getFunction(x)\ + _F_getFunc(x,TargetAddress,Function) +#define I2O_EXEC_IOP_RESET_MESSAGE_setFunction(x,y)\ + _F_setFunc(x,TargetAddress,Function,y) +#define I2O_EXEC_IOP_RESET_MESSAGE_getVersionOffset(x)\ + getU1((&(x)->VersionOffset),0) +#define I2O_EXEC_IOP_RESET_MESSAGE_setVersionOffset(x,y)\ + setU1((&(x)->VersionOffset),0,y) +#define I2O_EXEC_IOP_RESET_MESSAGE_getMsgFlags(x)\ + getU1((&(x)->VersionOffset),1) +#define I2O_EXEC_IOP_RESET_MESSAGE_setMsgFlags(x,y)\ + setU1((&(x)->VersionOffset),1,y) +#define I2O_EXEC_IOP_RESET_MESSAGE_getMessageSize(x)\ + getLU2((&(x)->VersionOffset),2) +#define I2O_EXEC_IOP_RESET_MESSAGE_setMessageSize(x,y)\ + setLU2((&(x)->VersionOffset),2,y) +#define I2O_EXEC_IOP_RESET_MESSAGE_getStatusWordLowAddress(x)\ + getLU4((&(x)->StatusWordLowAddress),0) +#define I2O_EXEC_IOP_RESET_MESSAGE_setStatusWordLowAddress(x,y)\ + setLU4((&(x)->StatusWordLowAddress),0,y) +#define I2O_EXEC_IOP_RESET_MESSAGE_getStatusWordHighAddress(x)\ + getLU4((&(x)->StatusWordHighAddress),0) +#define I2O_EXEC_IOP_RESET_MESSAGE_setStatusWordHighAddress(x,y)\ + setLU4((&(x)->StatusWordHighAddress),0,y) + + +/* + * I2O_EXEC_STATUS_GET_MESSAGE + */ +#define I2O_EXEC_STATUS_GET_MESSAGE_getVersionOffset(x)\ + getU1((&(x)->VersionOffset),0) +#define I2O_EXEC_STATUS_GET_MESSAGE_setVersionOffset(x,y)\ + setU1((&(x)->VersionOffset),0,y) +#define I2O_EXEC_STATUS_GET_MESSAGE_getMsgFlags(x)\ + getU1((&(x)->VersionOffset),1) +#define I2O_EXEC_STATUS_GET_MESSAGE_setMsgFlags(x,y)\ + setU1((&(x)->VersionOffset),1,y) +#define I2O_EXEC_STATUS_GET_MESSAGE_getMessageSize(x)\ + getLU2((&(x)->VersionOffset),2) +#define I2O_EXEC_STATUS_GET_MESSAGE_setMessageSize(x,y)\ + setLU2((&(x)->VersionOffset),2,y) +#define I2O_EXEC_STATUS_GET_MESSAGE_getReplyBufferAddressLow(x)\ + getLU4((&(x)->ReplyBufferAddressLow),0) +#define I2O_EXEC_STATUS_GET_MESSAGE_setReplyBufferAddressLow(x,y)\ + setLU4((&(x)->ReplyBufferAddressLow),0,y) +#define I2O_EXEC_STATUS_GET_MESSAGE_getReplyBufferAddressHigh(x)\ + getLU4((&(x)->ReplyBufferAddressHigh),0) +#define I2O_EXEC_STATUS_GET_MESSAGE_setReplyBufferAddressHigh(x,y)\ + setLU4((&(x)->ReplyBufferAddressHigh),0,y) +#define I2O_EXEC_STATUS_GET_MESSAGE_getReplyBufferLength(x)\ + getLU4((&(x)->ReplyBufferLength),0) +#define I2O_EXEC_STATUS_GET_MESSAGE_setReplyBufferLength(x,y)\ + setLU4((&(x)->ReplyBufferLength),0,y) +#define I2O_EXEC_STATUS_GET_MESSAGE_getTargetAddress(x)\ + _F_getTID(x,TargetAddress,TargetAddress) +#define I2O_EXEC_STATUS_GET_MESSAGE_setTargetAddress(x,y)\ + _F_setTID(x,TargetAddress,TargetAddress,y) +#define I2O_EXEC_STATUS_GET_MESSAGE_getInitiatorAddress(x)\ + _F_getTID1(x,TargetAddress,InitiatorAddress) +#define I2O_EXEC_STATUS_GET_MESSAGE_setInitiatorAddress(x,y)\ + _F_setTID1(x,TargetAddress,InitiatorAddress,y) +#define I2O_EXEC_STATUS_GET_MESSAGE_getFunction(x)\ + _F_getFunc(x,TargetAddress,Function) +#define I2O_EXEC_STATUS_GET_MESSAGE_setFunction(x,y)\ + _F_setFunc(x,TargetAddress,Function,y) + +/* + * I2O_MESSAGE_FRAME + */ +#define I2O_MESSAGE_FRAME_getVersionOffset(x)\ + getU1((&((x)->VersionOffset)),0) +#define I2O_MESSAGE_FRAME_setVersionOffset(x,y)\ + setU1(((&(x)->VersionOffset)),0,y) +#define I2O_MESSAGE_FRAME_getMsgFlags(x)\ + getU1((&((x)->VersionOffset)),1) +#define I2O_MESSAGE_FRAME_setMsgFlags(x,y)\ + setU1((&((x)->VersionOffset)),1,y) +#define I2O_MESSAGE_FRAME_getMessageSize(x)\ + getLU2((&((x)->VersionOffset)),2) +#define I2O_MESSAGE_FRAME_setMessageSize(x,y)\ + setLU2((&((x)->VersionOffset)),2,y) +#define I2O_MESSAGE_FRAME_getTargetAddress(x)\ + _F_getTID(x,TargetAddress,TargetAddress) +#define I2O_MESSAGE_FRAME_setTargetAddress(x,y)\ + _F_setTID(x,TargetAddress,TargetAddress,y) +#define I2O_MESSAGE_FRAME_getInitiatorAddress(x)\ + _F_getTID1(x,TargetAddress,InitiatorAddress) +#define I2O_MESSAGE_FRAME_setInitiatorAddress(x,y)\ + _F_setTID1(x,TargetAddress,InitiatorAddress,y) +#define I2O_MESSAGE_FRAME_getFunction(x)\ + _F_getFunc(x,TargetAddress,Function) +#define I2O_MESSAGE_FRAME_setFunction(x,y)\ + _F_setFunc(x,TargetAddress,Function,y) +/* 32 bit only for now */ +#define I2O_MESSAGE_FRAME_getInitiatorContext(x)\ + (x)->InitiatorContext +#define I2O_MESSAGE_FRAME_setInitiatorContext(x,y)\ + ((x)->InitiatorContext = (y)) +/* + * We are spilling the 64 bit Context field into the Transaction + * context of the specific frames. Synchronous commands (resetIop + * et al) do not have this field, so beware. Also, Failed Reply frames + * can not contain the 64 bit context, the software must reference + * the PreservedMFA and pick up the 64 bit context from the incoming + * message frame. The software must make no reference to the + * TransactionContext field at all. + */ +#if defined(_MSC_VER) && _MSC_VER >= 800 +#ifndef u_int64_t +#define u_int64_t unsigned __int64 +#endif +#endif +#define I2O_MESSAGE_FRAME_getInitiatorContext64(x)\ + (*((u_int64_t *)(&((x)->InitiatorContext)))) +#define I2O_MESSAGE_FRAME_setInitiatorContext64(x,y)\ + ((*((u_int64_t *)(&((x)->InitiatorContext))))=(y)) + +/* + * I2O_EXEC_OUTBOUND_INIT_MESSAGE + */ +#define I2O_EXEC_OUTBOUND_INIT_MESSAGE_getHostPageFrameSize(x)\ + getLU4((&(x)->HostPageFrameSize),0) +#define I2O_EXEC_OUTBOUND_INIT_MESSAGE_setHostPageFrameSize(x,y)\ + setLU4((&(x)->HostPageFrameSize),0,y) +#define I2O_EXEC_OUTBOUND_INIT_MESSAGE_getInitCode(x)\ + getU1((&(x)->InitCode),0) +#define I2O_EXEC_OUTBOUND_INIT_MESSAGE_setInitCode(x,y)\ + setU1((&(x)->InitCode),0,y) +#define I2O_EXEC_OUTBOUND_INIT_MESSAGE_getreserved(x)\ + getU1((&(x)->reserved),0) +#define I2O_EXEC_OUTBOUND_INIT_MESSAGE_setreserved(x,y)\ + setU1((&(x)->reserved),0,y) +#define I2O_EXEC_OUTBOUND_INIT_MESSAGE_getOutboundMFrameSize(x)\ + getLU2((&(x)->OutboundMFrameSize),0) +#define I2O_EXEC_OUTBOUND_INIT_MESSAGE_setOutboundMFrameSize(x,y)\ + setLU2((&(x)->OutboundMFrameSize),0,y) + +/* + * I2O_EXEC_SYS_TAB_SET_MESSAGE + */ +#define I2O_EXEC_SYS_TAB_SET_MESSAGE_getIOP_ID(x)\ + _F_get12bit(x,IOP_ID,IOP_ID) +#define I2O_EXEC_SYS_TAB_SET_MESSAGE_setIOP_ID(x,y)\ + _F_set12bit(x,IOP_ID,IOP_ID,y) +/* #define I2O_EXEC_SYS_TAB_SET_MESSAGE_getreserved1(x) */ +#define I2O_EXEC_SYS_TAB_SET_MESSAGE_getHostUnitID(x)\ + _F_get16bit(x,IOP_ID,2,HostUnitID) +#define I2O_EXEC_SYS_TAB_SET_MESSAGE_setHostUnitID(x,y)\ + _F_set16bit(x,IOP_ID,2,HostUnitID,y) +#define I2O_EXEC_SYS_TAB_SET_MESSAGE_getSegmentNumber(x)\ + _F_get12bit(x,SegmentNumber,SegmentNumber) +#define I2O_EXEC_SYS_TAB_SET_MESSAGE_setSegmentNumber(x,y)\ + _F_get12bit(x,SegmentNumber,SegmentNumber,y) + +/* later + * I2O_EXEC_SYS_ENABLE_MESSAGE + */ + +/* + * I2O_CLASS_ID + */ +#define I2O_CLASS_ID_getClass(x)\ + _F_get12bit(x,Class,0,Class) +#define I2O_CLASS_ID_setClass(x,y)\ + _F_set12bit(x,Class,0,Class,y) +#define I2O_CLASS_ID_getVersion(x)\ + _F_get4bit4(x,Class,1,Version) +#define I2O_CLASS_ID_setVersion(x,y)\ + _F_set4bit4(x,Class,1,Version,y) +#define I2O_CLASS_ID_getOrganizationID(x)\ + _F_get16bit(x,Class,2,OrganizationID) +#define I2O_CLASS_ID_setOrganizationID(x,y)\ + _F_set16bit(x,Class,2,OrganizationID,y) + +/* + * I2O_SET_SYSTAB_HEADER + */ +#define I2O_SET_SYSTAB_HEADER_getNumberEntries(x)\ + getU1((&((x)->NumberEntries)),0) +#define I2O_SET_SYSTAB_HEADER_setNumberEntries(x,y)\ + setU1((&(x)->NumberEntries),0,y) +#define I2O_SET_SYSTAB_HEADER_getSysTabVersion(x)\ + getU1((&((x)->SysTabVersion)),0) +#define I2O_SET_SYSTAB_HEADER_setSysTabVersion(x,y)\ + setU1((&(x)->SysTabVersion),0,y) +/* U16 reserved */ +/* U32 CurrentChangeIndicator */ + + + + +/* + * I2O_IOP_ENTRY + */ +#define I2O_IOP_ENTRY_getOrganizationID(x)\ + getLU2((&((x)->OrganizationID)),0) +#define I2O_IOP_ENTRY_setOrganizationID(x,y)\ + setLU2((&((x)->OrganizationID)),0,y) +/* #define I2O_IOP_ENTRY_getreserved U16; */ +#define I2O_IOP_ENTRY_getIOP_ID(x)\ + _F_get12bit(x,IOP_ID,0,IOP_ID) +#define I2O_IOP_ENTRY_setIOP_ID(x,y)\ + _F_set12bit(x,IOP_ID,0,IOP_ID,y) +/* BF reserved3:I2O_RESERVED_4BITS; */ +/* BF reserved1:I2O_RESERVED_16BITS; */ +#define I2O_IOP_ENTRY_getSegmentNumber(x)\ + _F_get12bit(x,SegmentNumber,0,SegmentNumber) +#define I2O_IOP_ENTRY_setSegmentNumber(x,y)\ + _F_set12bit(x,SegmentNumber,0,SegmentNumber,y) +#define I2O_IOP_ENTRY_getI2oVersion(x)\ + _F_get4bit4(x,SegmentNumber,1,I2oVersion) +#define I2O_IOP_ENTRY_setI2oVersion(x,y)\ + _F_set4bit4(x,SegmentNumber,1,I2oVersion,y) +#define I2O_IOP_ENTRY_getIopState(x)\ + _F_get8bit(x,SegmentNumber,2,IopState) +#define I2O_IOP_ENTRY_setIopState(x,y)\ + _F_set8bit(x,SegmentNumber,2,IopState,y) +#define I2O_IOP_ENTRY_getMessengerType(x)\ + _F_get8bit(x,SegmentNumber,3,MessengerType) +#define I2O_IOP_ENTRY_setMessengerType(x,y)\ + _F_set8bit(x,SegmentNumber,3,MessengerType,y) +#define I2O_IOP_ENTRY_getInboundMessageFrameSize(x)\ + getLU2((&((x)->InboundMessageFrameSize)),0) +#define I2O_IOP_ENTRY_setInboundMessageFrameSize(x,y)\ + setLU2((&((x)->InboundMessageFrameSize)),0,y) +#define I2O_IOP_ENTRY_getreserved2(x)\ + getLU2((&((x)->reserved2)),0) +#define I2O_IOP_ENTRY_setreserved2(x,y)\ + setLU2((&((x)->reserved2)),0,y) +#define I2O_IOP_ENTRY_getLastChanged(x)\ + getLU4((&((x)->LastChanged)),0) +#define I2O_IOP_ENTRY_setLastChanged(x,y)\ + setLU4((&((x)->LastChanged)),0,y) +#define I2O_IOP_ENTRY_getIopCapabilities(x)\ + getLU4((&((x)->IopCapabilities)),0) +#define I2O_IOP_ENTRY_setIopCapabilities(x,y)\ + setLU4((&((x)->IopCapabilities)),0,y) + +/* might want to declare I2O_MESSENGER_INFO struct */ + +#define I2O_IOP_ENTRY_getInboundMessagePortAddressLow(x)\ + getLU4((&((x)->MessengerInfo.InboundMessagePortAddressLow)),0) +#define I2O_IOP_ENTRY_setInboundMessagePortAddressLow(x,y)\ + setLU4((&((x)->MessengerInfo.InboundMessagePortAddressLow)),0,y) + +#define I2O_IOP_ENTRY_getInboundMessagePortAddressHigh(x)\ + getLU4((&((x)->MessengerInfo.InboundMessagePortAddressHigh)),0) +#define I2O_IOP_ENTRY_setInboundMessagePortAddressHigh(x,y)\ + setLU4((&((x)->MessengerInfo.InboundMessagePortAddressHigh)),0,y) + +/* + * I2O_HRT + */ +#define I2O_HRT_getNumberEntries(x)\ + getLU2((&((x)->NumberEntries)),0) +#define I2O_HRT_setNumberEntries(x,y)\ + setLU2((&(x)->NumberEntries),0,y) +#define I2O_HRT_getEntryLength(x)\ + getU1((&(x)->EntryLength),0) +#define I2O_HRT_setEntryLength(x,y)\ + setU1((&(x)->EntryLength),0,y) +#define I2O_HRT_getHRTVersion(x)\ + getU1((&(x)->HRTVersion),0) +#define I2O_HRT_setHRTVersion(x,y)\ + setU1((&(x)->HRTVersion),0,y) +#define I2O_HRT_getCurrentChangeIndicator(x)\ + getLU4((&(x)->CurrentChangeIndicator),0) +#define I2O_HRT_setCurrentChangeIndicator(x,y)\ + setLU4((&(x)->CurrentChangeIndicator),0,y) +#define I2O_HRT_getHRTEntryPtr(x,y)\ + ((&((x)->HRTEntry[0+y]))) + +/* + * I2O_HRT_ENTRY + */ +#define I2O_HRT_ENTRY_getAdapterID(x)\ + getLU4((&((x)->AdapterID)),0) +#define I2O_HRT_ENTRY_setAdapterID(x,y)\ + setLU4((&(x)->AdapterID),0,y) +#define I2O_HRT_ENTRY_getControllingTID(x)\ + _F_get12bit(x,ControllingTID,ControllingTID) +#define I2O_HRT_ENTRY_setControllingTID(x,y)\ + _F_set12bit(x,ControllingTID,ControllingTID,y) +#define I2O_HRT_ENTRY_getAdapterState(x)\ + _F_get4bit4(x,ControllingTID,1,AdapterState) +#define I2O_HRT_ENTRY_setIAdapterState(x,y)\ + _F_set4bit4(x,ControllingTID,1,AdapterState,y) +#define I2O_HRT_ENTRY_getBusNumber(x)\ + _F_get8bit(x,ControllingTID,2,BusNumber) +#define I2O_HRT_ENTRY_setBusNumber(x,y)\ + _F_set8bit(x,ControllingTID,2,BusNumber,y) +#define I2O_HRT_ENTRY_getBusType(x)\ + _F_get8bit(x,ControllingTID,3,BusType) +#define I2O_HRT_ENTRY_setBusType(x,y)\ + _F_set8bit(x,ControllingTID,3,BusType,y) +#define I2O_HRT_ENTRY_getPCIBusPtr(x,y)\ + (&((x)->uBus.PCIBus)) + +/* + * I2O_LCT + */ +#define I2O_LCT_getTableSize(x)\ + _F_get16bit(x,TableSize,0,TableSize) +#define I2O_LCT_setTableSize(x,y)\ + _F_set16bit(x,TableSize,0,TableSize,y) +#define I2O_LCT_getBootDeviceTID(x)\ + _F_get12bit(x,TableSize,2,BootDeviceTID) +#define I2O_LCT_setBootDeviceTID(x,y)\ + _F_set12bit(x,TableSize,2,BootDeviceTID,y) +#define I2O_LCT_getLctVer(x)\ + _F_get4bit4(x,TableSize,3,LctVer) +#define I2O_LCT_setLctVer(x,y)\ + _F_set4bit4(x,TableSize,3,LctVer,y) +#define I2O_LCT_getIopFlags(x)\ + getLU4((&(x)->IopFlags),0) +#define I2O_LCT_setIopFlags(x,y)\ + setLU4((&(x)->IopFlags),0,y) +#define I2O_LCT_getCurrentChangeIndicator(x)\ + getLU4((&(x)->CurrentChangeIndicator),0) +#define I2O_LCT_setCurrentChangeIndicator(x,y)\ + setLU4((&(x)->CurrentChangeIndicator),0,y) +#define I2O_LCT_getLCTEntryPtr(x,y)\ + (&((x)->LCTEntry[0+y])) + +/* + * I2O_LCT_ENTRY + */ +#define I2O_LCT_ENTRY_getTableEntrySize(x)\ + _F_get16bit(x,TableEntrySize,0,TableEntrySize) +#define I2O_LCT_ENTRY_setTableEntrySize(x,y)\ + _F_set16bit(x,TableEntrySize,0,TableEntrySize,y) +#define I2O_LCT_ENTRY_getLocalTID(x)\ + _F_get12bit(x,TableEntrySize,2,LocalTID) +#define I2O_LCT_ENTRY_setLocalTID(x,y)\ + _F_set12bit(x,TableEntrySize,2,LocalTID,y) +/* BF 4 reserved:I2O_4BIT_VERSION_SZ; */ +#define I2O_LCT_ENTRY_getChangeIndicator(x)\ + getLU4((&(x)->ChangeIndicator),0) +#define I2O_LCT_ENTRY_setChangeIndicator(x,y)\ + setLU4((&(x)->ChangeIndicator),0,y) +#define I2O_LCT_ENTRY_getDeviceFlags(x)\ + getLU4((&(x)->DeviceFlags),0) +#define I2O_LCT_ENTRY_setDeviceFlags(x,y)\ + setLU4((&(x)->DeviceFlags),0,y) +#define I2O_LCT_ENTRY_getClassIDPtr(x)\ + (&((x)->ClassID)) +#define I2O_LCT_ENTRY_getSubClassInfo(x)\ + getLU4((&(x)->SubClassInfo),0) +#define I2O_LCT_ENTRY_setSubClassInfo(x,y)\ + setLU4((&(x)->SubClassInfo),0,y) +#define I2O_LCT_ENTRY_getUserTID(x)\ + _F_getTID(x,UserTID,UserTID) +#define I2O_LCT_ENTRY_setUserTID(x,y)\ + _F_setTID(x,UserTID,UserTID,y) +#define I2O_LCT_ENTRY_getParentTID(x)\ + _F_getTID1(x,UserTID,ParentTID) +#define I2O_LCT_ENTRY_setParentTID(x,y)\ + _F_getTID1(x,UserTID,ParentTID,y) +#define I2O_LCT_ENTRY_getBiosInfo(x)\ + _F_getFunc(x,UserTID,BiosInfo) +#define I2O_LCT_ENTRY_setBiosInfo(x,y)\ + _F_setFunc(x,UserTID,BiosInfo,y) +/* 2 ulong U8 8 IdentityTag[I2O_IDENTITY_TAG_SZ]; */ +#define I2O_LCT_ENTRY_getEventCapabilities(x)\ + getLU4((&(x)->EventCapabilities),0) +#define I2O_LCT_ENTRY_setEventCapabilities(x,y)\ + setLU4((&(x)->EventCapabilities),0,y) + +/* + * I2O_PARAM_OPERATIONS_LIST_HEADER + */ +#define I2O_PARAM_OPERATIONS_LIST_HEADER_getOperationCount(x)\ + getLU2((&(x)->OperationCount),0) +#define I2O_PARAM_OPERATIONS_LIST_HEADER_setOperationCount(x,y)\ + setLU2((&(x)->OperationCount),0,y) +#define I2O_PARAM_OPERATIONS_LIST_HEADER_getReserved(x)\ + getLU2((&(x)->Reserved),0) +#define I2O_PARAM_OPERATIONS_LIST_HEADER_setReserved(x,y)\ + setLU2((&(x)->Reserved),0,y) + +/* + * I2O_PARAM_OPERATION_ALL_TEMPLATE + */ +#define I2O_PARAM_OPERATION_ALL_TEMPLATE_getOperation(x)\ + getLU2((&(x)->Operation),0) +#define I2O_PARAM_OPERATION_ALL_TEMPLATE_setOperation(x,y)\ + setLU2((&(x)->Operation),0,y) +#define I2O_PARAM_OPERATION_ALL_TEMPLATE_getGroupNumber(x)\ + getLU2((&(x)->GroupNumber),0) +#define I2O_PARAM_OPERATION_ALL_TEMPLATE_setGroupNumber(x,y)\ + setLU2((&(x)->GroupNumber),0,y) +#define I2O_PARAM_OPERATION_ALL_TEMPLATE_getFieldCount(x)\ + getLU2((&(x)->FieldCount),0) +#define I2O_PARAM_OPERATION_ALL_TEMPLATE_setFieldCount(x,y)\ + setLU2((&(x)->FieldCount),0,y) + +/* + * I2O_PARAM_RESULTS_LIST_HEADER + */ +#define I2O_PARAM_RESULTS_LIST_HEADER_getResultCount(x)\ + getLU2((&(x)->ResultCount),0) +#define I2O_PARAM_RESULTS_LIST_HEADER_setResultCount(x,y)\ + setLU2((&(x)->ResultCount),0,y) +#define I2O_PARAM_RESULTS_LIST_HEADER_getReserved(x)\ + getLU2((&(x)->Reserved),0) +#define I2O_PARAM_RESULTS_LIST_HEADER_setReserved(x,y)\ + setLU2((&(x)->Reserved),0,y) + +/* later + * I2O_HBA_ADAPTER_RESET_MESSAGE + */ + + +/* LATER + * I2O_SCSI_DEVICE_RESET_MESSAGE + */ + + +/* LATER + * I2O_HBA_BUS_RESET_MESSAGE + */ + + +/* + * I2O_EXEC_LCT_NOTIFY_MESSAGE + */ +/* I2O_MESSAGE_FRAME StdMessageFrame; */ +/* I2O_TRANSACTION_CONTEXT TransactionContext; */ +#define I2O_EXEC_LCT_NOTIFY_MESSAGE_getClassIdentifier(x)\ + getLU4((&(x)->ClassIdentifier),0) +#define I2O_EXEC_LCT_NOTIFY_MESSAGE_setClassIdentifier(x,y)\ + setLU4((&(x)->ClassIdentifier),0,y) +#define I2O_EXEC_LCT_NOTIFY_MESSAGE_getLastReportedChangeIndicator(x)\ + getLU4((&(x)->LastReportedChangeIndicator),0) +#define I2O_EXEC_LCT_NOTIFY_MESSAGE_setLastReportedChangeIndicator(x,y)\ + setLU4((&(x)->LastReportedChangeIndicator),0,y) +/* I2O_SG_ELEMENT SGL; */ + + + +/* + * I2O_UTIL_PARAMS_GET_MESSAGE + */ +/* I2O_MESSAGE_FRAME StdMessageFrame; */ +/* I2O_TRANSACTION_CONTEXT TransactionContext; */ +#define I2O_UTIL_PARAMS_GET_MESSAGE_getOperationFlags(x)\ + getLU4((&(x)->OperationFlags),0) +#define I2O_UTIL_PARAMS_GET_MESSAGE_setOperationFlags(x,y)\ + setLU4((&(x)->OperationFlags),0,y) +/* I2O_SG_ELEMENT SGL; */ + + +/* + * I2O_SCSI_SCB_ABORT_MESSAGE + */ +#define I2O_SCSI_SCB_ABORT_MESSAGE_getStdMessageFramePtr(x)\ + (&((x)->StdMessageFrame)) +#define I2O_SCSI_SCB_ABORT_MESSAGE_getTransactionContext(x)\ + (x)->TransactionContext +#define I2O_SCSI_SCB_ABORT_MESSAGE_setTransactionContext(x,y)\ + ((x)->TransactionContext = (y)) +#define I2O_SCSI_SCB_ABORT_MESSAGE_getTransactionContextToAbort(x)\ + (x)->TransactionContextToAbort +#define I2O_SCSI_SCB_ABORT_MESSAGE_setTransactionContextToAbort(x,y)\ + ((x)->TransactionContextToAbort = (y)) + + +/* + * I2O_DPT_DEVICE_INFO_SCALAR + */ +#define I2O_DPT_DEVICE_INFO_SCALAR_getDeviceType(x)\ + getU1((&(x)->DeviceType),0) +#define I2O_DPT_DEVICE_INFO_SCALAR_setDeviceType(x,y)\ + setU1((&(x)->DeviceType),0,y) +#define I2O_DPT_DEVICE_INFO_SCALAR_getFlags(x)\ + getU1((&(x)->Flags),0) +#define I2O_DPT_DEVICE_INFO_SCALAR_setFlags(x,y)\ + setU1((&(x)->Flags),0,y) +#define I2O_DPT_DEVICE_INFO_SCALAR_getBus(x)\ + getLU2((&(x)->Bus),0) +#define I2O_DPT_DEVICE_INFO_SCALAR_setBus(x,y)\ + setLU2((&(x)->Bus),0,y) +#define I2O_DPT_DEVICE_INFO_SCALAR_getIdentifier(x)\ + getLU4((&(x)->Identifier),0) +#define I2O_DPT_DEVICE_INFO_SCALAR_setIdentifier(x,y)\ + setLU4((&(x)->Identifier),0,y) +/* U8 LunInfo[8]; // SCSI-2 8-bit scalar LUN goes into offset 1 */ +#define I2O_DPT_DEVICE_INFO_SCALAR_getLunInfo(x)\ + getU1((&(x)->LunInfo[0]),1) +#define I2O_DPT_DEVICE_INFO_SCALAR_setLunInfo(x,y)\ + setU1((&(x)->LunInfo[0]),1,y) + +/* + * I2O_DPT_EXEC_IOP_BUFFERS_SCALAR + */ +#define I2O_DPT_EXEC_IOP_BUFFERS_SCALAR_getSerialOutputOffset(x)\ + getLU4((&(x)->SerialOutputOffset),0) +#define I2O_DPT_EXEC_IOP_BUFFERS_SCALAR_getSerialOutputSizet(x)\ + getLU4((&(x)->SerialOutputSize),0) +#define I2O_DPT_EXEC_IOP_BUFFERS_SCALAR_getSerialHeaderSize(x)\ + getLU4((&(x)->SerialHeaderSize),0) +#define I2O_DPT_EXEC_IOP_BUFFERS_SCALAR_getSerialFlagsSupported(x)\ + getLU4((&(x)->SerialFlagsSupported),0) + +/* + * I2O_PRIVATE_MESSAGE_FRAME + */ +/* typedef struct _I2O_PRIVATE_MESSAGE_FRAME { */ +/* I2O_MESSAGE_FRAME StdMessageFrame; */ +/* I2O_TRANSACTION_CONTEXT TransactionContext; */ +/* U16 XFunctionCode; */ +/* U16 OrganizationID; */ +/* PrivatePayload[]; */ +/* } I2O_PRIVATE_MESSAGE_FRAME, *PI2O_PRIVATE_MESSAGE_FRAME; */ +#define I2O_PRIVATE_MESSAGE_FRAME_getTransactionContext(x) \ + (x)->TransactionContext +#define I2O_PRIVATE_MESSAGE_FRAME_setTransactionContext(x,y) \ + ((x)->TransactionContext = (y)) +#define I2O_PRIVATE_MESSAGE_FRAME_getXFunctionCode(x) \ + getLU2((&(x)->XFunctionCode),0) +#define I2O_PRIVATE_MESSAGE_FRAME_setXFunctionCode(x,y) \ + setLU2((&(x)->XFunctionCode),0,y) +#define I2O_PRIVATE_MESSAGE_FRAME_getOrganizationID(x) \ + getLU2((&(x)->OrganizationID),0) +#define I2O_PRIVATE_MESSAGE_FRAME_setOrganizationID(x,y) \ + setLU2((&(x)->OrganizationID),0,y) +/* typedef struct _PRIVATE_SCSI_SCB_EXECUTE_MESSAGE { + * I2O_PRIVATE_MESSAGE_FRAME PRIVATE_SCSI_SCB_EXECUTE_MESSAGE; + * BF TID:16; // Upper four bits currently are zero + * // Command is interpreted by the host + * BF Interpret:1; + * // if TRUE, deal with Physical Firmware Array information + * BF Physical:1; + * BF Reserved1:14; + * U8 CDBLength; + * U8 Reserved; + * I2O_SCB_FLAGS SCBFlags; + * U8 CDB[ I2O_SCSI_CDB_LENGTH=16 ]; + * U32 ByteCount; + * I2O_SG_ELEMENT SGL; + * } PRIVATE_SCSI_SCB_EXECUTE_MESSAGE, * PPRIVATE_SCSI_SCB_EXECUTE_MESSAGE; + */ +/* + * PRIVATE_SCSI_SCB_EXECUTE_MESSAGE + */ +#define PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_getPRIVATE_SCSI_SCB_EXECUTE_MESSAGEPtr(x)\ + (&((x)->PRIVATE_SCSI_SCB_EXECUTE_MESSAGE)) +#define PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_getCDBLength(x)\ + getU1((&(x)->CDBLength),0) +#define PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setCDBLength(x,y)\ + setU1((&(x)->CDBLength),0,y) +#define PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_getReserved(x)\ + getU1((&(x)->Reserved),0) +#define PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setReserved(x,y)\ + setU1((&(x)->Reserved),0,y) +#define PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_getSCBFlags(x)\ + getLU2((&(x)->SCBFlags),0) +#define PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setSCBFlags(x,y)\ + setLU2((&(x)->SCBFlags),0,y) +#define PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_getByteCount(x)\ + getLU4((&((x)->ByteCount)),0) +#define PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setByteCount(x,y)\ + setLU4((&((x)->ByteCount)),0,y) +#define PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_getTID(x)\ + _F_get16bit(x,TID,0,TID) +#define PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setTID(x,y)\ + _F_set16bit(x,TID,0,TID,y) +#define PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_getInterpret(x)\ + _F_get1bit(x,TID,2,Interpret) +#define PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setInterpret(x,y)\ + _F_set1bit(x,TID,2,Interpret,y) +#define PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_getPhysical(x)\ + _F_get1bit1(x,TID,2,Physical) +#define PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setPhysical(x,y)\ + _F_set1bit1(x,TID,2,Physical,y) +#define PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_getCDBPtr(x)\ + (&((x)->CDB[0])) + + +/* + * PRIVATE_FLASH_REGION_MESSAGE + */ +#define PRIVATE_FLASH_REGION_MESSAGE_getFlashRegion(x) \ + getLU4((&((x)->FlashRegion)),0) +#define PRIVATE_FLASH_REGION_MESSAGE_setFlashRegion(x,y) \ + setLU4((&((x)->FlashRegion)),0,y) +#define PRIVATE_FLASH_REGION_MESSAGE_getRegionOffset(x) \ + getLU4((&((x)->RegionOffset)),0) +#define PRIVATE_FLASH_REGION_MESSAGE_setRegionOffset(x,y) \ + setLU4((&((x)->RegionOffset)),0,y) +#define PRIVATE_FLASH_REGION_MESSAGE_getByteCount(x) \ + getLU4((&((x)->ByteCount)),0) +#define PRIVATE_FLASH_REGION_MESSAGE_setByteCount(x,y) \ + setLU4((&((x)->ByteCount)),0,y) + +/* + * I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR + */ +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_getSCSIType(x)\ + getU1((&(x)->SCSIType),0) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_setSCSIType(x,y)\ + setU1((&(x)->SCSIType),0,y) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_getProtectionManagement(x)\ + getU1((&(x)->ProtectionManagement),0) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_setProtectionManagement(x,y)\ + setU1((&(x)->ProtectionManagement),0,y) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_getSettings(x)\ + getU1((&(x)->Settings),0) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_setSettings(x,y)\ + setU1((&(x)->Settings),0,y) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_getReserved1(x)\ + getU1((&(x)->Reserved1),0) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_setReserved1(x,y)\ + setU1((&(x)->Reserved1),0,y) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_getInitiatorID(x)\ + getLU4((&(x)->InitiatorID),0) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_setInitiatorID(x,y)\ + setLU4((&(x)->InitiatorID),0,y) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_getScanLun0Only(x)\ + getLU4((&(x)->ScanLun0Only),0) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_setScanLun0Only(x,y)\ + setLU4((&(x)->ScanLun0Only),0,y) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_getDisableDevice(x)\ + getLU2((&(x)->DisableDevice),0) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_setDisableDevice(x,y)\ + setLU2((&(x)->DisableDevice),0,y) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_getMaxOffset(x)\ + getU1((&(x)->MaxOffset),0) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_setMaxOffset(x,y)\ + setU1((&(x)->MaxOffset),0,y) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_getMaxDataWidth(x)\ + getU1((&(x)->MaxDataWidth),0) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_setMaxDataWidth(x,y)\ + setU1((&(x)->MaxDataWidth),0,y) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_getMaxSyncRate(x)\ + getLU4((&(x)->MaxSyncRate),0) +#define I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_setMaxSyncRate(x,y)\ + setLU4((&(x)->MaxSyncRate),0,y) + +/* + * I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME + */ +#define I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME_getStdReplyFramePtr(x)\ + (&((x)->StdReplyFrame)) +#define I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME_getTransferCount(x)\ + getLU4((&(x)->TransferCount),0) +#define I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME_setTransferCount(x,y)\ + setLU4((&(x)->TransferCount),0,y) +#define I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME_getAutoSenseTransferCount(x)\ + getLU4((&(x)->AutoSenseTransferCount),0) +#define I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME_setAutoSenseTransferCount(x,y)\ + setLU4((&(x)->AutoSenseTransferCount),0,y) + +/* + * I2O_SINGLE_REPLY_MESSAGE_FRAME + */ +#define I2O_SINGLE_REPLY_MESSAGE_FRAME_getStdMessageFramePtr(x)\ + (&((x)->StdMessageFrame)) +#define I2O_SINGLE_REPLY_MESSAGE_FRAME_getTransactionContext(x)\ + (x)->TransactionContext +#define I2O_SINGLE_REPLY_MESSAGE_FRAME_setTransactionContext(x,y)\ + ((x)->TransactionContext = (y)) +#define I2O_SINGLE_REPLY_MESSAGE_FRAME_getDetailedStatusCode(x)\ + getLU2((&((x)->DetailedStatusCode)),0) +#define I2O_SINGLE_REPLY_MESSAGE_FRAME_setDetailedStatusCode(x,y)\ + setLU2((&((x)->DetailedStatusCode)),0,y) +#define I2O_SINGLE_REPLY_MESSAGE_FRAME_getreserved(x)\ + getU1((&((x)->reserved)),0) +#define I2O_SINGLE_REPLY_MESSAGE_FRAME_setreserved(x,y)\ + setU1((&((x)->reserved)),0,y) +#define I2O_SINGLE_REPLY_MESSAGE_FRAME_getReqStatus(x)\ + getU1((&((x)->ReqStatus)),0) +#define I2O_SINGLE_REPLY_MESSAGE_FRAME_setReqStatus(x,y)\ + setU1((&((x)->ReqStatus)),0,y) + + +/* + * I2O_SCSI_SCB_EXECUTE_MESSAGE + */ +#define I2O_SCSI_SCB_EXECUTE_MESSAGE_getStdMessageFramePtr(x)\ + (&((x)->StdMessageFrame)) +#define I2O_SCSI_SCB_EXECUTE_MESSAGE_getTransactionContext(x)\ + (x)->TransactionContext +#define I2O_SCSI_SCB_EXECUTE_MESSAGE_setTransactionContext(x,y)\ + ((x)->TransactionContext = (y)) +#define I2O_SCSI_SCB_EXECUTE_MESSAGE_getCDBLength(x)\ + getU1((&((x)->CDBLength)),0) +#define I2O_SCSI_SCB_EXECUTE_MESSAGE_setCDBLength(x,y)\ + setU1((&((x)->CDBLength)),0,y) +#define I2O_SCSI_SCB_EXECUTE_MESSAGE_getReserved(x)\ + getU1((&((x)->Reserved)),0) +#define I2O_SCSI_SCB_EXECUTE_MESSAGE_setReserved(x,y)\ + setU1((&((x)->Reserved)),0,y) +#define I2O_SCSI_SCB_EXECUTE_MESSAGE_getSCBFlags(x)\ + getLU2((&((x)->SCBFlags)),0) +#define I2O_SCSI_SCB_EXECUTE_MESSAGE_setSCBFlags(x,y)\ + setLU2((&((x)->SCBFlags)),0,y) +#define I2O_SCSI_SCB_EXECUTE_MESSAGE_getByteCount(x)\ + getLU2((&((x)->ByteCount)),0) +#define I2O_SCSI_SCB_EXECUTE_MESSAGE_setByteCount(x,y)\ + setLU2((&((x)->ByteCount)),0,y) +/* define for these */ +/* U8 CDB[16]; */ +/* I2O_SG_ELEMENT SGL; */ + + +/* + * I2O_FAILURE_REPLY_MESSAGE_FRAME + */ +#define I2O_FAILURE_REPLY_MESSAGE_FRAME_getStdMessageFramePtr(x)\ + (&((x)->StdMessageFrame)) +#define I2O_FAILURE_REPLY_MESSAGE_FRAME_getTransactionContext(x)\ + (x)->TransactionContext +#define I2O_FAILURE_REPLY_MESSAGE_FRAME_setTransactionContext(x,y)\ + ((x)->TransactionContext = (y)) +#define I2O_FAILURE_REPLY_MESSAGE_FRAME_getLowestVersion(x)\ + getU1((&((x)->LowestVersion)),0) +#define I2O_FAILURE_REPLY_MESSAGE_FRAME_setLowestVersion(x,y)\ + setU1((&((x)->LowestVersion)),0,y) +#define I2O_FAILURE_REPLY_MESSAGE_FRAME_getHighestVersion(x)\ + getU1((&((x)->HighestVersion)),0) +#define I2O_FAILURE_REPLY_MESSAGE_FRAME_setHighestVersion(x,y)\ + setU1((&((x)->HighestVersion)),0,y) +#define I2O_FAILURE_REPLY_MESSAGE_FRAME_getAgeLimit(x)\ + getLU4((&((x)->AgeLimit)),0) +#define I2O_FAILURE_REPLY_MESSAGE_FRAME_setAgeLimit(x,y)\ + setLU4((&((x)->AgeLimit)),0,y) +#define I2O_FAILURE_REPLY_MESSAGE_FRAME_getSeverity(x)\ + _F_get8bit(x,Severity,0,Severity) +#define I2O_FAILURE_REPLY_MESSAGE_FRAME_setSeverity(x,y)\ + _F_set8bit(x,Severity,0,Severity,y) +#define I2O_FAILURE_REPLY_MESSAGE_FRAME_getFailureCode(x)\ + _F_get8bit(x,Severity,1,FailureCode) +#define I2O_FAILURE_REPLY_MESSAGE_FRAME_setFailureCode(x,y)\ + _F_get8bit(x,Severity,1,FailureCode,y) +/* + * #define I2O_FAILURE_REPLY_MESSAGE_FRAME_getFailingHostUnitID(x)\ + * _F_get16bit(x,reserved,1,FailingHostUnitID) + * #define I2O_FAILURE_REPLY_MESSAGE_FRAME_setFailingHostUnitID(x,y)\ + * _F_set16bit(x,reserved,1,FailingHostUnitID,y) + */ +#define I2O_FAILURE_REPLY_MESSAGE_FRAME_getPreservedMFA(x)\ + getLU4((&((x)->PreservedMFA)),0) +#define I2O_FAILURE_REPLY_MESSAGE_FRAME_setPreservedMFA(x,y)\ + setLU4((&((x)->PreservedMFA)),0,y) + + + +/* + * I2O_EXEC_STATUS_GET_REPLY + */ +#define I2O_EXEC_STATUS_GET_REPLY_getOrganizationID(x)\ + getLU2((&(x)->OrganizationID),0) +#define I2O_EXEC_STATUS_GET_REPLY_setOrganizationID(x,y)\ + setLU2((&(x)->OrganizationID),0,y) +/* #define I2O_EXEC_STATUS_GET_REPLY_getreserved; */ +#define I2O_EXEC_STATUS_GET_REPLY_getIOP_ID(x)\ + _F_get12bit(x,IOP_ID,0,IOP_ID) +#define I2O_EXEC_STATUS_GET_REPLY_setIOP_ID(x,y)\ + _F_set12bit(x,IOP_ID,0,IOP_ID,y) +/* #define I2O_EXEC_STATUS_GET_REPLY_getreserved1(x) */ +#define I2O_EXEC_STATUS_GET_REPLY_getHostUnitID(x)\ + _F_get16bit(x,IOP_ID,2,HostUnitID) +#define I2O_EXEC_STATUS_GET_REPLY_setHostUnitID(x,y)\ + _F_set16bit(x,IOP_ID,2,HostUnitID,y) +#define I2O_EXEC_STATUS_GET_REPLY_getSegmentNumber(x)\ + _F_get12bit(x,SegmentNumber,0,SegmentNumber) +#define I2O_EXEC_STATUS_GET_REPLY_setSegmentNumber(x,y)\ + _F_set12bit(x,SegmentNumber,0,SegmentNumber,y) +#define I2O_EXEC_STATUS_GET_REPLY_getI2oVersion(x)\ + _F_get4bit4(x,SegmentNumber,1,I2oVersion) +#define I2O_EXEC_STATUS_GET_REPLY_setI2oVersion(x,y)\ + _F_set4bit4(x,SegmentNumber,1,I2oVersion,y) +#define I2O_EXEC_STATUS_GET_REPLY_getIopState(x)\ + _F_get8bit(x,SegmentNumver,2,IopState) +#define I2O_EXEC_STATUS_GET_REPLY_setIopState(x,y)\ + _F_set8bit(x,SegmentNumver,2,IopState,y) +#define I2O_EXEC_STATUS_GET_REPLY_getMessengerType(x)\ + _F_get8bit(x,SegmentNumber,3,MessengerType) +#define I2O_EXEC_STATUS_GET_REPLY_setMessengerType(x,y)\ + _F_get8bit(x,SegmentNumber,3,MessengerType,y) +#define I2O_EXEC_STATUS_GET_REPLY_getInboundMFrameSize(x)\ + getLU2((&(x)->InboundMFrameSize),0) +#define I2O_EXEC_STATUS_GET_REPLY_setInboundMFrameSize(x,y)\ + setLU2((&(x)->InboundMFrameSize),0,y) +#define I2O_EXEC_STATUS_GET_REPLY_getInitCode(x)\ + getU1((&(x)->InitCode),0) +#define I2O_EXEC_STATUS_GET_REPLY_setInitCode(x,y)\ + setU1((&(x)->InitCode),0,y) +/* #define I2O_EXEC_STATUS_GET_REPLY_getreserved2(x) */ +#define I2O_EXEC_STATUS_GET_REPLY_getMaxInboundMFrames(x)\ + getLU4((&(x)->MaxInboundMFrames),0) +#define I2O_EXEC_STATUS_GET_REPLY_setMaxInboundMFrames(x,y)\ + setLU4((&(x)->MaxInboundMFrames),0,y) +#define I2O_EXEC_STATUS_GET_REPLY_getCurrentInboundMFrames(x)\ + getLU4((&(x)->CurrentInboundMFrames),0) +#define I2O_EXEC_STATUS_GET_REPLY_setCurrentInboundMFrames(x,y)\ + setLU4((&(x)->CurrentInboundMFrames),0,y) +#define I2O_EXEC_STATUS_GET_REPLY_getMaxOutboundMFrames(x)\ + getLU4((&(x)->MaxOutboundMFrames),0) +#define I2O_EXEC_STATUS_GET_REPLY_setMaxOutboundMFrames(x,y)\ + setLU4((&(x)->MaxOutboundMFrames),0,y) +/* #define I2O_EXEC_STATUS_GET_REPLY_getProductIDString(x) */ +#define I2O_EXEC_STATUS_GET_REPLY_getExpectedLCTSize(x)\ + getLU4((&(x)->ExpectedLCTSize),0) +#define I2O_EXEC_STATUS_GET_REPLY_setExpectedLCTSize(x,y)\ + setLU4((&(x)->ExpectedLCTSize),0,y) +#define I2O_EXEC_STATUS_GET_REPLY_getIopCapabilities(x)\ + getLU4((&(x)->IopCapabilities),0) +#define I2O_EXEC_STATUS_GET_REPLY_setIopCapabilities(x,y)\ + setLU4((&(x)->IopCapabilities),0,y) +#define I2O_EXEC_STATUS_GET_REPLY_getDesiredPrivateMemSize(x)\ + getLU4((&(x)->DesiredPrivateMemSize),0) +#define I2O_EXEC_STATUS_GET_REPLY_setDesiredPrivateMemSize(x,y)\ + setLU4((&(x)->DesiredPrivateMemSize),0,y) +#define I2O_EXEC_STATUS_GET_REPLY_getCurrentPrivateMemSize(x)\ + getLU4((&(x)->CurrentPrivateMemSize),0) +#define I2O_EXEC_STATUS_GET_REPLY_setCurrentPrivateMemSize(x,y)\ + setLU4((&(x)->CurrentPrivateMemSize),0,y) +#define I2O_EXEC_STATUS_GET_REPLY_getCurrentPrivateMemBase(x)\ + getLU4((&(x)->CurrentPrivateMemBase),0) +#define I2O_EXEC_STATUS_GET_REPLY_setCurrentPrivateMemBase(x,y)\ + setLU4((&(x)->CurrentPrivateMemBase),0,y) +#define I2O_EXEC_STATUS_GET_REPLY_getDesiredPrivateIOSize(x)\ + getLU4((&(x)->DesiredPrivateIOSize),0) +#define I2O_EXEC_STATUS_GET_REPLY_setDesiredPrivateIOSize(x,y)\ + setLU4((&(x)->DesiredPrivateIOSize),0,y) +#define I2O_EXEC_STATUS_GET_REPLY_getCurrentPrivateIOSize(x)\ + getLU4((&(x)->CurrentPrivateIOSize),0) +#define I2O_EXEC_STATUS_GET_REPLY_setCurrentPrivateIOSize(x,y)\ + setLU4((&(x)->CurrentPrivateIOSize),0,y) +#define I2O_EXEC_STATUS_GET_REPLY_getCurrentPrivateIOBase(x)\ + getLU4((&(x)->CurrentPrivateIOBase),0) +#define I2O_EXEC_STATUS_GET_REPLY_setCurrentPrivateIOBase(x,y)\ + setLU4((&(x)->CurrentPrivateIOBase),0,y) +/* #define I2O_EXEC_STATUS_GET_REPLY_getreserved3(x) */ +#define I2O_EXEC_STATUS_GET_REPLY_getSyncByte(x)\ + getU1((&(x)->SyncByte),0) +#define I2O_EXEC_STATUS_GET_REPLY_setSyncByte(x,y)\ + setU1((&(x)->SyncByte),0,y) + + + +/* + * I2O_HBA_BUS_QUIESCE_MESSAGE + */ +#define I2O_HBA_BUS_QUIESCE_MESSAGE_getStdMessageFramePtr(x)\ + (&((x)->StdMessageFrame)) +#define I2O_HBA_BUS_QUIESCE_MESSAGE_getTransactionContext(x)\ + getBU4((&((x)->TransactionContext)),0) +#define I2O_HBA_BUS_QUIESCE_MESSAGE_setTransactionContext(x,y)\ + setBU4((&((x)->TransactionContext)),0,y) +#define I2O_HBA_BUS_QUIESCE_MESSAGE_getFlags(x)\ + getLU4((&(x)->Flags),0) +#define I2O_HBA_BUS_QUIESCE_MESSAGE_setFlags(x,y)\ + setLU4((&(x)->Flags),0,y) + + +#endif /* __INCi2odeph */ diff --git a/sys/dev/asr/i2odpt.h b/sys/dev/asr/i2odpt.h new file mode 100644 index 000000000000..0add374e1271 --- /dev/null +++ b/sys/dev/asr/i2odpt.h @@ -0,0 +1,195 @@ +/* $FreeBSD$ */ +/**************************************************************** + * Copyright (c) 1996-2000 Distributed Processing Technology Corporation + * Copyright (c) 2000 Adaptec Corporation. + * All rights reserved. + * + ****************************************************************/ + +#if !defined(I2O_DPT_HDR) +#define I2O_DPT_HDR + +#define DPT_ORGANIZATION_ID 0x1B /* For Private Messages */ + +/* + * PrivateMessageFrame.StdMessageFrame.Function = I2O_PRIVATE_MESSAGE + * PrivateMessageFrame.XFunctionCode = I2O_SCSI_SCB_EXEC + */ + +typedef struct _PRIVATE_SCSI_SCB_EXECUTE_MESSAGE { + I2O_PRIVATE_MESSAGE_FRAME PrivateMessageFrame; +# if (defined(sparc) || defined(_DPT_BIG_ENDIAN)) + U32 TID; /* Upper four bits currently are zero */ +# else + BF TID:16; /* Upper four bits currently are zero */ + /* Command is interpreted by the host */ + BF Interpret:1; + /* if TRUE, deal with Physical Firmware Array information */ + BF Physical:1; + BF Reserved1:14; +# endif + U8 CDBLength; + U8 Reserved; + I2O_SCB_FLAGS SCBFlags; + U8 CDB[ I2O_SCSI_CDB_LENGTH ]; + U32 ByteCount; + I2O_SG_ELEMENT SGL; +} PRIVATE_SCSI_SCB_EXECUTE_MESSAGE, * PPRIVATE_SCSI_SCB_EXECUTE_MESSAGE; + +/* + * Flash access and programming messages + * PrivateMessageFrame.StdMessageFrame.Function = I2O_PRIVATE_MESSAGE + * PrivateMessageFrame.XFunctionCode = PRIVATE_FLAGS_REGION_* + * + * SIZE returns the total size of a region of flash + * READ copies a region (or portion thereof) into the buffer specified + * by the SGL + * WRITE writes a region (or portion thereof) using the data specified + * by the SGL + * + * Flash regions + * + * 0 operational-mode firmware + * 1 software (bios/utility) + * 2 oem nvram defaults + * 3 hba serial number + * 4 boot-mode firmware + * + * Any combination of RegionOffset and ByteCount can be specified providing + * they fit within the size of the specified region. + * + * Flash messages should be targeted to the Executive TID 0x000 + */ + +#define PRIVATE_FLASH_REGION_SIZE 0x0100 +#define PRIVATE_FLASH_REGION_READ 0x0101 +#define PRIVATE_FLASH_REGION_WRITE 0x0102 +#define PRIVATE_FLASH_REGION_CRC 0x0103 + +typedef struct _PRIVATE_FLASH_REGION_MESSAGE { + I2O_PRIVATE_MESSAGE_FRAME PrivateMessageFrame; + U32 FlashRegion; + U32 RegionOffset; + U32 ByteCount; + I2O_SG_ELEMENT SGL; +} PRIVATE_FLASH_REGION_MESSAGE, * PPRIVATE_FLASH_REGION_MESSAGE; + +/* DPT Driver Printf message */ + +#define PRIVATE_DRIVER_PRINTF 0x0200 + +/* FwPrintFlags */ +#define FW_FIRMWARE_FLAGS_NO_HEADER_B 0x00000001 /* Remove date header */ + +typedef struct _PRIVATE_DRIVER_PRINTF_MESSAGE { + + I2O_PRIVATE_MESSAGE_FRAME PrivateMessageFrame; + + /* total bytes in PrintBuffer, including header */ + U32 PrintBufferByteCount; + /* exact data to be copied into the serial PrintBuffer */ + U8 PrintBuffer[1]; + +} PRIVATE_DRIVER_PRINTF_MESSAGE, * PPRIVATE_DRIVER_PRINTF_MESSAGE; + +/* DPT Enable Diagnostics message 0x0201 */ + +#define PRIVATE_DIAG_ENABLE 0x0201 + +typedef struct _PRIVATE_DIAG_ENABLE_MESSAGE { + I2O_PRIVATE_MESSAGE_FRAME PrivateMessageFrame; +} PRIVATE_DIAG_MESSAGE_FRAME, * PPRIVATE_DIAG_MESSAGE_FRAME; + +/* DPT Driver Get/Put message */ + +#define PRIVATE_DRIVER_GET 0x300 +#define PRIVATE_DRIVER_PUT 0x301 + +typedef struct _PRIVATE_DRIVER_GETPUT_MESSAGE +{ + I2O_PRIVATE_MESSAGE_FRAME PrivateMessageFrame; + U32 Offset; + U32 ByteCount; + I2O_SG_ELEMENT SGL; +} PRIVATE_DRIVER_GETPUT_MESSAGE, * PPRIVATE_DRIVER_GETPUT_MESSAGE; + +/****************************************************************************/ + +/* DPT Peripheral Device Parameter Groups */ + +/****************************************************************************/ + +/* DPT Configuration and Operating Structures and Defines */ + +#define I2O_DPT_DEVICE_INFO_GROUP_NO 0x8000 + +/* - 8000h - DPT Device Information Parameters Group defines */ + +/* Device Type */ + +#define I2O_DPT_DEVICE_TYPE_DIRECT I2O_SCSI_DEVICE_TYPE_DIRECT +#define I2O_DPT_DEVICE_TYPE_SEQUENTIAL I2O_SCSI_DEVICE_TYPE_SEQUENTIAL +#define I2O_DPT_DEVICE_TYPE_PRINTER I2O_SCSI_DEVICE_TYPE_PRINTER +#define I2O_DPT_DEVICE_TYPE_PROCESSOR I2O_SCSI_DEVICE_TYPE_PROCESSOR +#define I2O_DPT_DEVICE_TYPE_WORM I2O_SCSI_DEVICE_TYPE_WORM +#define I2O_DPT_DEVICE_TYPE_CDROM I2O_SCSI_DEVICE_TYPE_CDROM +#define I2O_DPT_DEVICE_TYPE_SCANNER I2O_SCSI_DEVICE_TYPE_SCANNER +#define I2O_DPT_DEVICE_TYPE_OPTICAL I2O_SCSI_DEVICE_TYPE_OPTICAL +#define I2O_DPT_DEVICE_TYPE_MEDIA_CHANGER I2O_SCSI_DEVICE_TYPE_MEDIA_CHANGER +#define I2O_DPT_DEVICE_TYPE_COMM I2O_SCSI_DEVICE_TYPE_COMM +#define I2O_DPT_DEVICE_GRAPHICS_1 I2O_SCSI_DEVICE_GRAPHICS_1 +#define I2O_DPT_DEVICE_GRAPHICS_2 I2O_SCSI_DEVICE_GRAPHICS_2 +#define I2O_DPT_DEVICE_TYPE_ARRAY_CONT I2O_SCSI_DEVICE_TYPE_ARRAY_CONT +#define I2O_DPT_DEVICE_TYPE_UNKNOWN I2O_SCSI_DEVICE_TYPE_UNKNOWN + +/* Flags */ + +#define I2O_DPT_PERIPHERAL_TYPE_FLAG I2O_SCSI_PERIPHERAL_TYPE_FLAG +#define I2O_DPT_PERIPHERAL_TYPE_PARALLEL I2O_SCSI_PERIPHERAL_TYPE_PARALLEL +#define I2O_DPT_PERIPHERAL_TYPE_SERIAL I2O_SCSI_PERIPHERAL_TYPE_SERIAL + +#define I2O_DPT_RESERVED_FLAG I2O_SCSI_RESERVED_FLAG + +#define I2O_DPT_DISCONNECT_FLAG I2O_SCSI_DISCONNECT_FLAG +#define I2O_DPT_DISABLE_DISCONNECT I2O_SCSI_DISABLE_DISCONNECT +#define I2O_DPT_ENABLE_DISCONNECT I2O_SCSI_ENABLE_DISCONNECT + +#define I2O_DPT_MODE_MASK I2O_SCSI_MODE_MASK +#define I2O_DPT_MODE_SET_DATA I2O_SCSI_MODE_SET_DATA +#define I2O_DPT_MODE_SET_DEFAULT I2O_SCSI_MODE_SET_DEFAULT +#define I2O_DPT_MODE_SET_SAFEST I2O_SCSI_MODE_SET_SAFEST + +#define I2O_DPT_DATA_WIDTH_MASK I2O_SCSI_DATA_WIDTH_MASK +#define I2O_DPT_DATA_WIDTH_8 I2O_SCSI_DATA_WIDTH_8 +#define I2O_DPT_DATA_WIDTH_16 I2O_SCSI_DATA_WIDTH_16 +#define I2O_DPT_DATA_WIDTH_32 I2O_SCSI_DATA_WIDTH_32 + +#define I2O_DPT_SYNC_NEGOTIATION_FLAG I2O_SCSI_SYNC_NEGOTIATION_FLAG +#define I2O_DPT_DISABLE_SYNC_NEGOTIATION I2O_SCSI_DISABLE_SYNC_NEGOTIATION +#define I2O_DPT_ENABLE_SYNC_NEGOTIATION I2O_SCSI_ENABLE_SYNC_NEGOTIATION + +/* DPT Device Group 8000h - Device Information Parameter Group */ + +typedef struct _I2O_DPT_DEVICE_INFO_SCALAR { + U8 DeviceType; /* Identical to I2O_SCSI_DEVICE_INFO SCALAR */ + U8 Flags; /* Identical to I2O_SCSI_DEVICE_INFO SCALAR */ + U16 Bus; + U32 Identifier; + U8 LunInfo[8]; /* SCSI-2 8-bit scalar LUN goes into offset 1 */ + +} I2O_DPT_DEVICE_INFO_SCALAR, *PI2O_DPT_DEVICE_INFO_SCALAR; + +#define I2O_DPT_EXEC_IOP_BUFFERS_GROUP_NO 0x8000 + +/* DPT Exec Iop Buffers Group 8000h */ + +typedef struct _I2O_DPT_EXEC_IOP_BUFFERS_SCALAR { + U32 SerialOutputOffset; /* offset from base address to header */ + U32 SerialOutputSize; /* size of data buffer in bytes */ + U32 SerialHeaderSize; /* size of data buffer header in bytes */ + U32 SerialFlagsSupported; /* Mask of debug flags supported */ + +} I2O_DPT_EXEC_IOP_BUFFERS_SCALAR, *PI2O_DPT_EXEC_IOP_BUFFERS_SCALAR; + + +#endif /* I2O_DPT_HDR */ diff --git a/sys/dev/asr/i2oexec.h b/sys/dev/asr/i2oexec.h new file mode 100644 index 000000000000..eb0413560f0a --- /dev/null +++ b/sys/dev/asr/i2oexec.h @@ -0,0 +1,1265 @@ +/* $FreeBSD$ */ +/**************************************************************** + * Copyright (c) 1996-2000 Distributed Processing Technology Corporation + * Copyright (c) 2000 Adaptec Corporation. + * All rights reserved. + * + * Copyright 1999 I2O Special Interest Group (I2O SIG). All rights reserved. + * All rights reserved + * + * TERMS AND CONDITIONS OF USE + * + * Redistribution and use in source form, with or without modification, are + * permitted provided that redistributions of source code must retain the + * above copyright notice, this list of conditions and the following disclaimer. + * + * This software is provided `as is' by Distributed Processing Technology 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 Distributed Processing Technology 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 + * interruptions) 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 driver software, even if advised + * of the possibility of such damage. + * + * This header file, and any modifications of this header file, are provided + * contingent upon your agreement and adherence to the here-listed terms and + * conditions. By accepting and/or using this header file, you agree to abide + * by these terms and conditions and that these terms and conditions will be + * construed and governed in accordance with the laws of the State of California, + * without reference to conflict-of-law provisions. If you do not agree + * to these terms and conditions, please delete this file, and any copies, + * permanently, without making any use thereof. + * + * THIS HEADER FILE IS PROVIDED FREE OF CHARGE ON AN AS-IS BASIS WITHOUT + * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. I2O SIG DOES NOT WARRANT THAT THIS HEADER FILE WILL MEET THE + * USER'S REQUIREMENTS OR THAT ITS OPERATION WILL BE UNINTERRUPTED OR + * ERROR-FREE. + * + * I2O SIG DISCLAIMS ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF + * ANY PROPRIETARY RIGHTS, RELATING TO THE IMPLEMENTATION OF THE I2O + * SPECIFICATIONS. I2O SIG DOES NOT WARRANT OR REPRESENT THAT SUCH + * IMPLEMENTATIONS WILL NOT INFRINGE SUCH RIGHTS. + * + * THE USER OF THIS HEADER FILE SHALL HAVE NO RECOURSE TO I2O SIG FOR ANY + * ACTUAL OR CONSEQUENTIAL DAMAGES INCLUDING, BUT NOT LIMITED TO, LOST DATA + * OR LOST PROFITS ARISING OUT OF THE USE OR INABILITY TO USE THIS PROGRAM. + * + * I2O SIG grants the user of this header file a license to copy, distribute, + * and modify it, for any purpose, under the following terms. Any copying, + * distribution, or modification of this header file must not delete or alter + * the copyright notice of I2O SIG or any of these Terms and Conditions. + * + * Any distribution of this header file must not include a charge for the + * header file (unless such charges are strictly for the physical acts of + * copying or transferring copies). However, distribution of a product in + * which this header file is embedded may include a charge so long as any + * such charge does not include any charge for the header file itself. + * + * Any modification of this header file constitutes a derivative work based + * on this header file. Any distribution of such derivative work: (1) must + * include prominent notices that the header file has been changed from the + * original, together with the dates of any changes; (2) automatically includes + * this same license to the original header file from I2O SIG, without any + * restriction thereon from the distributing user; and (3) must include a + * grant of license of the modified file under the same terms and conditions + * as these Terms and Conditions. + * + * The I2O SIG Web site can be found at: http://www.i2osig.org + * + * The I2O SIG encourages you to deposit derivative works based on this + * header file at the I2O SIG Web site. Furthermore, to become a Registered + * Developer of the I2O SIG, sign up at the Web site or call 415.750.8352 + * (United States). + ****************************************************************/ + +/********************************************************************* + * I2OExec.h -- I2O Executive Class Message definition file + * + * This file contains information presented in Chapter 4 of the I2O(tm) + * Specification. + **********************************************************************/ + +#if !defined(I2O_EXECUTIVE_HDR) +#define I2O_EXECUTIVE_HDR + +#define I2OEXEC_REV 1_5_4 /* I2OExec header file revision string */ + +#if ((defined(KERNEL) || defined(_KERNEL)) && defined(__FreeBSD__)) +# if (!defined(KERN_VERSION)) +# include <sys/sysctl.h> +# endif +# if (KERN_VERSION < 3) +# include "i386/pci/i2omsg.h" /* Include the Base Message file */ +# include "i386/pci/i2outil.h" +# else +# include "dev/asr/i2omsg.h" /* Include the Base Message file */ +# include "dev/asr/i2outil.h" +# endif +#else +# include "i2omsg.h" /* Include the Base Message file */ +# include "i2outil.h" +#endif + + +/* + NOTES: + + Gets, reads, receives, etc. are all even numbered functions. + Sets, writes, sends, etc. are all odd numbered functions. + Functions that both send and receive data can be either but an attempt is made + to use the function number that indicates the greater transfer amount. + Functions that do not send or receive data use odd function numbers. + + Some functions are synonyms like read, receive and send, write. + + All common functions will have a code of less than 0x80. + Unique functions to a class will start at 0x80. + Executive Functions start at 0xA0. + + Utility Message function codes range from 0 - 0x1f + Base Message function codes range from 0x20 - 0xfe + Private Message function code is 0xff. +*/ + +PRAGMA_ALIGN_PUSH +PRAGMA_PACK_PUSH + +/* I2O Executive Function Codes. */ + +#define I2O_EXEC_ADAPTER_ASSIGN 0xB3 +#define I2O_EXEC_ADAPTER_READ 0xB2 +#define I2O_EXEC_ADAPTER_RELEASE 0xB5 +#define I2O_EXEC_BIOS_INFO_SET 0xA5 +#define I2O_EXEC_BOOT_DEVICE_SET 0xA7 +#define I2O_EXEC_CONFIG_VALIDATE 0xBB +#define I2O_EXEC_CONN_SETUP 0xCA +#define I2O_EXEC_DDM_DESTROY 0xB1 +#define I2O_EXEC_DDM_ENABLE 0xD5 +#define I2O_EXEC_DDM_QUIESCE 0xC7 +#define I2O_EXEC_DDM_RESET 0xD9 +#define I2O_EXEC_DDM_SUSPEND 0xAF +#define I2O_EXEC_DEVICE_ASSIGN 0xB7 +#define I2O_EXEC_DEVICE_RELEASE 0xB9 +#define I2O_EXEC_HRT_GET 0xA8 +#define I2O_EXEC_IOP_CLEAR 0xBE +#define I2O_EXEC_IOP_CONNECT 0xC9 +#define I2O_EXEC_IOP_RESET 0xBD +#define I2O_EXEC_LCT_NOTIFY 0xA2 +#define I2O_EXEC_OUTBOUND_INIT 0xA1 +#define I2O_EXEC_PATH_ENABLE 0xD3 +#define I2O_EXEC_PATH_QUIESCE 0xC5 +#define I2O_EXEC_PATH_RESET 0xD7 +#define I2O_EXEC_STATIC_MF_CREATE 0xDD +#define I2O_EXEC_STATIC_MF_RELEASE 0xDF +#define I2O_EXEC_STATUS_GET 0xA0 +#define I2O_EXEC_SW_DOWNLOAD 0xA9 +#define I2O_EXEC_SW_UPLOAD 0xAB +#define I2O_EXEC_SW_REMOVE 0xAD +#define I2O_EXEC_SYS_ENABLE 0xD1 +#define I2O_EXEC_SYS_MODIFY 0xC1 +#define I2O_EXEC_SYS_QUIESCE 0xC3 +#define I2O_EXEC_SYS_TAB_SET 0xA3 + + +/* I2O Get Status State values */ + +#define I2O_IOP_STATE_INITIALIZING 0x01 +#define I2O_IOP_STATE_RESET 0x02 +#define I2O_IOP_STATE_HOLD 0x04 +#define I2O_IOP_STATE_READY 0x05 +#define I2O_IOP_STATE_OPERATIONAL 0x08 +#define I2O_IOP_STATE_FAILED 0x10 +#define I2O_IOP_STATE_FAULTED 0x11 + + +/* Event Indicator Assignments for the Executive Class. */ + +#define I2O_EVENT_IND_RESOURCE_LIMIT 0x00000001 +#define I2O_EVENT_IND_CONNECTION_FAIL 0x00000002 +#define I2O_EVENT_IND_ADAPTER_FAULT 0x00000004 +#define I2O_EVENT_IND_POWER_FAIL 0x00000008 +#define I2O_EVENT_IND_RESET_PENDING 0x00000010 +#define I2O_EVENT_IND_RESET_IMMINENT 0x00000020 +#define I2O_EVENT_IND_HARDWARE_FAIL 0x00000040 +#define I2O_EVENT_IND_XCT_CHANGE 0x00000080 +#define I2O_EVENT_IND_NEW_LCT_ENTRY 0x00000100 +#define I2O_EVENT_IND_MODIFIED_LCT 0x00000200 +#define I2O_EVENT_IND_DDM_AVAILABILITY 0x00000400 + +/* Resource Limit Event Data */ + +#define I2O_EVENT_RESOURCE_LIMIT_LOW_MEMORY 0x00000001 +#define I2O_EVENT_RESOURCE_LIMIT_INBOUND_POOL_LOW 0x00000002 +#define I2O_EVENT_RESOURCE_LIMIT_OUTBOUND_POOL_LOW 0x00000004 + +/* Connection Fail Event Data */ + +#define I2O_EVENT_CONNECTION_FAIL_REPOND_NORMAL 0x00000000 +#define I2O_EVENT_CONNECTION_FAIL_NOT_REPONDING 0x00000001 +#define I2O_EVENT_CONNECTION_FAIL_NO_AVAILABLE_FRAMES 0x00000002 + +/* Reset Pending Event Data */ + +#define I2O_EVENT_RESET_PENDING_POWER_LOSS 0x00000001 +#define I2O_EVENT_RESET_PENDING_CODE_VIOLATION 0x00000002 + +/* Reset Imminent Event Data */ + +#define I2O_EVENT_RESET_IMMINENT_UNKNOWN_CAUSE 0x00000000 +#define I2O_EVENT_RESET_IMMINENT_POWER_LOSS 0x00000001 +#define I2O_EVENT_RESET_IMMINENT_CODE_VIOLATION 0x00000002 +#define I2O_EVENT_RESET_IMMINENT_PARITY_ERROR 0x00000003 +#define I2O_EVENT_RESET_IMMINENT_CODE_EXCEPTION 0x00000004 +#define I2O_EVENT_RESET_IMMINENT_WATCHDOG_TIMEOUT 0x00000005 + +/* Hardware Fail Event Data */ + +#define I2O_EVENT_HARDWARE_FAIL_UNKNOWN_CAUSE 0x00000000 +#define I2O_EVENT_HARDWARE_FAIL_CPU_FAILURE 0x00000001 +#define I2O_EVENT_HARDWARE_FAIL_MEMORY_FAULT 0x00000002 +#define I2O_EVENT_HARDWARE_FAIL_DMA_FAILURE 0x00000003 +#define I2O_EVENT_HARDWARE_FAIL_IO_BUS_FAILURE 0x00000004 + +/* DDM Availability Event Data */ + +#define I2O_EVENT_DDM_AVAILIBILITY_RESPOND_NORMAL 0x00000000 +#define I2O_EVENT_DDM_AVAILIBILITY_CONGESTED 0x00000001 +#define I2O_EVENT_DDM_AVAILIBILITY_NOT_RESPONDING 0x00000002 +#define I2O_EVENT_DDM_AVAILIBILITY_PROTECTION_VIOLATION 0x00000003 +#define I2O_EVENT_DDM_AVAILIBILITY_CODE_VIOLATION 0x00000004 + +/****************************************************************************/ + +#define I2O_OPERATION_FLAG_ASSIGN_PERMANENT 0x01 + +/* ExecAdapterAssign Function Message Frame structure. */ + +typedef struct _I2O_EXEC_ADAPTER_ASSIGN_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +#if (defined(__BORLANDC__)) + U32 DdmTID; +#else + BF DdmTID:I2O_TID_SZ; + BF reserved:I2O_RESERVED_12BITS; + BF OperationFlags:I2O_8BIT_FLAGS_SZ; +#endif + I2O_HRT_ENTRY HRTEntry; +} I2O_EXEC_ADAPTER_ASSIGN_MESSAGE, *PI2O_EXEC_ADAPTER_ASSIGN_MESSAGE; + + +/****************************************************************************/ + +#define I2O_REQUEST_FLAG_CONFIG_REGISTER 0x00000000 +#define I2O_REQUEST_FLAG_IO_REGISTER 0x00000001 +#define I2O_REQUEST_FLAG_ADAPTER_MEMORY 0x00000002 + +/* ExecAdapterRead Function Message Frame structure. */ + +typedef struct _I2O_EXEC_ADAPTER_READ_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U32 AdapterID; + U32 RequestFlags; + U32 Offset; + U32 Length; + I2O_SG_ELEMENT SGL; +} I2O_EXEC_ADAPTER_READ_MESSAGE, *PI2O_EXEC_ADAPTER_READ_MESSAGE; + + +/****************************************************************************/ + +#define I2O_OPERATION_FLAG_RELEASE_PERMANENT 0x01 + +/* ExecAdapterRelease Function Message Frame structure. */ + +typedef struct _I2O_EXEC_ADAPTER_RELEASE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U8 reserved[3]; + U8 OperationFlags; + I2O_HRT_ENTRY HRTEntry; +} I2O_EXEC_ADAPTER_RELEASE_MESSAGE, *PI2O_EXEC_ADAPTER_RELEASE_MESSAGE; + + +/****************************************************************************/ + +/* ExecBiosInfoSet Function Message Frame structure. */ + +typedef struct _I2O_EXEC_BIOS_INFO_SET_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +#if (defined(__BORLANDC__)) + U32 DeviceTID; +#else + BF DeviceTID:I2O_TID_SZ; + BF reserved:I2O_RESERVED_12BITS; + BF BiosInfo:I2O_BIOS_INFO_SZ; +#endif +} I2O_EXEC_BIOS_INFO_SET_MESSAGE, *PI2O_EXEC_BIOS_INFO_SET_MESSAGE; + + +/****************************************************************************/ + +/* ExecBootDeviceSet Function Message Frame structure. */ + +typedef struct _I2O_EXEC_BOOT_DEVICE_SET_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + BF BootDevice:I2O_TID_SZ; + BF reserved:I2O_RESERVED_4BITS; + BF reserved1:I2O_RESERVED_16BITS; +} I2O_EXEC_BOOT_DEVICE_SET_MESSAGE, *PI2O_EXEC_BOOT_DEVICE_SET_MESSAGE; + + +/****************************************************************************/ + +/* ExecConfigValidate Function Message Frame structure. */ + +typedef struct _I2O_EXEC_CONFIG_VALIDATE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +} I2O_EXEC_CONFIG_VALIDATE_MESSAGE, *PI2O_EXEC_CONFIG_VALIDATE_MESSAGE; + + +/****************************************************************************/ + +/* ExecConnSetup Requestor */ + +typedef struct _I2O_ALIAS_CONNECT_SETUP { +#if (defined(__BORLANDC__)) + U32 IOP1AliasForTargetDevice; +#else + BF IOP1AliasForTargetDevice:I2O_TID_SZ; + BF IOP2AliasForInitiatorDevice:I2O_TID_SZ; + BF reserved:I2O_RESERVED_8BITS; +#endif +} I2O_ALIAS_CONNECT_SETUP, *PI2O_ALIAS_CONNECT_SETUP; + +#define I2O_OPERATION_FLAG_PEER_TO_PEER_BIDIRECTIONAL 0x01 + +/* ExecConnSetup Object */ + +typedef struct _I2O_OBJECT_CONNECT_SETUP { +#if (defined(__BORLANDC__)) + U32 TargetDevice; +#else + BF TargetDevice:I2O_TID_SZ; + BF InitiatorDevice:I2O_TID_SZ; + BF OperationFlags:I2O_8BIT_FLAGS_SZ; +#endif +} I2O_OBJECT_CONNECT_SETUP, *PI2O_OBJECT_CONNECT_SETUP; + + +/* ExecConnSetup Function Message Frame structure. */ + +typedef struct _I2O_EXEC_CONN_SETUP_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + I2O_OBJECT_CONNECT_SETUP ObjectInfo; + I2O_ALIAS_CONNECT_SETUP AliasInfo; + U16 IOP2InboundMFrameSize; + U16 reserved; + U32 MessageClass; +} I2O_EXEC_CONN_SETUP_MESSAGE, *PI2O_EXEC_CONN_SETUP_MESSAGE; + + +/* ExecConnSetup Object Reply */ + +typedef struct _I2O_OBJECT_CONNECT_REPLY { +#if (defined(__BORLANDC__)) + U32 TargetDevice; +#else + BF TargetDevice:I2O_TID_SZ; + BF InitiatorDevice:I2O_TID_SZ; + BF ReplyStatusCode:I2O_8BIT_FLAGS_SZ; +#endif +} I2O_OBJECT_CONNECT_REPLY, *PI2O_OBJECT_CONNECT_REPLY; + + +/* ExecConnSetup reply structure. */ + +typedef struct _I2O_EXEC_CONN_SETUP_REPLY { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + I2O_OBJECT_CONNECT_REPLY ObjectInfo; + I2O_ALIAS_CONNECT_SETUP AliasInfo; + U16 IOP2InboundMFrameSize; + U16 reserved; +} I2O_EXEC_CONN_SETUP_REPLY, *PI2O_EXEC_CONN_SETUP_REPLY; + + +/****************************************************************************/ + +/* ExecDdmDestroy Function Message Frame structure. */ + +typedef struct _I2O_EXEC_DDM_DESTROY_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + BF DdmTID:I2O_TID_SZ; + BF reserved:I2O_RESERVED_4BITS; + BF reserved1:I2O_RESERVED_16BITS; +} I2O_EXEC_DDM_DESTROY_MESSAGE, *PI2O_EXEC_DDM_DESTROY_MESSAGE; + + +/****************************************************************************/ + +/* ExecDdmEnable Function Message Frame structure. */ + +typedef struct _I2O_EXEC_DDM_ENABLE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + BF DeviceTID:I2O_TID_SZ; + BF reserved2:I2O_RESERVED_4BITS; + BF reserved1:I2O_RESERVED_16BITS; + BF IOP_ID:I2O_IOP_ID_SZ; + BF reserved:I2O_RESERVED_4BITS; + BF HostUnitID:I2O_UNIT_ID_SZ; +} I2O_EXEC_DDM_ENABLE_MESSAGE, *PI2O_EXEC_DDM_ENABLE_MESSAGE; + + +/****************************************************************************/ + +/* ExecDdmQuiesce Function Message Frame structure. */ + +typedef struct _I2O_EXEC_DDM_QUIESCE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + BF DeviceTID:I2O_TID_SZ; + BF reserved2:I2O_RESERVED_4BITS; + BF reserved1:I2O_RESERVED_16BITS; + BF IOP_ID:I2O_IOP_ID_SZ; + BF reserved:I2O_RESERVED_4BITS; + BF HostUnitID:I2O_UNIT_ID_SZ; +} I2O_EXEC_DDM_QUIESCE_MESSAGE, *PI2O_EXEC_DDM_QUIESCE_MESSAGE; + + +/****************************************************************************/ + +/* ExecDdmReset Function Message Frame structure. */ + +typedef struct _I2O_EXEC_DDM_RESET_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + BF DeviceTID:I2O_TID_SZ; + BF reserved2:I2O_RESERVED_4BITS; + BF reserved1:I2O_RESERVED_16BITS; + BF IOP_ID:I2O_IOP_ID_SZ; + BF reserved:I2O_RESERVED_4BITS; + BF HostUnitID:I2O_UNIT_ID_SZ; +} I2O_EXEC_DDM_RESET_MESSAGE, *PI2O_EXEC_DDM_RESET_MESSAGE; + + +/****************************************************************************/ + +/* ExecDdmSuspend Function Message Frame structure. */ + +typedef struct _I2O_EXEC_DDM_SUSPEND_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + BF DdmTID:I2O_TID_SZ; + BF reserved:I2O_RESERVED_4BITS; + BF reserved1:I2O_RESERVED_16BITS; +} I2O_EXEC_DDM_SUSPEND_MESSAGE, *PI2O_EXEC_DDM_SUSPEND_MESSAGE; + + +/****************************************************************************/ + +#define I2O_OPERATION_FLAG_ASSIGN_PERMANENT 0x01 + +/* ExecDeviceAssign Function Message Frame structure. */ + +typedef struct _I2O_EXEC_DEVICE_ASSIGN_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +#if (defined(__BORLANDC__)) + U32 DeviceTID; +#else + BF DeviceTID:I2O_TID_SZ; + BF DdmTID:I2O_TID_SZ; + BF OperationFlags:I2O_8BIT_FLAGS_SZ; +#endif + BF IOP_ID:I2O_IOP_ID_SZ; + BF reserved:I2O_RESERVED_4BITS; + BF HostUnitID:I2O_UNIT_ID_SZ; +} I2O_EXEC_DEVICE_ASSIGN_MESSAGE, *PI2O_EXEC_DEVICE_ASSIGN_MESSAGE; + + +/****************************************************************************/ + +#define I2O_OPERATION_FLAG_RELEASE_PERMANENT 0x01 + +/* ExecDeviceRelease Function Message Frame structure. */ + +typedef struct _I2O_EXEC_DEVICE_RELEASE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +#if (defined(__BORLANDC__)) + U32 DeviceTID; +#else + BF DeviceTID:I2O_TID_SZ; + BF DdmTID:I2O_TID_SZ; + BF OperationFlags:I2O_8BIT_FLAGS_SZ; +#endif + BF IOP_ID:I2O_IOP_ID_SZ; + BF reserved:I2O_RESERVED_4BITS; + BF HostUnitID:I2O_UNIT_ID_SZ; +} I2O_EXEC_DEVICE_RELEASE_MESSAGE, *PI2O_EXEC_DEVICE_RELEASE_MESSAGE; + + +/****************************************************************************/ + +/* HRT Entry Structure defined in I2OMSG.H */ + +/* ExecHrtGet Function Message Frame structure. */ + +typedef struct _I2O_EXEC_HRT_GET_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + I2O_SG_ELEMENT SGL; +} I2O_EXEC_HRT_GET_MESSAGE, *PI2O_EXEC_HRT_GET_MESSAGE; + + +/****************************************************************************/ + + +/* ExecIopClear Function Message Frame structure. */ + +typedef struct _I2O_EXEC_IOP_CLEAR_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +} I2O_EXEC_IOP_CLEAR_MESSAGE, *PI2O_EXEC_IOP_CLEAR_MESSAGE; + + +/****************************************************************************/ + + +/* ExecIopConnect Function Message Frame structure. */ + +typedef struct _I2O_EXEC_IOP_CONNECT_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + BF reserved:I2O_RESERVED_16BITS; + BF reserved3:I2O_RESERVED_8BITS; + BF IOP1MsgerType:I2O_MESSENGER_TYPE_SZ; + U16 IOP1InboundMFrameSize; + BF IOP1AliasForIOP2:I2O_TID_SZ; + U8 reserved1; + BF IOP_ID1:I2O_IOP_ID_SZ; + BF reserved2:I2O_RESERVED_4BITS; + BF HostUnitID1:I2O_UNIT_ID_SZ; +} I2O_EXEC_IOP_CONNECT_MESSAGE, *PI2O_EXEC_IOP_CONNECT_MESSAGE; + + + /* ExecIopConnect reply structure */ + +typedef struct _I2O_EXEC_IOP_CONNECT_IOP_REPLY { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U16 DetailedStatusCode; + U8 reserved; + U8 ReqStatus; + U16 IOP2InboundMFrameSize; + BF IOP2AliasForIOP1:I2O_TID_SZ; + U8 reserved1; + BF IOP_ID2:I2O_IOP_ID_SZ; + BF reserved2:I2O_RESERVED_4BITS; + BF HostUnitID2:I2O_UNIT_ID_SZ; +} I2O_EXEC_IOP_CONNECT_REPLY, *PI2O_EXEC_IOP_CONNECT_REPLY; + + +/****************************************************************************/ + + +#define I2O_EXEC_IOP_RESET_RESERVED_SZ 16 + +#define I2O_EXEC_IOP_RESET_IN_PROGRESS 0x01 +#define I2O_EXEC_IOP_RESET_REJECTED 0x02 + +#define I2O_EXEC_IOP_RESET_STATUS_RESERVED_SZ 3 + +typedef struct _I2O_EXEC_IOP_RESET_STATUS { +# if (defined(_DPT_BIG_ENDIAN) || defined(sparc)) + U32 ResetStatus; +# else + U8 ResetStatus; + U8 reserved[I2O_EXEC_IOP_RESET_STATUS_RESERVED_SZ]; +# endif +} I2O_EXEC_IOP_RESET_STATUS, *PI2O_EXEC_IOP_RESET_STATUS; + + +/* ExecIopReset Function Message Frame structure. */ + +typedef struct _I2O_EXEC_IOP_RESET_MESSAGE { + U8 VersionOffset; + U8 MsgFlags; + U16 MessageSize; +#if (defined(__BORLANDC__) || defined(sparc)) + U32 TargetAddress; +#else + BF TargetAddress:I2O_TID_SZ; + BF InitiatorAddress:I2O_TID_SZ; + BF Function:I2O_FUNCTION_SZ; +#endif + U8 Reserved[I2O_EXEC_IOP_RESET_RESERVED_SZ]; + U32 StatusWordLowAddress; + U32 StatusWordHighAddress; +} I2O_EXEC_IOP_RESET_MESSAGE, *PI2O_EXEC_IOP_RESET_MESSAGE; + + +/****************************************************************************/ + +/* LCT Entry Structure defined in I2OMSG.H */ + +/* ExecLCTNotify Function Message Frame structure. */ + +typedef struct _I2O_EXEC_LCT_NOTIFY_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U32 ClassIdentifier; + U32 LastReportedChangeIndicator; + I2O_SG_ELEMENT SGL; +} I2O_EXEC_LCT_NOTIFY_MESSAGE, *PI2O_EXEC_LCT_NOTIFY_MESSAGE; + + +/****************************************************************************/ + + +/* ExecOutboundInit Function Message Frame structure. */ + +typedef struct _I2O_EXEC_OUTBOUND_INIT_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U32 HostPageFrameSize; + U8 InitCode; + U8 reserved; + U16 OutboundMFrameSize; + I2O_SG_ELEMENT SGL; +} I2O_EXEC_OUTBOUND_INIT_MESSAGE, *PI2O_EXEC_OUTBOUND_INIT_MESSAGE; + + +#define I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS 0x01 +#define I2O_EXEC_OUTBOUND_INIT_REJECTED 0x02 +#define I2O_EXEC_OUTBOUND_INIT_FAILED 0x03 +#define I2O_EXEC_OUTBOUND_INIT_COMPLETE 0x04 + +#define I2O_EXEC_OUTBOUND_INIT_RESERVED_SZ 3 + + +typedef struct _I2O_EXEC_OUTBOUND_INIT_STATUS { + U8 InitStatus; + U8 reserved[I2O_EXEC_OUTBOUND_INIT_RESERVED_SZ]; +} I2O_EXEC_OUTBOUND_INIT_STATUS, *PI2O_EXEC_OUTBOUND_INIT_STATUS; + + +typedef struct _I2O_EXEC_OUTBOUND_INIT_RECLAIM_LIST { + U32 MFACount; + U32 MFAReleaseCount; + U32 MFAAddress[1]; +} I2O_EXEC_OUTBOUND_INIT_RECLAIM_LIST, *PI2O_EXEC_OUTBOUND_INIT_RECLAIM_LIST; + + +/****************************************************************************/ + +/* ExecPathEnable Function Message Frame structure. */ + +typedef struct _I2O_EXEC_PATH_ENABLE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + BF IOP_ID:I2O_IOP_ID_SZ; + BF reserved:I2O_RESERVED_4BITS; + BF HostUnitID:I2O_UNIT_ID_SZ; +} I2O_EXEC_PATH_ENABLE_MESSAGE, *PI2O_EXEC_PATH_ENABLE_MESSAGE; + + +/****************************************************************************/ + +/* ExecPathQuiesce Function Message Frame structure. */ + +typedef struct _I2O_EXEC_PATH_QUIESCE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + BF IOP_ID:I2O_IOP_ID_SZ; + BF reserved:I2O_RESERVED_4BITS; + BF HostUnitID:I2O_UNIT_ID_SZ; +} I2O_EXEC_PATH_QUIESCE_MESSAGE, *PI2O_EXEC_PATH_QUIESCE_MESSAGE; + + +/****************************************************************************/ + +/* ExecPathReset Function Message Frame structure. */ + +typedef struct _I2O_EXEC_PATH_RESET_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + BF IOP_ID:I2O_IOP_ID_SZ; + BF reserved:I2O_RESERVED_4BITS; + BF HostUnitID:I2O_UNIT_ID_SZ; +} I2O_EXEC_PATH_RESET_MESSAGE, *PI2O_EXEC_PATH_RESET_MESSAGE; + + +/****************************************************************************/ + +#define I2O_EXEC_STATIC_MF_CREATE_RESERVED_SZ 3 + +/* ExecStaticMfCreate Message Frame structure */ + +typedef struct _I2O_EXEC_STATIC_MF_CREATE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U8 MaxOutstanding; + U8 reserved[I2O_EXEC_STATIC_MF_CREATE_RESERVED_SZ]; + I2O_MESSAGE_FRAME StaticMessageFrame; +} I2O_EXEC_STATIC_MF_CREATE_MESSAGE, *PI2O_EXEC_STATIC_MF_CREATE_MESSAGE; + + +/* ExecStaticMfCreate Message Frame reply */ + +typedef struct _I2O_EXEC_STATIC_MF_CREATE_REPLY { + I2O_SINGLE_REPLY_MESSAGE_FRAME StdReplyFrame; + PI2O_MESSAGE_FRAME StaticMFA; +} I2O_EXEC_STATIC_MF_CREATE_REPLY, *PI2O_EXEC_STATIC_MF_CREATE_REPLY; + + +/* ExecStaticMfRelease Message Frame structure */ + +typedef struct _I2O_EXEC_STATIC_MF_RELEASE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + PI2O_MESSAGE_FRAME StaticMFA; +} I2O_EXEC_STATIC_MF_RELEASE_MESSAGE, *PI2O_EXEC_STATIC_MF_RELEASE_MESSAGE; + + +/****************************************************************************/ + +#define I2O_EXEC_STATUS_GET_RESERVED_SZ 16 + +/* ExecStatusGet Function Message Frame structure. */ + +typedef struct _I2O_EXEC_STATUS_GET_MESSAGE { + U8 VersionOffset; + U8 MsgFlags; + U16 MessageSize; +#if (defined(__BORLANDC__) || defined(_DPT_BIG_ENDIAN) || defined(sparc)) + U32 TargetAddress; +#else + BF TargetAddress:I2O_TID_SZ; + BF InitiatorAddress:I2O_TID_SZ; + BF Function:I2O_FUNCTION_SZ; +#endif + U8 Reserved[I2O_EXEC_STATUS_GET_RESERVED_SZ]; + U32 ReplyBufferAddressLow; + U32 ReplyBufferAddressHigh; + U32 ReplyBufferLength; +} I2O_EXEC_STATUS_GET_MESSAGE, *PI2O_EXEC_STATUS_GET_MESSAGE; + + +#define I2O_IOP_STATUS_PROD_ID_STR_SZ 24 +#define I2O_EXEC_STATUS_GET_REPLY_RESERVED_SZ 6 + +/* ExecStatusGet reply Structure */ + +#define I2O_IOP_CAP_CONTEXT_32_ONLY 0x00000000 +#define I2O_IOP_CAP_CONTEXT_64_ONLY 0x00000001 +#define I2O_IOP_CAP_CONTEXT_32_64_NOT_CURRENTLY 0x00000002 +#define I2O_IOP_CAP_CONTEXT_32_64_CURRENTLY 0x00000003 +#define I2O_IOP_CAP_CURRENT_CONTEXT_NOT_CONFIG 0x00000000 +#define I2O_IOP_CAP_CURRENT_CONTEXT_32_ONLY 0x00000004 +#define I2O_IOP_CAP_CURRENT_CONTEXT_64_ONLY 0x00000008 +#define I2O_IOP_CAP_CURRENT_CONTEXT_32_64 0x0000000C +#define I2O_IOP_CAP_INBOUND_PEER_SUPPORT 0x00000010 +#define I2O_IOP_CAP_OUTBOUND_PEER_SUPPORT 0x00000020 +#define I2O_IOP_CAP_PEER_TO_PEER_SUPPORT 0x00000040 + +typedef struct _I2O_EXEC_STATUS_GET_REPLY { + U16 OrganizationID; + U16 reserved; +#if (defined(_DPT_BIG_ENDIAN) || defined(sparc)) + U32 IOP_ID; +#else + BF IOP_ID:I2O_IOP_ID_SZ; + BF reserved1:I2O_RESERVED_4BITS; + BF HostUnitID:I2O_UNIT_ID_SZ; +#endif +#if (defined(_DPT_BIG_ENDIAN) || defined(sparc)) + U32 SegmentNumber; +#else + BF SegmentNumber:I2O_SEGMENT_NUMBER_SZ; + BF I2oVersion:I2O_4BIT_VERSION_SZ; + BF IopState:I2O_IOP_STATE_SZ; + BF MessengerType:I2O_MESSENGER_TYPE_SZ; +#endif + U16 InboundMFrameSize; + U8 InitCode; + U8 reserved2; + U32 MaxInboundMFrames; + U32 CurrentInboundMFrames; + U32 MaxOutboundMFrames; + U8 ProductIDString[I2O_IOP_STATUS_PROD_ID_STR_SZ]; + U32 ExpectedLCTSize; + U32 IopCapabilities; + U32 DesiredPrivateMemSize; + U32 CurrentPrivateMemSize; + U32 CurrentPrivateMemBase; + U32 DesiredPrivateIOSize; + U32 CurrentPrivateIOSize; + U32 CurrentPrivateIOBase; + U8 reserved3[3]; + U8 SyncByte; +} I2O_EXEC_STATUS_GET_REPLY, *PI2O_EXEC_STATUS_GET_REPLY; + + +/****************************************************************************/ + +#define I2O_EXEC_SW_DOWNLOAD_FLAG_LOAD_MEMORY 0x00 +#define I2O_EXEC_SW_DOWNLOAD_FLAG_PERMANENT_STORE 0x01 +#define I2O_EXEC_SW_DOWNLOAD_FLAG_EXPERIMENTAL 0x00 +#define I2O_EXEC_SW_DOWNLOAD_FLAG_OVERRIDE 0x02 + +#define I2O_EXEC_SW_TYPE_DDM 0x01 +#define I2O_EXEC_SW_TYPE_DDM_MPB 0x02 +#define I2O_EXEC_SW_TYPE_DDM_CONFIG_TABLE 0x03 +#define I2O_EXEC_SW_TYPE_IRTOS 0x11 +#define I2O_EXEC_SW_TYPE_IRTOS_PRIVATE_MODULE 0x12 +#define I2O_EXEC_SW_TYPE_IRTOS_DIALOG_TABLE 0x13 +#define I2O_EXEC_SW_TYPE_IOP_PRIVATE_MODULE 0x22 +#define I2O_EXEC_SW_TYPE_IOP_DIALOG_TABLE 0x23 + + +/* I2O ExecSwDownload/Upload/Remove SwID Structure */ + +typedef struct _I2O_SW_ID { + U16 ModuleID; + U16 OrganizationID; +} I2O_SW_ID, *PI2O_SW_ID; + + +/* ExecSwDownload Function Message Frame structure. */ + +typedef struct _I2O_EXEC_SW_DOWNLOAD_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U8 CurrentFragment; + U8 TotalFragments; + U8 SwType; + U8 DownloadFlags; + U32 SWSize; + I2O_SW_ID SwID; + I2O_SG_ELEMENT SGL; +} I2O_EXEC_SW_DOWNLOAD_MESSAGE, *PI2O_EXEC_SW_DOWNLOAD_MESSAGE; + + +/****************************************************************************/ + + +/* ExecSwUpload Function Message Frame structure. */ + +typedef struct _I2O_EXEC_SW_UPLOAD_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U8 CurrentFragment; + U8 TotalFragments; + U8 SwType; + U8 UploadFlags; + U32 SWSize; + I2O_SW_ID SwID; + I2O_SG_ELEMENT SGL; +} I2O_EXEC_SW_UPLOAD_MESSAGE, *PI2O_EXEC_SW_UPLOAD_MESSAGE; + + +/****************************************************************************/ + + +/* ExecSwRemove Function Message Frame structure. */ + +typedef struct _I2O_EXEC_SW_REMOVE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U16 reserved; + U8 SwType; + U8 RemoveFlags; + U32 SWSize; + I2O_SW_ID SwID; +} I2O_EXEC_SW_REMOVE_MESSAGE, *PI2O_EXEC_SW_REMOVE_MESSAGE; + + +/****************************************************************************/ + + +/* ExecSysEnable Function Message Frame structure. */ + +typedef struct _I2O_EXEC_SYS_ENABLE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +} I2O_EXEC_SYS_ENABLE_MESSAGE, *PI2O_EXEC_SYS_ENABLE_MESSAGE; + + +/****************************************************************************/ + + +/* ExecSysModify Function Message Frame structure. */ + +typedef struct _I2O_EXEC_SYS_MODIFY_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + I2O_SG_ELEMENT SGL; +} I2O_EXEC_SYS_MODIFY_MESSAGE, *PI2O_EXEC_SYS_MODIFY_MESSAGE; + + +/****************************************************************************/ + + +/* ExecSysQuiesce Function Message Frame structure. */ + +typedef struct _I2O_EXEC_SYS_QUIESCE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +} I2O_EXEC_SYS_QUIESCE_MESSAGE, *PI2O_EXEC_SYS_QUIESCE_MESSAGE; + + +/****************************************************************************/ + + +/* ExecSysTabSet (System Table) Function Message Frame structure. */ + +#define I2O_EXEC_SYS_TAB_IOP_ID_LOCAL_IOP 0x000 +#define I2O_EXEC_SYS_TAB_IOP_ID_LOCAL_HOST 0x001 +#define I2O_EXEC_SYS_TAB_IOP_ID_UNKNOWN_IOP 0xFFF +#define I2O_EXEC_SYS_TAB_HOST_UNIT_ID_LOCAL_UNIT 0x0000 +#define I2O_EXEC_SYS_TAB_HOST_UNIT_ID_UNKNOWN_UNIT 0xffff +#define I2O_EXEC_SYS_TAB_SEG_NUMBER_LOCAL_SEGMENT 0x000 +#define I2O_EXEC_SYS_TAB_SEG_NUMBER_UNKNOWN_SEGMENT 0xfff + +typedef struct _I2O_EXEC_SYS_TAB_SET_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +#if (defined(_DPT_BIG_ENDIAN) || defined(sparc)) + U32 IOP_ID; +#else + BF IOP_ID:I2O_IOP_ID_SZ; + BF reserved:I2O_RESERVED_4BITS; + BF HostUnitID:I2O_UNIT_ID_SZ; +#endif +#if (defined(_DPT_BIG_ENDIAN) || defined(sparc)) + U32 SegmentNumber; +#else + BF SegmentNumber:I2O_SEGMENT_NUMBER_SZ; + BF reserved2:I2O_RESERVED_4BITS; + BF reserved3:I2O_RESERVED_16BITS; +#endif + I2O_SG_ELEMENT SGL; +} I2O_EXEC_SYS_TAB_SET_MESSAGE, *PI2O_EXEC_SYS_TAB_SET_MESSAGE; + + +/* ExecSysTabSet (System Table) Header Reply structure. */ + +#define I2O_SET_SYSTAB_RESERVED_SZ 8 + +typedef struct _I2O_SET_SYSTAB_HEADER { + U8 NumberEntries; + U8 SysTabVersion; + U16 reserved; + U32 CurrentChangeIndicator; + U8 reserved1[I2O_SET_SYSTAB_RESERVED_SZ]; +/* I2O_SYSTAB_ENTRY SysTabEntry[1]; */ +} I2O_SET_SYSTAB_HEADER, *PI2O_SET_SYSTAB_HEADER; + + +#define I2O_RESOURCE_MANAGER_VERSION 0 + +typedef struct _MESSENGER_INFO { + U32 InboundMessagePortAddressLow; + U32 InboundMessagePortAddressHigh; + } I2O_MESSENGER_INFO, *PI2O_MESSENGER_INFO; + +/* ExecSysTabSet IOP Descriptor Entry structure. */ + +typedef struct _I2O_IOP_ENTRY { + U16 OrganizationID; + U16 reserved; +#if (defined(_DPT_BIG_ENDIAN) || defined(sparc)) + U32 IOP_ID; +#else + BF IOP_ID:I2O_IOP_ID_SZ; + BF reserved3:I2O_RESERVED_4BITS; + BF reserved1:I2O_RESERVED_16BITS; +#endif +#if (defined(_DPT_BIG_ENDIAN) || defined(sparc)) + U32 SegmentNumber; +#else + BF SegmentNumber:I2O_SEGMENT_NUMBER_SZ; + BF I2oVersion:I2O_4BIT_VERSION_SZ; + BF IopState:I2O_IOP_STATE_SZ; + BF MessengerType:I2O_MESSENGER_TYPE_SZ; +#endif + U16 InboundMessageFrameSize; + U16 reserved2; + U32 LastChanged; + U32 IopCapabilities; + I2O_MESSENGER_INFO MessengerInfo; +} I2O_IOP_ENTRY, *PI2O_IOP_ENTRY; + + +/****************************************************************************/ +/* Executive Parameter Groups */ +/****************************************************************************/ + + +#define I2O_EXEC_IOP_HARDWARE_GROUP_NO 0x0000 +#define I2O_EXEC_IOP_MESSAGE_IF_GROUP_NO 0x0001 +#define I2O_EXEC_EXECUTING_ENVIRONMENT_GROUP_NO 0x0002 +#define I2O_EXEC_EXECUTING_DDM_LIST_GROUP_NO 0x0003 +#define I2O_EXEC_DRIVER_STORE_GROUP_NO 0x0004 +#define I2O_EXEC_DRIVER_STORE_TABLE_GROUP_NO 0x0005 +#define I2O_EXEC_IOP_BUS_ATTRIBUTES_GROUP_NO 0x0006 +#define I2O_EXEC_IOP_SW_ATTRIBUTES_GROUP_NO 0x0007 +#define I2O_EXEC_HARDWARE_RESOURCE_TABLE_GROUP_NO 0x0100 +#define I2O_EXEC_LCT_SCALAR_GROUP_NO 0x0101 +#define I2O_EXEC_LCT_TABLE_GROUP_NO 0x0102 +#define I2O_EXEC_SYSTEM_TABLE_GROUP_NO 0x0103 +#define I2O_EXEC_EXTERNAL_CONN_TABLE_GROUP_NO 0x0104 + + +/* EXEC Group 0000h - IOP Hardware Parameter Group */ + +/* IOP HardWare Capabilities defines */ + +#define I2O_IOP_HW_CAP_SELF_BOOT 0x00000001 +#define I2O_IOP_HW_CAP_IRTOS_UPGRADEABLE 0x00000002 +#define I2O_IOP_HW_CAP_DOWNLOADABLE_DDM 0x00000004 +#define I2O_IOP_HW_CAP_INSTALLABLE_DDM 0x00000008 +#define I2O_IOP_HW_CAP_BATTERY_BACKUP_RAM 0x00000010 + +/* IOP Processor Type defines */ + +#define I2O_IOP_PROC_TYPE_INTEL_80960 0x00 +#define I2O_IOP_PROC_TYPE_AMD_29000 0x01 +#define I2O_IOP_PROC_TYPE_MOTOROLA_68000 0x02 +#define I2O_IOP_PROC_TYPE_ARM 0x03 +#define I2O_IOP_PROC_TYPE_MIPS 0x04 +#define I2O_IOP_PROC_TYPE_SPARC 0x05 +#define I2O_IOP_PROC_TYPE_POWER_PC 0x06 +#define I2O_IOP_PROC_TYPE_ALPHA 0x07 +#define I2O_IOP_PROC_TYPE_INTEL_X86 0x08 +#define I2O_IOP_PROC_TYPE_OTHER 0xFF + + +typedef struct _I2O_EXEC_IOP_HARDWARE_SCALAR { + U16 I2oVendorID; + U16 ProductID; + U32 ProcessorMemory; + U32 PermMemory; + U32 HWCapabilities; + U8 ProcessorType; + U8 ProcessorVersion; +} I2O_EXEC_IOP_HARDWARE_SCALAR, *PI2O_EXEC_IOP_HARDWARE_SCALAR; + + +/* EXEC Group 0001h - IOP Message Interface Parameter Group */ + +/* InitCode defines */ +#define I2O_MESSAGE_IF_INIT_CODE_NO_OWNER 0x00 +#define I2O_MESSAGE_IF_INIT_CODE_BIOS 0x10 +#define I2O_MESSAGE_IF_INIT_CODE_OEM_BIOS_EXTENSION 0x20 +#define I2O_MESSAGE_IF_INIT_CODE_ROM_BIOS_EXTENSION 0x30 +#define I2O_MESSAGE_IF_INIT_CODE_OS 0x80 + +typedef struct _I2O_EXEC_IOP_MESSAGE_IF_SCALAR { + U32 InboundFrameSize; + U32 InboundSizeTarget; + U32 InboundMax; + U32 InboundTarget; + U32 InboundPoolCount; + U32 InboundCurrentFree; + U32 InboundCurrentPost; + U16 StaticCount; + U16 StaticInstanceCount; + U16 StaticLimit; + U16 StaticInstanceLimit; + U32 OutboundFrameSize; + U32 OutboundMax; + U32 OutboundMaxTarget; + U32 OutboundCurrentFree; + U32 OutboundCurrentPost; + U8 InitCode; +} I2O_EXEC_IOP_MESSAGE_IF_SCALAR, *PI2O_EXEC_IOP_MESSAGE_IF_SCALAR; + + +/* EXEC Group 0002h - Executing Environment Parameter Group */ + +typedef struct _I2O_EXEC_EXECUTE_ENVIRONMENT_SCALAR { + U32 MemTotal; + U32 MemFree; + U32 PageSize; + U32 EventQMax; + U32 EventQCurrent; + U32 DDMLoadMax; +} I2O_EXEC_EXECUTE_ENVIRONMENT_SCALAR, *PI2O_EXEC_EXECUTE_ENVIRONMENT_SCALAR; + + +/* EXEC Group 0003h - Executing DDM's Parameter Group */ + +/* ModuleType Defines */ + +#define I2O_EXEC_DDM_MODULE_TYPE_OTHER 0x00 +#define I2O_EXEC_DDM_MODULE_TYPE_DOWNLOAD 0x01 +#define I2O_EXEC_DDM_MODULE_TYPE_EMBEDDED 0x22 + + +typedef struct _I2O_EXEC_EXECUTE_DDM_TABLE { + U16 DdmTID; + U8 ModuleType; + U8 reserved; + U16 I2oVendorID; + U16 ModuleID; + U8 ModuleName[I2O_MODULE_NAME_SZ]; + U32 ModuleVersion; + U32 DataSize; + U32 CodeSize; +} I2O_EXEC_EXECUTE_DDM_TABLE, *PI2O_EXEC_EXECUTE_DDM_TABLE; + + +/* EXEC Group 0004h - Driver Store Environment Parameter Group */ + + +typedef struct _I2O_EXEC_DRIVER_STORE_SCALAR { + U32 ModuleLimit; + U32 ModuleCount; + U32 CurrentSpace; + U32 FreeSpace; +} I2O_EXEC_DRIVER_STORE_SCALAR, *PI2O_EXEC_DRIVER_STORE_SCALAR; + + +/* EXEC Group 0005h - Driver Store Parameter Group */ + + +typedef struct _I2O_EXEC_DRIVER_STORE_TABLE { + U16 StoredDdmIndex; + U8 ModuleType; + U8 reserved; + U16 I2oVendorID; + U16 ModuleID; + U8 ModuleName[I2O_MODULE_NAME_SZ]; + U32 ModuleVersion; + U16 DateDay; + U16 DateMonth; + U32 DateYear; + U32 ModuleSize; + U32 MpbSize; + U32 ModuleFlags; +} I2O_EXEC_DRIVER_STORE_TABLE, *PI2O_EXEC_DRIVER_STORE_TABLE; + + +/* EXEC Group 0006h - IOP's Bus Attributes Parameter Group */ + +#define I2O_EXEC_IOP_BUS_ATTRIB_SYSTEM_BUS 0x00 +#define I2O_EXEC_IOP_BUS_ATTRIB_BRIDGED_SYSTEM_BUS 0x01 +#define I2O_EXEC_IOP_BUS_ATTRIB_PRIVATE 0x02 + +typedef struct _I2O_EXEC_IOP_BUS_ATTRIBUTE_TABLE { + U32 BusID; + U8 BusType; + U8 MaxAdapters; + U8 AdapterCount; + U8 BusAttributes; +} I2O_EXEC_IOP_BUS_ATTRIBUTE_TABLE, *PI2O_EXEC_IOP_BUS_ATTRIBUTE_TABLE; + + +/* EXEC Group 0007h - IOP's Bus Attributes Parameter Group */ + +#define I2O_EXEC_IOP_SW_CAP_IRTOS_I2O_COMPLIANT 0x00000001 +#define I2O_EXEC_IOP_SW_CAP_IRTOS_UPGRADEABLE 0x00000002 +#define I2O_EXEC_IOP_SW_CAP_DOWNLOADABLE_DDM 0x00000004 +#define I2O_EXEC_IOP_SW_CAP_INSTALLABLE_DDM 0x00000008 + +typedef struct _I2O_EXEC_IOP_SW_ATTRIBUTES_SCALAR { + U16 I2oVendorID; + U16 ProductID; + U32 CodeSize; + U32 SWCapabilities; +} I2O_EXEC_IOP_SW_ATTRIBUTES_SCALAR, *PI2O_EXEC_IOP_SW_ATTRIBUTES_SCALAR; + + +/* EXEC Group 0100h - Hardware Resource Table Parameter Group */ + +typedef struct _I2O_EXEC_HARDWARE_RESOURCE_TABLE { + U32 AdapterID; + U16 StateInfo; /* AdapterState plus Local TID */ + U8 BusNumber; + U8 BusType; + U64 PhysicalLocation; + U32 MemorySpace; + U32 IoSpace; +} I2O_EXEC_HARDWARE_RESOURCE_TABLE, *PI2O_EXEC_HARDWARE_RESOURCE_TABLE; + +/* EXEC Group 0101h - Logical Configuration Table Scalar Parameter Group */ + +typedef struct _I2O_EXEC_LCT_SCALAR { + U16 BootDevice; + U32 IopFlags; + U32 CurrentChangeIndicator; +} I2O_EXEC_LCT_SCALAR, *PI2O_EXEC_LCT_SCALAR; + +/* EXEC Group 0102h - Logical Configuration Table Parameter Group */ + +typedef struct _I2O_EXEC_LCT_TABLE { + U16 LocalTID; + U16 UserTID; + U16 ParentTID; + U16 DdmTID; + U32 ChangeIndicator; + U32 DeviceFlags; + U32 ClassID; + U32 SubClass; + U8 IdentityTag[I2O_IDENTITY_TAG_SZ]; + U32 EventCapabilities; + U8 BiosInfo; +} I2O_EXEC_LCT_TABLE, *PI2O_EXEC_LCT_TABLE; + +/* EXEC Group 0103h - System Table Parameter Group */ + +#define I2O_MESSENGER_TYPE_MEMORY_MAPPED_MESSAGE_UNIT 0x0 + +typedef struct _I2O_EXEC_SYSTEM_TABLE { + U16 IOP_ID; + U16 OrganizationID; + U16 SegmentNumber; + U8 Version; + U8 IopState; + U8 MessengerType; + U8 reserved; + U32 InboundMessagePortAddress; + U16 InboundMessageFrameSize; + U32 IopCapabilities; + I2O_MESSENGER_INFO MessengerInfo; +} I2O_EXEC_SYSTEM_TABLE, *PI2O_EXEC_SYSTEM_TABLE; + + +/* EXEC Group 0104h - External Connection Table Parameter Group */ + +#define I2O_EXEC_XCT_FLAGS_REMOTE_IOP_CREATED_CONNECTION 0x00 +#define I2O_EXEC_XCT_FLAGS_THIS_IOP_CREATED_CONNECTION 0x01 + +typedef struct _I2O_EXEC_EXTERNAL_CONNECTION_TABLE { + U16 LocalAliasTID; + U16 RemoteTID; + U16 RemoteIOP; + U16 RemoteUnitID; + U8 Flags; + U8 reserved; +} I2O_EXEC_EXTERNAL_CONNECTION_TABLE, *PI2O_EXEC_EXTERNAL_CONNECTION_TABLE; + + +/****************************************************************************/ + +PRAGMA_PACK_POP + +PRAGMA_ALIGN_POP + +#endif /* I2O_EXECUTIVE_HDR */ diff --git a/sys/dev/asr/i2omsg.h b/sys/dev/asr/i2omsg.h new file mode 100644 index 000000000000..bb28d628c626 --- /dev/null +++ b/sys/dev/asr/i2omsg.h @@ -0,0 +1,1290 @@ +/* $FreeBSD$ */ +/**************************************************************** + * Copyright (c) 1996-2000 Distributed Processing Technology Corporation + * Copyright (c) 2000 Adaptec Corporation. + * All rights reserved. + * + * Copyright 1999 I2O Special Interest Group (I2O SIG). All rights reserved. + * All rights reserved + * + * TERMS AND CONDITIONS OF USE + * + * Redistribution and use in source form, with or without modification, are + * permitted provided that redistributions of source code must retain the + * above copyright notice, this list of conditions and the following disclaimer. + * + * This software is provided `as is' by Distributed Processing Technology 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 Distributed Processing Technology 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 + * interruptions) 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 driver software, even if advised + * of the possibility of such damage. + * + * This header file, and any modifications of this header file, are provided + * contingent upon your agreement and adherence to the here-listed terms and + * conditions. By accepting and/or using this header file, you agree to abide + * by these terms and conditions and that these terms and conditions will be + * construed and governed in accordance with the laws of the State of California, + * without reference to conflict-of-law provisions. If you do not agree + * to these terms and conditions, please delete this file, and any copies, + * permanently, without making any use thereof. + * + * THIS HEADER FILE IS PROVIDED FREE OF CHARGE ON AN AS-IS BASIS WITHOUT + * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. I2O SIG DOES NOT WARRANT THAT THIS HEADER FILE WILL MEET THE + * USER'S REQUIREMENTS OR THAT ITS OPERATION WILL BE UNINTERRUPTED OR + * ERROR-FREE. + * + * I2O SIG DISCLAIMS ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF + * ANY PROPRIETARY RIGHTS, RELATING TO THE IMPLEMENTATION OF THE I2O + * SPECIFICATIONS. I2O SIG DOES NOT WARRANT OR REPRESENT THAT SUCH + * IMPLEMENTATIONS WILL NOT INFRINGE SUCH RIGHTS. + * + * THE USER OF THIS HEADER FILE SHALL HAVE NO RECOURSE TO I2O SIG FOR ANY + * ACTUAL OR CONSEQUENTIAL DAMAGES INCLUDING, BUT NOT LIMITED TO, LOST DATA + * OR LOST PROFITS ARISING OUT OF THE USE OR INABILITY TO USE THIS PROGRAM. + * + * I2O SIG grants the user of this header file a license to copy, distribute, + * and modify it, for any purpose, under the following terms. Any copying, + * distribution, or modification of this header file must not delete or alter + * the copyright notice of I2O SIG or any of these Terms and Conditions. + * + * Any distribution of this header file must not include a charge for the + * header file (unless such charges are strictly for the physical acts of + * copying or transferring copies). However, distribution of a product in + * which this header file is embedded may include a charge so long as any + * such charge does not include any charge for the header file itself. + * + * Any modification of this header file constitutes a derivative work based + * on this header file. Any distribution of such derivative work: (1) must + * include prominent notices that the header file has been changed from the + * original, together with the dates of any changes; (2) automatically includes + * this same license to the original header file from I2O SIG, without any + * restriction thereon from the distributing user; and (3) must include a + * grant of license of the modified file under the same terms and conditions + * as these Terms and Conditions. + * + * The I2O SIG Web site can be found at: http://www.i2osig.org + * + * The I2O SIG encourages you to deposit derivative works based on this + * header file at the I2O SIG Web site. Furthermore, to become a Registered + * Developer of the I2O SIG, sign up at the Web site or call 415.750.8352 + * (United States). + ****************************************************************/ + +/********************************************************************* + * I2OMsg.h -- I2O Message defintion file + * + * This file contains information presented in Chapter 3, 4 and 6 of + * the I2O(tm) Specification and most of the I2O Global defines and + * Typedefs. + **********************************************************************/ + +#if !defined(I2O_MESSAGE_HDR) +#define I2O_MESSAGE_HDR + +#define I2OMSG_REV 1_5_4 /* I2OMsg header file revision string */ + +/* + + NOTES: + + Gets, reads, receives, etc. are all even numbered functions. + Sets, writes, sends, etc. are all odd numbered functions. + Functions that both send and receive data can be either but an attempt is + made to use the function number that indicates the greater transfer amount. + Functions that do not send or receive data use odd function numbers. + + Some functions are synonyms like read, receive and send, write. + + All common functions will have a code of less than 0x80. + Unique functions to a class will start at 0x80. + Executive Functions start at 0xA0. + + Utility Message function codes range from 0 - 0x1f + Base Message function codes range from 0x20 - 0xfe + Private Message function code is 0xff. +*/ + + + +#if ((defined(KERNEL) || defined(_KERNEL)) && defined(__FreeBSD__)) +# if (KERN_VERSION < 3) +# include "i386/pci/i2otypes.h" +# else +# include "dev/asr/i2otypes.h" +# endif +#else +# include "i2otypes.h" +#endif + + +PRAGMA_ALIGN_PUSH + +PRAGMA_PACK_PUSH + +/* Set to 1 for 64 bit Context Fields */ +#define I2O_64BIT_CONTEXT 0 + +/****************************************************************************/ + +/* Common functions accross all classes. */ + +#define I2O_PRIVATE_MESSAGE 0xFF + +/****************************************************************************/ +/* Class ID and Code Assignments */ + + +#define I2O_CLASS_VERSION_10 0x00 +#define I2O_CLASS_VERSION_11 0x01 + +/* Class Code Names: Table 6-1 Class Code Assignments. */ +#define I2O_CLASS_EXECUTIVE 0x000 +#define I2O_CLASS_DDM 0x001 +#define I2O_CLASS_RANDOM_BLOCK_STORAGE 0x010 +#define I2O_CLASS_SEQUENTIAL_STORAGE 0x011 +#define I2O_CLASS_LAN 0x020 +#define I2O_CLASS_WAN 0x030 +#define I2O_CLASS_FIBRE_CHANNEL_PORT 0x040 +#define I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL 0x041 +#define I2O_CLASS_SCSI_PERIPHERAL 0x051 +#define I2O_CLASS_ATE_PORT 0x060 +#define I2O_CLASS_ATE_PERIPHERAL 0x061 +#define I2O_CLASS_FLOPPY_CONTROLLER 0x070 +#define I2O_CLASS_FLOPPY_DEVICE 0x071 +#define I2O_CLASS_BUS_ADAPTER_PORT 0x080 +/* Class Codes 0x090 - 0x09f are reserved for Peer-to-Peer classes */ +#define I2O_CLASS_MATCH_ANYCLASS 0xffffffff + +#define I2O_SUBCLASS_i960 0x001 +#define I2O_SUBCLASS_HDM 0x020 +#define I2O_SUBCLASS_ISM 0x021 + + +/****************************************************************************/ +/* Message Frame defines and structures */ + +/* Defines for the Version_Status field. */ + +#define I2O_VERSION_10 0x00 +#define I2O_VERSION_11 0x01 + +#define I2O_VERSION_OFFSET_NUMBER_MASK 0x07 +#define I2O_VERSION_OFFSET_SGL_TRL_OFFSET_MASK 0xF0 + +/* Defines for the Message Flags Field. */ +/* Please Note the the FAIL bit is only set in the Transport Fail Message. */ +#define I2O_MESSAGE_FLAGS_STATIC 0x01 +#define I2O_MESSAGE_FLAGS_64BIT_CONTEXT 0x02 +#define I2O_MESSAGE_FLAGS_MULTIPLE 0x10 +#define I2O_MESSAGE_FLAGS_FAIL 0x20 +#define I2O_MESSAGE_FLAGS_LAST 0x40 +#define I2O_MESSAGE_FLAGS_REPLY 0x80 + +/* Defines for Request Status Codes: Table 3-1 Reply Status Codes. */ + +#define I2O_REPLY_STATUS_SUCCESS 0x00 +#define I2O_REPLY_STATUS_ABORT_DIRTY 0x01 +#define I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER 0x02 +#define I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER 0x03 +#define I2O_REPLY_STATUS_ERROR_DIRTY 0x04 +#define I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER 0x05 +#define I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER 0x06 +#define I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY 0x08 +#define I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER 0x09 +#define I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER 0x0A +#define I2O_REPLY_STATUS_TRANSACTION_ERROR 0x0B +#define I2O_REPLY_STATUS_PROGRESS_REPORT 0x80 + +/* DetailedStatusCode defines for ALL messages: Table 3-2 Detailed Status Codes. */ + +#define I2O_DETAIL_STATUS_SUCCESS 0x0000 +#define I2O_DETAIL_STATUS_BAD_KEY 0x0002 +#define I2O_DETAIL_STATUS_TCL_ERROR 0x0003 +#define I2O_DETAIL_STATUS_REPLY_BUFFER_FULL 0x0004 +#define I2O_DETAIL_STATUS_NO_SUCH_PAGE 0x0005 +#define I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_SOFT 0x0006 +#define I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_HARD 0x0007 +#define I2O_DETAIL_STATUS_CHAIN_BUFFER_TOO_LARGE 0x0009 +#define I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION 0x000A +#define I2O_DETAIL_STATUS_DEVICE_LOCKED 0x000B +#define I2O_DETAIL_STATUS_DEVICE_RESET 0x000C +#define I2O_DETAIL_STATUS_INAPPROPRIATE_FUNCTION 0x000D +#define I2O_DETAIL_STATUS_INVALID_INITIATOR_ADDRESS 0x000E +#define I2O_DETAIL_STATUS_INVALID_MESSAGE_FLAGS 0x000F +#define I2O_DETAIL_STATUS_INVALID_OFFSET 0x0010 +#define I2O_DETAIL_STATUS_INVALID_PARAMETER 0x0011 +#define I2O_DETAIL_STATUS_INVALID_REQUEST 0x0012 +#define I2O_DETAIL_STATUS_INVALID_TARGET_ADDRESS 0x0013 +#define I2O_DETAIL_STATUS_MESSAGE_TOO_LARGE 0x0014 +#define I2O_DETAIL_STATUS_MESSAGE_TOO_SMALL 0x0015 +#define I2O_DETAIL_STATUS_MISSING_PARAMETER 0x0016 +#define I2O_DETAIL_STATUS_TIMEOUT 0x0017 +#define I2O_DETAIL_STATUS_UNKNOWN_ERROR 0x0018 +#define I2O_DETAIL_STATUS_UNKNOWN_FUNCTION 0x0019 +#define I2O_DETAIL_STATUS_UNSUPPORTED_VERSION 0x001A +#define I2O_DEATIL_STATUS_DEVICE_BUSY 0x001B +#define I2O_DETAIL_STATUS_DEVICE_NOT_AVAILABLE 0x001C + +/* Common I2O Field sizes */ + +#define I2O_TID_SZ 12 +#define I2O_FUNCTION_SZ 8 +#define I2O_UNIT_ID_SZ 16 +#define I2O_SEGMENT_NUMBER_SZ 12 + +#define I2O_IOP_ID_SZ 12 +#define I2O_GROUP_ID_SZ 16 +#define I2O_IOP_STATE_SZ 8 +#define I2O_MESSENGER_TYPE_SZ 8 + +#define I2O_CLASS_ID_SZ 12 +#define I2O_CLASS_ORGANIZATION_ID_SZ 16 + +#define I2O_4BIT_VERSION_SZ 4 +#define I2O_8BIT_FLAGS_SZ 8 +#define I2O_COMMON_LENGTH_FIELD_SZ 16 + +#define I2O_DEVID_DESCRIPTION_SZ 16 +#define I2O_DEVID_VENDOR_INFO_SZ 16 +#define I2O_DEVID_PRODUCT_INFO_SZ 16 +#define I2O_DEVID_REV_LEVEL_SZ 8 +#define I2O_MODULE_NAME_SZ 24 + +#define I2O_BIOS_INFO_SZ 8 + +#define I2O_RESERVED_4BITS 4 +#define I2O_RESERVED_8BITS 8 +#define I2O_RESERVED_12BITS 12 +#define I2O_RESERVED_16BITS 16 +#define I2O_RESERVED_20BITS 20 +#define I2O_RESERVED_24BITS 24 +#define I2O_RESERVED_28BITS 28 + + +typedef U32 I2O_PARAMETER_TID; + + +#if I2O_64BIT_CONTEXT +typedef U64 I2O_INITIATOR_CONTEXT; +typedef U64 I2O_TRANSACTION_CONTEXT; +#else +typedef U32 I2O_INITIATOR_CONTEXT; +typedef U32 I2O_TRANSACTION_CONTEXT; +#endif + +/* Serial Number format defines */ + +#define I2O_SERIAL_FORMAT_UNKNOWN 0 +#define I2O_SERIAL_FORMAT_BINARY 1 +#define I2O_SERIAL_FORMAT_ASCII 2 +#define I2O_SERIAL_FORMAT_UNICODE 3 +#define I2O_SERIAL_FORMAT_LAN_MAC 4 +#define I2O_SERIAL_FORMAT_WAN 5 + +/* Special TID Assignments */ + +#define I2O_IOP_TID 0 +#define I2O_HOST_TID 1 + + +/****************************************************************************/ + +/* I2O Message Frame common for all messages */ + +typedef struct _I2O_MESSAGE_FRAME { + U8 VersionOffset; + U8 MsgFlags; + U16 MessageSize; +#if (defined(__BORLANDC__)) || defined(_DPT_BIG_ENDIAN) || (defined(sparc)) + U32 TargetAddress; +#else + BF TargetAddress:I2O_TID_SZ; + BF InitiatorAddress:I2O_TID_SZ; + BF Function:I2O_FUNCTION_SZ; +#endif + I2O_INITIATOR_CONTEXT InitiatorContext; +} I2O_MESSAGE_FRAME, *PI2O_MESSAGE_FRAME; + + +/****************************************************************************/ + +/* Transaction Reply Lists (TRL) Control Word structure */ + +#define I2O_TRL_FLAGS_SINGLE_FIXED_LENGTH 0x00 +#define I2O_TRL_FLAGS_SINGLE_VARIABLE_LENGTH 0x40 +#define I2O_TRL_FLAGS_MULTIPLE_FIXED_LENGTH 0x80 + +typedef struct _I2O_TRL_CONTROL_WORD { + U8 TrlCount; + U8 TrlElementSize; + U8 reserved; + U8 TrlFlags; +#if I2O_64BIT_CONTEXT + U32 Padding; /* Padding for 64 bit */ +#endif +} I2O_TRL_CONTROL_WORD, *PI2O_TRL_CONTROL_WORD; + +/****************************************************************************/ + +/* I2O Successful Single Transaction Reply Message Frame structure. */ + +typedef struct _I2O_SINGLE_REPLY_MESSAGE_FRAME { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U16 DetailedStatusCode; + U8 reserved; + U8 ReqStatus; +/* ReplyPayload */ +} I2O_SINGLE_REPLY_MESSAGE_FRAME, *PI2O_SINGLE_REPLY_MESSAGE_FRAME; + + +/****************************************************************************/ + +/* I2O Successful Multiple Transaction Reply Message Frame structure. */ + +typedef struct _I2O_MULTIPLE_REPLY_MESSAGE_FRAME { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRL_CONTROL_WORD TrlControlWord; + U16 DetailedStatusCode; + U8 reserved; + U8 ReqStatus; +/* TransactionDetails[] */ +} I2O_MULTIPLE_REPLY_MESSAGE_FRAME, *PI2O_MULTIPLE_REPLY_MESSAGE_FRAME; + + +/****************************************************************************/ + +/* I2O Private Message Frame structure. */ + +typedef struct _I2O_PRIVATE_MESSAGE_FRAME { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U16 XFunctionCode; + U16 OrganizationID; +/* PrivatePayload[] */ +} I2O_PRIVATE_MESSAGE_FRAME, *PI2O_PRIVATE_MESSAGE_FRAME; + + +/****************************************************************************/ + +/* Message Failure Severity Codes */ + +#define I2O_SEVERITY_FORMAT_ERROR 0x1 +#define I2O_SEVERITY_PATH_ERROR 0x2 +#define I2O_SEVERITY_PATH_STATE 0x4 +#define I2O_SEVERITY_CONGESTION 0x8 + +/* Transport Failure Codes: Table 3-3 Mesasge Failure Codes */ + +#define I2O_FAILURE_CODE_TRANSPORT_SERVICE_SUSPENDED 0x81 +#define I2O_FAILURE_CODE_TRANSPORT_SERVICE_TERMINATED 0x82 +#define I2O_FAILURE_CODE_TRANSPORT_CONGESTION 0x83 +#define I2O_FAILURE_CODE_TRANSPORT_FAIL 0x84 +#define I2O_FAILURE_CODE_TRANSPORT_STATE_ERROR 0x85 +#define I2O_FAILURE_CODE_TRANSPORT_TIME_OUT 0x86 +#define I2O_FAILURE_CODE_TRANSPORT_ROUTING_FAILURE 0x87 +#define I2O_FAILURE_CODE_TRANSPORT_INVALID_VERSION 0x88 +#define I2O_FAILURE_CODE_TRANSPORT_INVALID_OFFSET 0x89 +#define I2O_FAILURE_CODE_TRANSPORT_INVALID_MSG_FLAGS 0x8A +#define I2O_FAILURE_CODE_TRANSPORT_FRAME_TOO_SMALL 0x8B +#define I2O_FAILURE_CODE_TRANSPORT_FRAME_TOO_LARGE 0x8C +#define I2O_FAILURE_CODE_TRANSPORT_INVALID_TARGET_ID 0x8D +#define I2O_FAILURE_CODE_TRANSPORT_INVALID_INITIATOR_ID 0x8E +#define I2O_FAILURE_CODE_TRANSPORT_INVALID_INITIATOR_CONTEXT 0x8F +#define I2O_FAILURE_CODE_TRANSPORT_UNKNOWN_FAILURE 0xFF + +/* IOP_ID and Severity sizes */ + +#define I2O_FAILCODE_SEVERITY_SZ 8 +#define I2O_FAILCODE_CODE_SZ 8 + +/* I2O Transport Message Reply for Message Failure. */ + +typedef struct _I2O_FAILURE_REPLY_MESSAGE_FRAME { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +# if (defined(_DPT_BIG_ENDIAN) || defined(sparc) || defined(__BORLANDC__)) + U32 LowestVersion; + U32 reserved; +# else + U8 LowestVersion; + U8 HighestVersion; +/* BF Severity:I2O_FAILCODE_SEVERITY_SZ; +// BF FailureCode:I2O_FAILCODE_CODE_SZ; +// +// Due to our compiler padding this structure and making it larger than +// it really is (4 bytes larger), we are re-defining these two fields +*/ + U8 Severity; + U8 FailureCode; + BF reserved:I2O_RESERVED_4BITS; + BF FailingHostUnitID:I2O_UNIT_ID_SZ; + BF reserved1:12; +# endif + U32 AgeLimit; +/* i2odep.h looks after this, but for portability sake ... */ +#if (!defined(__FAR__)) +# if (defined(__BORLANDC__)) +# define __FAR__ far +# else +# define __FAR__ +# endif +#endif +/* Not really `far, but it is a *long* physical pointer reference */ + I2O_MESSAGE_FRAME __FAR__ * PreservedMFA; +} I2O_FAILURE_REPLY_MESSAGE_FRAME, *PI2O_FAILURE_REPLY_MESSAGE_FRAME; + +/* I2O Transport Message Reply for Transaction Error. */ + +typedef struct _I2O_TRANSACTION_ERROR_REPLY_MESSAGE_FRAME { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U16 DetailedStatusCode; + U8 reserved; + U8 ReqStatus; /* Should always be Transaction Error */ + U32 ErrorOffset; + U8 BitOffset; + U8 reserved1; + U16 reserved2; +} I2O_TRANSACTION_ERROR_REPLY_MESSAGE_FRAME, *PI2O_TRANSACTION_ERROR_REPLY_MESSAGE_FRAME; + +/****************************************************************************/ + +/* Misc. commonly used structures */ + +/* Class ID Block */ + +typedef struct _I2O_CLASS_ID { +#if (defined(_DPT_BIG_ENDIAN) || defined(sparc)) + U32 Class; +#else + BF Class:I2O_CLASS_ID_SZ; + BF Version:I2O_4BIT_VERSION_SZ; + BF OrganizationID:I2O_CLASS_ORGANIZATION_ID_SZ; +#endif +} I2O_CLASS_ID, *PI2O_CLASS_ID; + + +#define I2O_MAX_SERIAL_NUMBER_SZ 256 + +typedef struct _I2O_SERIAL_INFO { + U8 SerialNumberLength; + U8 SerialNumberFormat; + U8 SerialNumber[I2O_MAX_SERIAL_NUMBER_SZ]; +} I2O_SERIAL_INFO, *PI2O_SERIAL_INFO; + + +/****************************************************************************/ +/* Hardware Resource Table (HRT) and Logical Configuration Table (LCT) */ +/****************************************************************************/ + +/* Bus Type Code defines */ + +#define I2O_LOCAL_BUS 0 +#define I2O_ISA_BUS 1 +#define I2O_EISA_BUS 2 +#define I2O_MCA_BUS 3 +#define I2O_PCI_BUS 4 +#define I2O_PCMCIA_BUS 5 +#define I2O_NUBUS_BUS 6 +#define I2O_CARDBUS_BUS 7 +#define I2O_OTHER_BUS 0x80 + +#define I2O_HRT_STATE_SZ 4 +#define I2O_HRT_BUS_NUMBER_SZ 8 +#define I2O_HRT_BUS_TYPE_SZ 8 + + +/* Bus Structures */ + +/* PCI Bus */ +typedef struct _I2O_PCI_BUS_INFO { + U8 PciFunctionNumber; + U8 PciDeviceNumber; + U8 PciBusNumber; + U8 reserved; + U16 PciVendorID; + U16 PciDeviceID; +} I2O_PCI_BUS_INFO, *PI2O_PCI_BUS_INFO; + +/* Local Bus */ +typedef struct _I2O_LOCAL_BUS_INFO { + U16 LbBaseIOPort; + U16 reserved; + U32 LbBaseMemoryAddress; +} I2O_LOCAL_BUS_INFO, *PI2O_LOCAL_BUS_INFO; + +/* ISA Bus */ +typedef struct _I2O_ISA_BUS_INFO { + U16 IsaBaseIOPort; + U8 CSN; + U8 reserved; + U32 IsaBaseMemoryAddress; +} I2O_ISA_BUS_INFO, *PI2O_ISA_BUS_INFO; + +/* EISA Bus */ +typedef struct _I2O_EISA_BUS_INFO { + U16 EisaBaseIOPort; + U8 reserved; + U8 EisaSlotNumber; + U32 EisaBaseMemoryAddress; +} I2O_EISA_BUS_INFO, *PI2O_EISA_BUS_INFO; + +/* MCA Bus */ +typedef struct _I2O_MCA_BUS_INFO { + U16 McaBaseIOPort; + U8 reserved; + U8 McaSlotNumber; + U32 McaBaseMemoryAddress; +} I2O_MCA_BUS_INFO, *PI2O_MCA_BUS_INFO; + +/* Other Bus */ +typedef struct _I2O_OTHER_BUS_INFO { + U16 BaseIOPort; + U16 reserved; + U32 BaseMemoryAddress; +} I2O_OTHER_BUS_INFO, *PI2O_OTHER_BUS_INFO; + + +/* HRT Entry Block */ + +typedef struct _I2O_HRT_ENTRY { + U32 AdapterID; +#if (defined(_DPT_BIG_ENDIAN) || defined(sparc)) + U32 ControllingTID; +#else + BF ControllingTID:I2O_TID_SZ; + BF AdapterState:I2O_HRT_STATE_SZ; + BF BusNumber:I2O_HRT_BUS_NUMBER_SZ; + BF BusType:I2O_HRT_BUS_TYPE_SZ; +#endif + union { + /* PCI Bus */ + I2O_PCI_BUS_INFO PCIBus; + + /* Local Bus */ + I2O_LOCAL_BUS_INFO LocalBus; + + /* ISA Bus */ + I2O_ISA_BUS_INFO ISABus; + + /* EISA Bus */ + I2O_EISA_BUS_INFO EISABus; + + /* MCA Bus */ + I2O_MCA_BUS_INFO MCABus; + + /* Other. */ + I2O_OTHER_BUS_INFO OtherBus; + }uBus; +} I2O_HRT_ENTRY, *PI2O_HRT_ENTRY; + + +/* I2O Hardware Resource Table structure. */ + +typedef struct _I2O_HRT { + U16 NumberEntries; + U8 EntryLength; + U8 HRTVersion; + U32 CurrentChangeIndicator; + I2O_HRT_ENTRY HRTEntry[1]; +} I2O_HRT, *PI2O_HRT; + + +/****************************************************************************/ +/* Logical Configuration Table */ +/****************************************************************************/ + +/* I2O Logical Configuration Table structures. */ + +#define I2O_IDENTITY_TAG_SZ 8 + +/* I2O Logical Configuration Table Device Flags */ + +#define I2O_LCT_DEVICE_FLAGS_CONF_DIALOG_REQUEST 0x01 +#define I2O_LCT_DEVICE_FLAGS_MORE_THAN_1_USER 0x02 +#define I2O_LCT_DEVICE_FLAGS_PEER_SERVICE_DISABLED 0x10 +#define I2O_LCT_DEVICE_FLAGS_MANAGEMENT_SERVICE_DISABLED 0x20 + +/* LCT Entry Block */ + +typedef struct _I2O_LCT_ENTRY { +#if (defined(_DPT_BIG_ENDIAN) || defined(sparc)) + U32 TableEntrySize; +#else + BF TableEntrySize:I2O_COMMON_LENGTH_FIELD_SZ; + BF LocalTID:I2O_TID_SZ; + BF reserved:I2O_4BIT_VERSION_SZ; +#endif + U32 ChangeIndicator; + U32 DeviceFlags; + I2O_CLASS_ID ClassID; + U32 SubClassInfo; +#if (defined(__BORLANDC__)) || defined(_DPT_BIG_ENDIAN) || (defined(sparc)) + U32 UserTID; +#else + BF UserTID:I2O_TID_SZ; + BF ParentTID:I2O_TID_SZ; + BF BiosInfo:I2O_BIOS_INFO_SZ; +#endif + U8 IdentityTag[I2O_IDENTITY_TAG_SZ]; + U32 EventCapabilities; +} I2O_LCT_ENTRY, *PI2O_LCT_ENTRY; + + +/* I2O Logical Configuration Table structure. */ + +typedef struct _I2O_LCT { +#if (defined(_DPT_BIG_ENDIAN) || defined(sparc)) + U32 TableSize; +#else + BF TableSize:I2O_COMMON_LENGTH_FIELD_SZ; + BF BootDeviceTID:I2O_TID_SZ; + BF LctVer:I2O_4BIT_VERSION_SZ; +#endif + U32 IopFlags; + U32 CurrentChangeIndicator; + I2O_LCT_ENTRY LCTEntry[1]; +} I2O_LCT, *PI2O_LCT; + + +/****************************************************************************/ + +/* Memory Addressing structures and defines. */ + +/* SglFlags defines. */ + +#define I2O_SGL_FLAGS_LAST_ELEMENT 0x80 +#define I2O_SGL_FLAGS_END_OF_BUFFER 0x40 + +#define I2O_SGL_FLAGS_IGNORE_ELEMENT 0x00 +#define I2O_SGL_FLAGS_TRANSPORT_ELEMENT 0x04 +#define I2O_SGL_FLAGS_BIT_BUCKET_ELEMENT 0x08 +#define I2O_SGL_FLAGS_IMMEDIATE_DATA_ELEMENT 0x0C +#define I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT 0x10 +#define I2O_SGL_FLAGS_PAGE_LIST_ADDRESS_ELEMENT 0x20 +#define I2O_SGL_FLAGS_CHAIN_POINTER_ELEMENT 0x30 +#define I2O_SGL_FLAGS_LONG_TRANSACTION_ELEMENT 0x40 +#define I2O_SGL_FLAGS_SHORT_TRANSACTION_ELEMENT 0x70 +#define I2O_SGL_FLAGS_SGL_ATTRIBUTES_ELEMENT 0x7C + +#define I2O_SGL_FLAGS_BC0 0x01 +#define I2O_SGL_FLAGS_BC1 0x02 +#define I2O_SGL_FLAGS_DIR 0x04 +#define I2O_SGL_FLAGS_LOCAL_ADDRESS 0x08 + +#define I2O_SGL_FLAGS_CONTEXT_COUNT_MASK 0x03 +#define I2O_SGL_FLAGS_ADDRESS_MODE_MASK 0x3C +#define I2O_SGL_FLAGS_NO_CONTEXT 0x00 + +/* Scatter/Gather Truth Table */ + +/* + +typedef enum _SG_TYPE { + INVALID, + Ignore, + TransportDetails, + BitBucket, + ImmediateData, + Simple, + PageList, + ChainPointer, + ShortTransaction, + LongTransaction, + SGLAttributes, + INVALID/ReservedLongFormat, + INVALID/ReservedShortFormat +} SG_TYPE, *PSG_TYPE; + + + 0x00 Ignore; + 0x04 TransportDetails; + 0x08 BitBucket; + 0x0C ImmediateData; + 0x10 Simple; + 0x14 Simple; + 0x18 Simple; + 0x1C Simple; + 0x20 PageList; + 0x24 PageList; + 0x28 PageList; + 0x2C PageList; + 0x30 ChainPointer; + 0x34 INVALID; + 0x38 ChainPointer; + 0x3C INVALID; + 0x40 LongTransaction; + 0x44 INVALID/ReservedLongFormat; + 0x48 BitBucket; + 0x4C ImmediateData; + 0x50 Simple; + 0x54 Simple; + 0x58 Simple; + 0x5C Simple; + 0x60 PageList; + 0x64 PageList; + 0x68 PageList; + 0x6C PageList; + 0x70 ShortTransaction; + 0x74 INVALID/ReservedShortFormat; + 0x78 INVALID/ReservedShortFormat; + 0x7C SGLAttributes; +*/ + + +/* 32 Bit Context Field defines */ + +#define I2O_SGL_FLAGS_CONTEXT32_NULL 0x00 +#define I2O_SGL_FLAGS_CONTEXT32_U32 0x01 +#define I2O_SGL_FLAGS_CONTEXT32_U64 0x02 +#define I2O_SGL_FLAGS_CONTEXT32_U96 0x03 + +#define I2O_SGL_FLAGS_CONTEXT32_NULL_SZ 0x00 +#define I2O_SGL_FLAGS_CONTEXT32_U32_SZ 0x04 +#define I2O_SGL_FLAGS_CONTEXT32_U64_SZ 0x08 +#define I2O_SGL_FLAGS_CONTEXT32_U96_SZ 0x0C + +/* 64 Bit Context Field defines */ + +#define I2O_SGL_FLAGS_CONTEXT64_NULL 0x00 +#define I2O_SGL_FLAGS_CONTEXT64_U64 0x01 +#define I2O_SGL_FLAGS_CONTEXT64_U128 0x02 +#define I2O_SGL_FLAGS_CONTEXT64_U192 0x03 + +#define I2O_SGL_FLAGS_CONTEXT64_NULL_SZ 0x00 +#define I2O_SGL_FLAGS_CONTEXT64_U64_SZ 0x08 +#define I2O_SGL_FLAGS_CONTEXT64_U128_SZ 0x10 +#define I2O_SGL_FLAGS_CONTEXT64_U192_SZ 0x18 + +/* SGL Attribute Element defines */ + +#define I2O_SGL_ATTRIBUTE_FLAGS_BIT_BUCKET_HINT 0x0400 +#define I2O_SGL_ATTRIBUTE_FLAGS_IMMEDIATE_DATA_HINT 0x0200 +#define I2O_SGL_ATTRIBUTE_FLAGS_LOCAL_ADDRESS_HINT 0x0100 +#define I2O_SGL_ATTRIBUTE_FLAGS_32BIT_TRANSACTION 0x0000 +#define I2O_SGL_ATTRIBUTE_FLAGS_64BIT_TRANSACTION 0x0004 +#define I2O_SGL_ATTRIBUTE_FLAGS_32BIT_LOCAL_ADDRESS 0x0000 + +/* SG Size defines */ + +#define I2O_SG_COUNT_SZ 24 +#define I2O_SG_FLAGS_SZ 8 + +/* Standard Flags and Count fields for SG Elements */ + +typedef struct _I2O_FLAGS_COUNT { +#if (defined(__BORLANDC__)) || defined(_DPT_BIG_ENDIAN) || (defined(sparc)) + U32 Count; +#else + BF Count:I2O_SG_COUNT_SZ; + BF Flags:I2O_SG_FLAGS_SZ; +#endif +} I2O_FLAGS_COUNT, *PI2O_FLAGS_COUNT; + +/* Bit Bucket Element */ + +typedef struct _I2O_SGE_BIT_BUCKET_ELEMENT { + I2O_FLAGS_COUNT FlagsCount; + U32 BufferContext; +} I2O_SGE_BIT_BUCKET_ELEMENT, *PI2O_SGE_BIT_BUCKET_ELEMENT; + +/* Chain Addressing Scatter-Gather Element */ + +typedef struct _I2O_SGE_CHAIN_ELEMENT { + I2O_FLAGS_COUNT FlagsCount; + U32 PhysicalAddress; +} I2O_SGE_CHAIN_ELEMENT, *PI2O_SGE_CHAIN_ELEMENT; + +/* Chain Addressing with Context Scatter-Gather Element */ + +typedef struct _I2O_SGE_CHAIN_CONTEXT_ELEMENT { + I2O_FLAGS_COUNT FlagsCount; + U32 Context[1]; + U32 PhysicalAddress; +} I2O_SGE_CHAIN_CONTEXT_ELEMENT, *PI2O_SGE_CHAIN_CONTEXT_ELEMENT; + +/* Ignore Scatter-Gather Element */ + +typedef struct _I2O_SGE_IGNORE_ELEMENT { + I2O_FLAGS_COUNT FlagsCount; +} I2O_SGE_IGNORE_ELEMENT, *PI2O_SGE_IGNORE_ELEMENT; + +/* Immediate Data Element */ + +typedef struct _I2O_SGE_IMMEDIATE_DATA_ELEMENT { + I2O_FLAGS_COUNT FlagsCount; +} I2O_SGE_IMMEDIATE_DATA_ELEMENT, *PI2O_SGE_IMMEDIATE_DATA_ELEMENT; + +/* Immediate Data with Context Element */ + +typedef struct _I2O_SGE_IMMEDIATE_DATA_CONTEXT_ELEMENT { + I2O_FLAGS_COUNT FlagsCount; + U32 BufferContext; +} I2O_SGE_IMMEDIATE_DATA_CONTEXT_ELEMENT, *PI2O_SGE_IMMEDIATE_DATA_CONTEXT_ELEMENT; + +/* Long Transaction Parameters Element */ + +typedef struct _I2O_SGE_LONG_TRANSACTION_ELEMENT { +#if (defined(__BORLANDC__)) + U32 LongElementLength; +#else + BF LongElementLength:I2O_SG_COUNT_SZ; + BF Flags:I2O_SG_FLAGS_SZ; +#endif + U32 BufferContext; +} I2O_SGE_LONG_TRANSACTION_ELEMENT, *PI2O_SGE_LONG_TRANSACTION_ELEMENT; + +/* Page List Scatter-Gather Element */ + +typedef struct _I2O_SGE_PAGE_ELEMENT { + I2O_FLAGS_COUNT FlagsCount; + U32 PhysicalAddress[1]; +} I2O_SGE_PAGE_ELEMENT , *PI2O_SGE_PAGE_ELEMENT ; + +/* Page List with Context Scatter-Gather Element */ + +typedef struct _I2O_SGE_PAGE_CONTEXT_ELEMENT { + I2O_FLAGS_COUNT FlagsCount; + U32 BufferContext[1]; + U32 PhysicalAddress[1]; +} I2O_SGE_PAGE_CONTEXT_ELEMENT, *PI2O_SGE_PAGE_CONTEXT_ELEMENT; + +/* SGL Attribute Element */ + +typedef struct _I2O_SGE_SGL_ATTRIBUTES_ELEMENT { + U16 SglAttributeFlags; + U8 ElementLength; + U8 Flags; + U32 PageFrameSize; +} I2O_SGE_SGL_ATTRIBUTES_ELEMENT, *PI2O_SGE_SGL_ATTRIBUTES_ELEMENT; + +/* Short Transaction Parameters Element */ + +typedef struct _I2O_SGE_SHORT_TRANSACTION_ELEMENT { + U16 ClassFields; + U8 ElementLength; + U8 Flags; + U32 BufferContext; +} I2O_SGE_SHORT_TRANSACTION_ELEMENT, *PI2O_SGE_SHORT_TRANSACTION_ELEMENT; + +/* Simple Addressing Scatter-Gather Element */ + +typedef struct _I2O_SGE_SIMPLE_ELEMENT { + I2O_FLAGS_COUNT FlagsCount; + U32 PhysicalAddress; +} I2O_SGE_SIMPLE_ELEMENT, *PI2O_SGE_SIMPLE_ELEMENT; + +/* Simple Addressing with Context Scatter-Gather Element */ + +typedef struct _I2O_SGE_SIMPLE_CONTEXT_ELEMENT { + I2O_FLAGS_COUNT FlagsCount; + U32 BufferContext[1]; + U32 PhysicalAddress; +} I2O_SGE_SIMPLE_CONTEXT_ELEMENT, *PI2O_SGE_SIMPLE_CONTEXT_ELEMENT; + +/* Transport Detail Element */ + +typedef struct _I2O_SGE_TRANSPORT_ELEMENT { +#if (defined(__BORLANDC__)) + U32 LongElementLength; +#else + BF LongElementLength:I2O_SG_COUNT_SZ; + BF Flags:I2O_SG_FLAGS_SZ; +#endif +} I2O_SGE_TRANSPORT_ELEMENT, *PI2O_SGE_TRANSPORT_ELEMENT; + +typedef struct _I2O_SG_ELEMENT { + union { + /* Bit Bucket Element */ + I2O_SGE_BIT_BUCKET_ELEMENT BitBucket; + + /* Chain Addressing Element */ + I2O_SGE_CHAIN_ELEMENT Chain; + + /* Chain Addressing with Context Element */ + I2O_SGE_CHAIN_CONTEXT_ELEMENT ChainContext; + + /* Ignore Scatter-Gather Element */ + I2O_SGE_IGNORE_ELEMENT Ignore; + + /* Immediate Data Element */ + I2O_SGE_IMMEDIATE_DATA_ELEMENT ImmediateData; + + /* Immediate Data with Context Element */ + I2O_SGE_IMMEDIATE_DATA_CONTEXT_ELEMENT ImmediateDataContext; + + /* Long Transaction Parameters Element */ + I2O_SGE_LONG_TRANSACTION_ELEMENT LongTransaction; + + /* Page List Element */ + I2O_SGE_PAGE_ELEMENT Page; + + /* Page List with Context Element */ + I2O_SGE_PAGE_CONTEXT_ELEMENT PageContext; + + /* SGL Attribute Element */ + I2O_SGE_SGL_ATTRIBUTES_ELEMENT SGLAttribute; + + /* Short Transaction Parameters Element */ + I2O_SGE_SHORT_TRANSACTION_ELEMENT ShortTransaction; + + /* Simple Addressing Element */ + I2O_SGE_SIMPLE_ELEMENT Simple[1]; + + /* Simple Addressing with Context Element */ + I2O_SGE_SIMPLE_CONTEXT_ELEMENT SimpleContext[1]; + + /* Transport Detail Element */ + I2O_SGE_TRANSPORT_ELEMENT Transport; +#if (defined(sun) && defined(u)) +// there is a macro defined in Solaris sys/user.h for u, rename this to uSG + } uSG ; +#else + } u ; +#endif +} I2O_SG_ELEMENT, *PI2O_SG_ELEMENT; + +/****************************************************************************/ +/* Basic Parameter Group Access */ +/****************************************************************************/ + +/* Operation Function Numbers */ + +#define I2O_PARAMS_OPERATION_FIELD_GET 0x0001 +#define I2O_PARAMS_OPERATION_LIST_GET 0x0002 +#define I2O_PARAMS_OPERATION_MORE_GET 0x0003 +#define I2O_PARAMS_OPERATION_SIZE_GET 0x0004 +#define I2O_PARAMS_OPERATION_TABLE_GET 0x0005 +#define I2O_PARAMS_OPERATION_FIELD_SET 0x0006 +#define I2O_PARAMS_OPERATION_LIST_SET 0x0007 +#define I2O_PARAMS_OPERATION_ROW_ADD 0x0008 +#define I2O_PARAMS_OPERATION_ROW_DELETE 0x0009 +#define I2O_PARAMS_OPERATION_TABLE_CLEAR 0x000A + +/* Operations List Header */ + +typedef struct _I2O_PARAM_OPERATIONS_LIST_HEADER { + U16 OperationCount; + U16 Reserved; +} I2O_PARAM_OPERATIONS_LIST_HEADER, *PI2O_PARAM_OPERATIONS_LIST_HEADER; + +/* Results List Header */ + +typedef struct _I2O_PARAM_RESULTS_LIST_HEADER { + U16 ResultCount; + U16 Reserved; +} I2O_PARAM_RESULTS_LIST_HEADER, *PI2O_PARAM_RESULTS_LIST_HEADER; + +/* Read Operation Result Block Template Structure */ + +typedef struct _I2O_PARAM_READ_OPERATION_RESULT { + U16 BlockSize; + U8 BlockStatus; + U8 ErrorInfoSize; + /* Operations Results */ + /* Pad (if any) */ + /* ErrorInformation (if any) */ +} I2O_PARAM_READ_OPERATION_RESULT, *PI2O_PARAM_READ_OPERATION_RESULT; + +typedef struct _I2O_TABLE_READ_OPERATION_RESULT { + U16 BlockSize; + U8 BlockStatus; + U8 ErrorInfoSize; + U16 RowCount; + U16 MoreFlag; + /* Operations Results */ + /* Pad (if any) */ + /* ErrorInformation (if any) */ +} I2O_TABLE_READ_OPERATION_RESULT, *PI2O_TABLE_READ_OPERATION_RESULT; + +/* Error Information Template Structure */ + +typedef struct _I2O_PARAM_ERROR_INFO_TEMPLATE { + U16 OperationCode; + U16 GroupNumber; + U16 FieldIdx; + U8 AdditionalStatus; + U8 NumberKeys; + /* List of Key Values (variable) */ + /* Pad (if any) */ +} I2O_PARAM_ERROR_INFO_TEMPLATE, *PI2O_PARAM_ERROR_INFO_TEMPLATE; + +/* Operation Template for Specific Fields */ + +typedef struct _I2O_PARAM_OPERATION_SPECIFIC_TEMPLATE { + U16 Operation; + U16 GroupNumber; + U16 FieldCount; + U16 FieldIdx[1]; + /* Pad (if any) */ +} I2O_PARAM_OPERATION_SPECIFIC_TEMPLATE, *PI2O_PARAM_OPERATION_SPECIFIC_TEMPLATE; + +/* Operation Template for All Fields */ + +typedef struct _I2O_PARAM_OPERATION_ALL_TEMPLATE { + U16 Operation; + U16 GroupNumber; + U16 FieldCount; + /* Pad (if any) */ +} I2O_PARAM_OPERATION_ALL_TEMPLATE, *PI2O_PARAM_OPERATION_ALL_TEMPLATE; + +/* Operation Template for All List Fields */ + +typedef struct _I2O_PARAM_OPERATION_ALL_LIST_TEMPLATE { + U16 Operation; + U16 GroupNumber; + U16 FieldCount; + U16 KeyCount; + U8 KeyValue; + /* Pad (if any) */ +} I2O_PARAM_OPERATION_ALL_LIST_TEMPLATE, *PI2O_PARAM_OPERATION_ALL_LIST_TEMPLATE; + +/* Modify Operation Result Block Template Structure */ + +typedef struct _I2O_PARAM_MODIFY_OPERATION_RESULT { + U16 BlockSize; + U8 BlockStatus; + U8 ErrorInfoSize; + /* ErrorInformation (if any) */ +} I2O_PARAM_MODIFY_OPERATION_RESULT, *PI2O_PARAM_MODIFY_OPERATION_RESULT; + +/* Operation Template for Row Delete */ + +typedef struct _I2O_PARAM_OPERATION_ROW_DELETE_TEMPLATE { + U16 Operation; + U16 GroupNumber; + U16 RowCount; + U8 KeyValue; +} I2O_PARAM_OPERATION_ROW_DELETE_TEMPLATE, *PI2O_PARAM_OPERATION_ROW_DELETE_TEMPLATE; + +/* Operation Template for Table Clear */ + +typedef struct _I2O_PARAM_OPERATION_TABLE_CLEAR_TEMPLATE { + U16 Operation; + U16 GroupNumber; +} I2O_PARAM_OPERATION_TABLE_CLEAR_TEMPLATE, *PI2O_PARAM_OPERATION_TABLE_CLEAR_TEMPLATE; + +/* Status codes and Error Information for Parameter functions */ + +#define I2O_PARAMS_STATUS_SUCCESS 0x00 +#define I2O_PARAMS_STATUS_BAD_KEY_ABORT 0x01 +#define I2O_PARAMS_STATUS_BAD_KEY_CONTINUE 0x02 +#define I2O_PARAMS_STATUS_BUFFER_FULL 0x03 +#define I2O_PARAMS_STATUS_BUFFER_TOO_SMALL 0x04 +#define I2O_PARAMS_STATUS_FIELD_UNREADABLE 0x05 +#define I2O_PARAMS_STATUS_FIELD_UNWRITEABLE 0x06 +#define I2O_PARAMS_STATUS_INSUFFICIENT_FIELDS 0x07 +#define I2O_PARAMS_STATUS_INVALID_GROUP_ID 0x08 +#define I2O_PARAMS_STATUS_INVALID_OPERATION 0x09 +#define I2O_PARAMS_STATUS_NO_KEY_FIELD 0x0A +#define I2O_PARAMS_STATUS_NO_SUCH_FIELD 0x0B +#define I2O_PARAMS_STATUS_NON_DYNAMIC_GROUP 0x0C +#define I2O_PARAMS_STATUS_OPERATION_ERROR 0x0D +#define I2O_PARAMS_STATUS_SCALAR_ERROR 0x0E +#define I2O_PARAMS_STATUS_TABLE_ERROR 0x0F +#define I2O_PARAMS_STATUS_WRONG_GROUP_TYPE 0x10 + + +/****************************************************************************/ +/* GROUP Parameter Groups */ +/****************************************************************************/ + +/* GROUP Configuration and Operating Structures and Defines */ + +/* Groups Numbers */ + +#define I2O_UTIL_PARAMS_DESCRIPTOR_GROUP_NO 0xF000 +#define I2O_UTIL_PHYSICAL_DEVICE_TABLE_GROUP_NO 0xF001 +#define I2O_UTIL_CLAIMED_TABLE_GROUP_NO 0xF002 +#define I2O_UTIL_USER_TABLE_GROUP_NO 0xF003 +#define I2O_UTIL_PRIVATE_MESSAGE_EXTENSIONS_GROUP_NO 0xF005 +#define I2O_UTIL_AUTHORIZED_USER_TABLE_GROUP_NO 0xF006 +#define I2O_UTIL_DEVICE_IDENTITY_GROUP_NO 0xF100 +#define I2O_UTIL_DDM_IDENTITY_GROUP_NO 0xF101 +#define I2O_UTIL_USER_INFORMATION_GROUP_NO 0xF102 +#define I2O_UTIL_SGL_OPERATING_LIMITS_GROUP_NO 0xF103 +#define I2O_UTIL_SENSORS_GROUP_NO 0xF200 + +/* UTIL Group F000h - GROUP DESCRIPTORS Parameter Group */ + +#define I2O_UTIL_GROUP_PROPERTIES_GROUP_TABLE 0x01 +#define I2O_UTIL_GROUP_PROPERTIES_ROW_ADDITION 0x02 +#define I2O_UTIL_GROUP_PROPERTIES_ROW_DELETION 0x04 +#define I2O_UTIL_GROUP_PROPERTIES_CLEAR_OPERATION 0x08 + +typedef struct _I2O_UTIL_GROUP_DESCRIPTOR_TABLE { + U16 GroupNumber; + U16 FieldCount; + U16 RowCount; + U8 Properties; + U8 reserved; +} I2O_UTIL_GROUP_DESCRIPTOR_TABLE, *PI2O_UTIL_GROUP_DESCRIPTOR_TABLE; + +/* UTIL Group F001h - Physical Device Table Parameter Group */ + +typedef struct _I2O_UTIL_PHYSICAL_DEVICE_TABLE { + U32 AdapterID; +} I2O_UTIL_PHYSICAL_DEVICE_TABLE, *PI2O_UTIL_PHYSICAL_DEVICE_TABLE; + +/* UTIL Group F002h - Claimed Table Parameter Group */ + +typedef struct _I2O_UTIL_CLAIMED_TABLE { + U16 ClaimedTID; +} I2O_UTIL_CLAIMED_TABLE, *PI2O_UTIL_CLAIMED_TABLE; + +/* UTIL Group F003h - User Table Parameter Group */ + +typedef struct _I2O_UTIL_USER_TABLE { + U16 Instance; + U16 UserTID; + U8 ClaimType; + U8 reserved1; + U16 reserved2; +} I2O_UTIL_USER_TABLE, *PI2O_UTIL_USER_TABLE; + +/* UTIL Group F005h - Private Message Extensions Parameter Group */ + +typedef struct _I2O_UTIL_PRIVATE_MESSAGE_EXTENSIONS_TABLE { + U16 ExtInstance; + U16 OrganizationID; + U16 XFunctionCode; +} I2O_UTIL_PRIVATE_MESSAGE_EXTENSIONS_TABLE, *PI2O_UTIL_PRIVATE_MESSAGE_EXTENSIONS_TABLE; + +/* UTIL Group F006h - Authorized User Table Parameter Group */ + +typedef struct _I2O_UTIL_AUTHORIZED_USER_TABLE { + U16 AlternateTID; +} I2O_UTIL_AUTHORIZED_USER_TABLE, *PI2O_UTIL_AUTHORIZED_USER_TABLE; + +/* UTIL Group F100h - Device Identity Parameter Group */ + +typedef struct _I2O_UTIL_DEVICE_IDENTITY_SCALAR { + U32 ClassID; + U16 OwnerTID; + U16 ParentTID; + U8 VendorInfo[I2O_DEVID_VENDOR_INFO_SZ]; + U8 ProductInfo[I2O_DEVID_PRODUCT_INFO_SZ]; + U8 Description[I2O_DEVID_DESCRIPTION_SZ]; + U8 ProductRevLevel[I2O_DEVID_REV_LEVEL_SZ]; + U8 SNFormat; + U8 SerialNumber[I2O_MAX_SERIAL_NUMBER_SZ]; +} I2O_UTIL_DEVICE_IDENTITY_SCALAR, *PI2O_UTIL_DEVICE_IDENTITY_SCALAR; + +/* UTIL Group F101h - DDM Identity Parameter Group */ + +typedef struct _I2O_UTIL_DDM_IDENTITY_SCALAR { + U16 DdmTID; + U8 ModuleName[I2O_MODULE_NAME_SZ]; + U8 ModuleRevLevel[I2O_DEVID_REV_LEVEL_SZ]; + U8 SNFormat; + U8 SerialNumber[I2O_MAX_SERIAL_NUMBER_SZ]; +} I2O_UTIL_DDM_IDENTITY_SCALAR, *PI2O_UTIL_DDM_IDENTITY_SCALAR; + +/* UTIL Group F102h - User Information Parameter Group */ + +#define I2O_USER_DEVICE_NAME_SZ 64 +#define I2O_USER_SERVICE_NAME_SZ 64 +#define I2O_USER_PHYSICAL_LOCATION_SZ 64 + +typedef struct _I2O_UTIL_USER_INFORMATION_SCALAR { + U8 DeviceName[I2O_USER_DEVICE_NAME_SZ]; + U8 ServiceName[I2O_USER_SERVICE_NAME_SZ]; + U8 PhysicalLocation[I2O_USER_PHYSICAL_LOCATION_SZ]; + U32 InstanceNumber; +} I2O_UTIL_USER_INFORMATION_SCALAR, *PI2O_UTIL_USER_INFORMATION_SCALAR; + +/* UTIL Group F103h - SGL Operating Limits Parameter Group */ + +typedef struct _I2O_UTIL_SGL_OPERATING_LIMITS_SCALAR { + U32 SglChainSize; + U32 SglChainSizeMax; + U32 SglChainSizeTarget; + U16 SglFragCount; + U16 SglFragCountMax; + U16 SglFragCountTarget; +} I2O_UTIL_SGL_OPERATING_LIMITS_SCALAR, *PI2O_UTIL_SGL_OPERATING_LIMITS_SCALAR; + +/* UTIL Group F200h - Sensors Parameter Group */ + +#define I2O_SENSOR_COMPONENT_OTHER 0x00 +#define I2O_SENSOR_COMPONENT_PLANAR_LOGIC_BOARD 0x01 +#define I2O_SENSOR_COMPONENT_CPU 0x02 +#define I2O_SENSOR_COMPONENT_CHASSIS 0x03 +#define I2O_SENSOR_COMPONENT_POWER_SUPPLY 0x04 +#define I2O_SENSOR_COMPONENT_STORAGE 0x05 +#define I2O_SENSOR_COMPONENT_EXTERNAL 0x06 + +#define I2O_SENSOR_SENSOR_CLASS_ANALOG 0x00 +#define I2O_SENSOR_SENSOR_CLASS_DIGITAL 0x01 + +#define I2O_SENSOR_SENSOR_TYPE_OTHER 0x00 +#define I2O_SENSOR_SENSOR_TYPE_THERMAL 0x01 +#define I2O_SENSOR_SENSOR_TYPE_DC_VOLTAGE 0x02 +#define I2O_SENSOR_SENSOR_TYPE_AC_VOLTAGE 0x03 +#define I2O_SENSOR_SENSOR_TYPE_DC_CURRENT 0x04 +#define I2O_SENSOR_SENSOR_TYPE_AC_CURRENT 0x05 +#define I2O_SENSOR_SENSOR_TYPE_DOOR_OPEN 0x06 +#define I2O_SENSOR_SENSOR_TYPE_FAN_OPERATIONAL 0x07 + +#define I2O_SENSOR_SENSOR_STATE_NORMAL 0x00 +#define I2O_SENSOR_SENSOR_STATE_ABNORMAL 0x01 +#define I2O_SENSOR_SENSOR_STATE_UNKNOWN 0x02 +#define I2O_SENSOR_SENSOR_STATE_LOW_CAT 0x03 +#define I2O_SENSOR_SENSOR_STATE_LOW 0x04 +#define I2O_SENSOR_SENSOR_STATE_LOW_WARNING 0x05 +#define I2O_SENSOR_SENSOR_STATE_HIGH_WARNING 0x06 +#define I2O_SENSOR_SENSOR_STATE_HIGH 0x07 +#define I2O_SENSOR_SENSOR_STATE_HIGH_CAT 0x08 + +#define I2O_SENSOR_EVENT_ENABLE_STATE_CHANGE 0x0001 +#define I2O_SENSOR_EVENT_ENABLE_LOW_CATASTROPHIC 0x0002 +#define I2O_SENSOR_EVENT_ENABLE_LOW_READING 0x0004 +#define I2O_SENSOR_EVENT_ENABLE_LOW_WARNING 0x0008 +#define I2O_SENSOR_EVENT_ENABLE_CHANGE_TO_NORMAL 0x0010 +#define I2O_SENSOR_EVENT_ENABLE_HIGH_WARNING 0x0020 +#define I2O_SENSOR_EVENT_ENABLE_HIGH_READING 0x0040 +#define I2O_SENSOR_EVENT_ENABLE_HIGH_CATASTROPHIC 0x0080 + + +typedef struct _I2O_UTIL_SENSORS_TABLE { + U16 SensorInstance; + U8 Component; + U16 ComponentInstance; + U8 SensorClass; + U8 SensorType; + S8 ScalingExponent; + S32 ActualReading; + S32 MinimumReading; + S32 Low2LowCatThreshold; + S32 LowCat2LowThreshold; + S32 LowWarn2LowThreshold; + S32 Low2LowWarnThreshold; + S32 Norm2LowWarnThreshold; + S32 LowWarn2NormThreshold; + S32 NominalReading; + S32 HiWarn2NormThreshold; + S32 Norm2HiWarnThreshold; + S32 High2HiWarnThreshold; + S32 HiWarn2HighThreshold; + S32 HiCat2HighThreshold; + S32 Hi2HiCatThreshold; + S32 MaximumReading; + U8 SensorState; + U16 EventEnable; +} I2O_UTIL_SENSORS_TABLE, *PI2O_UTIL_SENSORS_TABLE; + + +PRAGMA_PACK_POP + +PRAGMA_ALIGN_POP + +#endif /* I2O_MESSAGE_HDR */ diff --git a/sys/dev/asr/i2otypes.h b/sys/dev/asr/i2otypes.h new file mode 100644 index 000000000000..18511e66252d --- /dev/null +++ b/sys/dev/asr/i2otypes.h @@ -0,0 +1,134 @@ +/* $FreeBSD$ */ +/**************************************************************** + * Copyright (c) 1996-2000 Distributed Processing Technology Corporation + * Copyright (c) 2000 Adaptec Corporation. + * All rights reserved. + * + * Copyright 1999 I2O Special Interest Group (I2O SIG). All rights reserved. + * All rights reserved + * + * TERMS AND CONDITIONS OF USE + * + * Redistribution and use in source form, with or without modification, are + * permitted provided that redistributions of source code must retain the + * above copyright notice, this list of conditions and the following disclaimer. + * + * This software is provided `as is' by Distributed Processing Technology 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 Distributed Processing Technology 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 + * interruptions) 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 driver software, even if advised + * of the possibility of such damage. + * + * This header file, and any modifications of this header file, are provided + * contingent upon your agreement and adherence to the here-listed terms and + * conditions. By accepting and/or using this header file, you agree to abide + * by these terms and conditions and that these terms and conditions will be + * construed and governed in accordance with the laws of the State of California, + * without reference to conflict-of-law provisions. If you do not agree + * to these terms and conditions, please delete this file, and any copies, + * permanently, without making any use thereof. + * + * THIS HEADER FILE IS PROVIDED FREE OF CHARGE ON AN AS-IS BASIS WITHOUT + * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. I2O SIG DOES NOT WARRANT THAT THIS HEADER FILE WILL MEET THE + * USER'S REQUIREMENTS OR THAT ITS OPERATION WILL BE UNINTERRUPTED OR + * ERROR-FREE. + * + * I2O SIG DISCLAIMS ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF + * ANY PROPRIETARY RIGHTS, RELATING TO THE IMPLEMENTATION OF THE I2O + * SPECIFICATIONS. I2O SIG DOES NOT WARRANT OR REPRESENT THAT SUCH + * IMPLEMENTATIONS WILL NOT INFRINGE SUCH RIGHTS. + * + * THE USER OF THIS HEADER FILE SHALL HAVE NO RECOURSE TO I2O SIG FOR ANY + * ACTUAL OR CONSEQUENTIAL DAMAGES INCLUDING, BUT NOT LIMITED TO, LOST DATA + * OR LOST PROFITS ARISING OUT OF THE USE OR INABILITY TO USE THIS PROGRAM. + * + * I2O SIG grants the user of this header file a license to copy, distribute, + * and modify it, for any purpose, under the following terms. Any copying, + * distribution, or modification of this header file must not delete or alter + * the copyright notice of I2O SIG or any of these Terms and Conditions. + * + * Any distribution of this header file must not include a charge for the + * header file (unless such charges are strictly for the physical acts of + * copying or transferring copies). However, distribution of a product in + * which this header file is embedded may include a charge so long as any + * such charge does not include any charge for the header file itself. + * + * Any modification of this header file constitutes a derivative work based + * on this header file. Any distribution of such derivative work: (1) must + * include prominent notices that the header file has been changed from the + * original, together with the dates of any changes; (2) automatically includes + * this same license to the original header file from I2O SIG, without any + * restriction thereon from the distributing user; and (3) must include a + * grant of license of the modified file under the same terms and conditions + * as these Terms and Conditions. + * + * The I2O SIG Web site can be found at: http://www.i2osig.org + * + * The I2O SIG encourages you to deposit derivative works based on this + * header file at the I2O SIG Web site. Furthermore, to become a Registered + * Developer of the I2O SIG, sign up at the Web site or call 415.750.8352 + * (United States). + ****************************************************************/ + +#ifndef __INCi2otypesh +#define __INCi2otypesh + +#define I2OTYPES_REV 1_5_4 + +/* include architecture/compiler dependencies */ + +#if ((defined(KERNEL) || defined(_KERNEL)) && defined(__FreeBSD__)) +# if (KERN_VERSION < 3) +# include "i386/pci/i2odep.h" +# else +# include "dev/asr/i2odep.h" +# endif +#else +# include "i2odep.h" +#endif + + +/* 64 bit defines */ + +typedef struct _S64 { + U32 LowPart; + S32 HighPart; +} S64; + +typedef struct _U64 { + U32 LowPart; + U32 HighPart; +} U64; + +/* Pointer to Basics */ + +typedef VOID *PVOID; +typedef S8 *PS8; +typedef S16 *PS16; +typedef S32 *PS32; +typedef S64 *PS64; + +/* Pointer to Unsigned Basics */ + +typedef U8 *PU8; +typedef U16 *PU16; +typedef U32 *PU32; +typedef U64 *PU64; + +/* misc */ + +typedef S32 I2O_ARG; +typedef U32 I2O_COUNT; +typedef U32 I2O_USECS; +typedef U32 I2O_ADDR32; +typedef U32 I2O_SIZE; + +#endif /* __INCi2otypesh */ diff --git a/sys/dev/asr/i2outil.h b/sys/dev/asr/i2outil.h new file mode 100644 index 000000000000..ee9ba54609ce --- /dev/null +++ b/sys/dev/asr/i2outil.h @@ -0,0 +1,418 @@ +/* $FreeBSD$ */ +/**************************************************************** + * Copyright (c) 1996-2000 Distributed Processing Technology Corporation + * Copyright (c) 2000 Adaptec Corporation. + * All rights reserved. + * + * Copyright 1999 I2O Special Interest Group (I2O SIG). All rights reserved. + * All rights reserved + * + * TERMS AND CONDITIONS OF USE + * + * Redistribution and use in source form, with or without modification, are + * permitted provided that redistributions of source code must retain the + * above copyright notice, this list of conditions and the following disclaimer. + * + * This software is provided `as is' by Distributed Processing Technology 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 Distributed Processing Technology 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 + * interruptions) 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 driver software, even if advised + * of the possibility of such damage. + * + * This header file, and any modifications of this header file, are provided + * contingent upon your agreement and adherence to the here-listed terms and + * conditions. By accepting and/or using this header file, you agree to abide + * by these terms and conditions and that these terms and conditions will be + * construed and governed in accordance with the laws of the State of California, + * without reference to conflict-of-law provisions. If you do not agree + * to these terms and conditions, please delete this file, and any copies, + * permanently, without making any use thereof. + * + * THIS HEADER FILE IS PROVIDED FREE OF CHARGE ON AN AS-IS BASIS WITHOUT + * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. I2O SIG DOES NOT WARRANT THAT THIS HEADER FILE WILL MEET THE + * USER'S REQUIREMENTS OR THAT ITS OPERATION WILL BE UNINTERRUPTED OR + * ERROR-FREE. + * + * I2O SIG DISCLAIMS ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF + * ANY PROPRIETARY RIGHTS, RELATING TO THE IMPLEMENTATION OF THE I2O + * SPECIFICATIONS. I2O SIG DOES NOT WARRANT OR REPRESENT THAT SUCH + * IMPLEMENTATIONS WILL NOT INFRINGE SUCH RIGHTS. + * + * THE USER OF THIS HEADER FILE SHALL HAVE NO RECOURSE TO I2O SIG FOR ANY + * ACTUAL OR CONSEQUENTIAL DAMAGES INCLUDING, BUT NOT LIMITED TO, LOST DATA + * OR LOST PROFITS ARISING OUT OF THE USE OR INABILITY TO USE THIS PROGRAM. + * + * I2O SIG grants the user of this header file a license to copy, distribute, + * and modify it, for any purpose, under the following terms. Any copying, + * distribution, or modification of this header file must not delete or alter + * the copyright notice of I2O SIG or any of these Terms and Conditions. + * + * Any distribution of this header file must not include a charge for the + * header file (unless such charges are strictly for the physical acts of + * copying or transferring copies). However, distribution of a product in + * which this header file is embedded may include a charge so long as any + * such charge does not include any charge for the header file itself. + * + * Any modification of this header file constitutes a derivative work based + * on this header file. Any distribution of such derivative work: (1) must + * include prominent notices that the header file has been changed from the + * original, together with the dates of any changes; (2) automatically includes + * this same license to the original header file from I2O SIG, without any + * restriction thereon from the distributing user; and (3) must include a + * grant of license of the modified file under the same terms and conditions + * as these Terms and Conditions. + * + * The I2O SIG Web site can be found at: http://www.i2osig.org + * + * The I2O SIG encourages you to deposit derivative works based on this + * header file at the I2O SIG Web site. Furthermore, to become a Registered + * Developer of the I2O SIG, sign up at the Web site or call 415.750.8352 + * (United States). + ****************************************************************/ + +/********************************************************************* + * I2OUtil.h -- I2O Utility Class Message defintion file + * + * This file contains information presented in Chapter 6 of the I2O + * Specification. + **********************************************************************/ + +#if !defined(I2O_UTILITY_HDR) +#define I2O_UTILITY_HDR + +#define I2OUTIL_REV 1_5_4 /* I2OUtil header file revision string */ + +#if ((defined(KERNEL) || defined(_KERNEL)) && defined(__FreeBSD__)) +# if (KERN_VERSION < 3) +# include "i386/pci/i2omsg.h" /* Include the Base Message file */ +# else +# include "dev/asr/i2omsg.h" +# endif +#else +# include "i2omsg.h" /* Include the Base Message file */ +#endif + + +/* +NOTES: + + Gets, reads, receives, etc. are all even numbered functions. + Sets, writes, sends, etc. are all odd numbered functions. + Functions that both send and receive data can be either but an attempt is made + to use the function number that indicates the greater transfer amount. + Functions that do not send or receive data use odd function numbers. + + Some functions are synonyms like read, receive and send, write. + + All common functions will have a code of less than 0x80. + Unique functions to a class will start at 0x80. + Executive Functions start at 0xA0. + + Utility Message function codes range from 0 - 0x1f + Base Message function codes range from 0x20 - 0xfe + Private Message function code is 0xff. +*/ + +PRAGMA_ALIGN_PUSH + +PRAGMA_PACK_PUSH + +/* Utility Message class functions. */ + +#define I2O_UTIL_NOP 0x00 +#define I2O_UTIL_ABORT 0x01 +#define I2O_UTIL_CLAIM 0x09 +#define I2O_UTIL_CLAIM_RELEASE 0x0B +#define I2O_UTIL_CONFIG_DIALOG 0x10 +#define I2O_UTIL_DEVICE_RESERVE 0x0D +#define I2O_UTIL_DEVICE_RELEASE 0x0F +#define I2O_UTIL_EVENT_ACKNOWLEDGE 0x14 +#define I2O_UTIL_EVENT_REGISTER 0x13 +#define I2O_UTIL_LOCK 0x17 +#define I2O_UTIL_LOCK_RELEASE 0x19 +#define I2O_UTIL_PARAMS_GET 0x06 +#define I2O_UTIL_PARAMS_SET 0x05 +#define I2O_UTIL_REPLY_FAULT_NOTIFY 0x15 + +/****************************************************************************/ + +/* ABORT Abort type defines. */ + +#define I2O_ABORT_TYPE_EXACT_ABORT 0x00 +#define I2O_ABORT_TYPE_FUNCTION_ABORT 0x01 +#define I2O_ABORT_TYPE_TRANSACTION_ABORT 0x02 +#define I2O_ABORT_TYPE_WILD_ABORT 0x03 +#define I2O_ABORT_TYPE_CLEAN_EXACT_ABORT 0x04 +#define I2O_ABORT_TYPE_CLEAN_FUNCTION_ABORT 0x05 +#define I2O_ABORT_TYPE_CLEAN_TRANSACTION_ABORT 0x06 +#define I2O_ABORT_TYPE_CLEAN_WILD_ABORT 0x07 + +/* UtilAbort Function Message Frame structure. */ + +typedef struct _I2O_UTIL_ABORT_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +# if (defined(_DPT_BIG_ENDIAN) || defined(sparc)) + U32 reserved; +# else + U16 reserved; + U8 AbortType; + U8 FunctionToAbort; +# endif + I2O_TRANSACTION_CONTEXT TransactionContextToAbort; +} I2O_UTIL_ABORT_MESSAGE, *PI2O_UTIL_ABORT_MESSAGE; + + +typedef struct _I2O_UTIL_ABORT_REPLY { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U32 CountOfAbortedMessages; +} I2O_UTIL_ABORT_REPLY, *PI2O_UTIL_ABORT_REPLY; + + +/****************************************************************************/ + +/* Claim Flag defines */ + +#define I2O_CLAIM_FLAGS_EXCLUSIVE 0x0001 /* Reserved */ +#define I2O_CLAIM_FLAGS_RESET_SENSITIVE 0x0002 +#define I2O_CLAIM_FLAGS_STATE_SENSITIVE 0x0004 +#define I2O_CLAIM_FLAGS_CAPACITY_SENSITIVE 0x0008 +#define I2O_CLAIM_FLAGS_PEER_SERVICE_DISABLED 0x0010 +#define I2O_CLAIM_FLAGS_MGMT_SERVICE_DISABLED 0x0020 + +/* Claim Type defines */ + +#define I2O_CLAIM_TYPE_PRIMARY_USER 0x01 +#define I2O_CLAIM_TYPE_AUTHORIZED_USER 0x02 +#define I2O_CLAIM_TYPE_SECONDARY_USER 0x03 +#define I2O_CLAIM_TYPE_MANAGEMENT_USER 0x04 + +/* UtilClaim Function Message Frame structure. */ + +typedef struct _I2O_UTIL_CLAIM_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U16 ClaimFlags; + U8 reserved; + U8 ClaimType; +} I2O_UTIL_CLAIM_MESSAGE, *PI2O_UTIL_CLAIM_MESSAGE; + + +/****************************************************************************/ + +/* Claim Release Flag defines */ + +#define I2O_RELEASE_FLAGS_CONDITIONAL 0x0001 + +/* UtilClaimRelease Function Message Frame structure. */ + +typedef struct _I2O_UTIL_CLAIM_RELEASE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U16 ReleaseFlags; + U8 reserved; + U8 ClaimType; +} I2O_UTIL_CLAIM_RELEASE_MESSAGE, *PI2O_UTIL_CLAIM_RELEASE_MESSAGE; + + +/****************************************************************************/ + +/* UtilConfigDialog Function Message Frame structure */ + +typedef struct _I2O_UTIL_CONFIG_DIALOG_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U32 PageNumber; + I2O_SG_ELEMENT SGL; +} I2O_UTIL_CONFIG_DIALOG_MESSAGE, *PI2O_UTIL_CONFIG_DIALOG_MESSAGE; + + +/****************************************************************************/ + +/* Event Acknowledge Function Message Frame structure */ + +typedef struct _I2O_UTIL_EVENT_ACK_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U32 EventIndicator; + U32 EventData[1]; +} I2O_UTIL_EVENT_ACK_MESSAGE, *PI2O_UTIL_EVENT_ACK_MESSAGE; + +/* Event Ack Reply structure */ + +typedef struct _I2O_UTIL_EVENT_ACK_REPLY { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U32 EventIndicator; + U32 EventData[1]; +} I2O_UTIL_EVENT_ACK_REPLY, *PI2O_UTIL_EVENT_ACK_REPLY; + + +/****************************************************************************/ + +/* Event Indicator Mask Flags */ + +#define I2O_EVENT_IND_STATE_CHANGE 0x80000000 +#define I2O_EVENT_IND_GENERAL_WARNING 0x40000000 +#define I2O_EVENT_IND_CONFIGURATION_FLAG 0x20000000 +/* #define I2O_EVENT_IND_RESERVE_RELEASE 0x10000000 */ +#define I2O_EVENT_IND_LOCK_RELEASE 0x10000000 +#define I2O_EVENT_IND_CAPABILITY_CHANGE 0x08000000 +#define I2O_EVENT_IND_DEVICE_RESET 0x04000000 +#define I2O_EVENT_IND_EVENT_MASK_MODIFIED 0x02000000 +#define I2O_EVENT_IND_FIELD_MODIFIED 0x01000000 +#define I2O_EVENT_IND_VENDOR_EVENT 0x00800000 +#define I2O_EVENT_IND_DEVICE_STATE 0x00400000 + +/* Event Data for generic Events */ + +#define I2O_EVENT_STATE_CHANGE_NORMAL 0x00 +#define I2O_EVENT_STATE_CHANGE_SUSPENDED 0x01 +#define I2O_EVENT_STATE_CHANGE_RESTART 0x02 +#define I2O_EVENT_STATE_CHANGE_NA_RECOVER 0x03 +#define I2O_EVENT_STATE_CHANGE_NA_NO_RECOVER 0x04 +#define I2O_EVENT_STATE_CHANGE_QUIESCE_REQUEST 0x05 +#define I2O_EVENT_STATE_CHANGE_FAILED 0x10 +#define I2O_EVENT_STATE_CHANGE_FAULTED 0x11 + +#define I2O_EVENT_GEN_WARNING_NORMAL 0x00 +#define I2O_EVENT_GEN_WARNING_ERROR_THRESHOLD 0x01 +#define I2O_EVENT_GEN_WARNING_MEDIA_FAULT 0x02 + +#define I2O_EVENT_CAPABILITY_OTHER 0x01 +#define I2O_EVENT_CAPABILITY_CHANGED 0x02 + +#define I2O_EVENT_SENSOR_STATE_CHANGED 0x01 + + +/* UtilEventRegister Function Message Frame structure */ + +typedef struct _I2O_UTIL_EVENT_REGISTER_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U32 EventMask; +} I2O_UTIL_EVENT_REGISTER_MESSAGE, *PI2O_UTIL_EVENT_REGISTER_MESSAGE; + +/* UtilEventRegister Reply structure */ + +typedef struct _I2O_UTIL_EVENT_REGISTER_REPLY { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U32 EventIndicator; + U32 EventData[1]; +} I2O_UTIL_EVENT_REGISTER_REPLY, *PI2O_UTIL_EVENT_REGISTER_REPLY; + + +/****************************************************************************/ + +/* UtilLock Function Message Frame structure. */ + +typedef struct _I2O_UTIL_LOCK_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +} I2O_UTIL_LOCK_MESSAGE, *PI2O_UTIL_LOCK_MESSAGE; + +/****************************************************************************/ + +/* UtilLockRelease Function Message Frame structure. */ + +typedef struct _I2O_UTIL_LOCK_RELEASE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +} I2O_UTIL_LOCK_RELEASE_MESSAGE, *PI2O_UTIL_LOCK_RELEASE_MESSAGE; + + +/****************************************************************************/ + +/* UtilNOP Function Message Frame structure. */ + +typedef struct _I2O_UTIL_NOP_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; +} I2O_UTIL_NOP_MESSAGE, *PI2O_UTIL_NOP_MESSAGE; + + +/****************************************************************************/ + +/* UtilParamsGet Message Frame structure. */ + +typedef struct _I2O_UTIL_PARAMS_GET_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U32 OperationFlags; + I2O_SG_ELEMENT SGL; +} I2O_UTIL_PARAMS_GET_MESSAGE, *PI2O_UTIL_PARAMS_GET_MESSAGE; + + +/****************************************************************************/ + +/* UtilParamsSet Message Frame structure. */ + +typedef struct _I2O_UTIL_PARAMS_SET_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U32 OperationFlags; + I2O_SG_ELEMENT SGL; +} I2O_UTIL_PARAMS_SET_MESSAGE, *PI2O_UTIL_PARAMS_SET_MESSAGE; + + +/****************************************************************************/ + +/* UtilReplyFaultNotify Message for Message Failure. */ + +typedef struct _I2O_UTIL_REPLY_FAULT_NOTIFY_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; + U8 LowestVersion; + U8 HighestVersion; + BF Severity:I2O_FAILCODE_SEVERITY_SZ; + BF FailureCode:I2O_FAILCODE_CODE_SZ; + BF FailingIOP_ID:I2O_IOP_ID_SZ; + BF reserved:I2O_RESERVED_4BITS; + BF FailingHostUnitID:I2O_UNIT_ID_SZ; + U32 AgeLimit; +#if I2O_64BIT_CONTEXT + PI2O_MESSAGE_FRAME OriginalMFA; +#else + PI2O_MESSAGE_FRAME OriginalMFALowPart; + U32 OriginalMFAHighPart; /* Always 0000 */ +#endif +} I2O_UTIL_REPLY_FAULT_NOTIFY_MESSAGE, *PI2O_UTIL_REPLY_FAULT_NOTIFY_MESSAGE; + + +/****************************************************************************/ + +/* Device Reserve Function Message Frame structure. */ +/* NOTE: This was previously called the Reserve Message */ + +typedef struct _I2O_UTIL_DEVICE_RESERVE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +} I2O_UTIL_DEVICE_RESERVE_MESSAGE, *PI2O_UTIL_DEVICE_RESERVE_MESSAGE; + + +/****************************************************************************/ + +/* Device Release Function Message Frame structure. */ +/* NOTE: This was previously called the ReserveRelease Message */ + +typedef struct _I2O_UTIL_DEVICE_RELEASE_MESSAGE { + I2O_MESSAGE_FRAME StdMessageFrame; + I2O_TRANSACTION_CONTEXT TransactionContext; +} I2O_UTIL_DEVICE_RELEASE_MESSAGE, *PI2O_UTIL_DEVICE_RELEASE_MESSAGE; + + +/****************************************************************************/ + +PRAGMA_PACK_POP +PRAGMA_ALIGN_POP + +#endif /* I2O_UTILITY_HDR */ diff --git a/sys/dev/asr/osd_defs.h b/sys/dev/asr/osd_defs.h new file mode 100644 index 000000000000..89591343bd54 --- /dev/null +++ b/sys/dev/asr/osd_defs.h @@ -0,0 +1,80 @@ +/* $FreeBSD$ */ +/* BSDI osd_defs.h,v 1.4 1998/06/03 19:14:58 karels Exp */ +/* + * Copyright (c) 1996-1999 Distributed Processing Technology Corporation + * All rights reserved. + * + * Redistribution and use in source form, with or without modification, are + * permitted provided that redistributions of source code must retain the + * above copyright notice, this list of conditions and the following disclaimer. + * + * This software is provided `as is' by Distributed Processing Technology 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 Distributed Processing Technology 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 + * interruptions) 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 driver software, even if advised + * of the possibility of such damage. + * + */ + +#ifndef _OSD_DEFS_H +#define _OSD_DEFS_H + +/*File - OSD_DEFS.H + **************************************************************************** + * + *Description: + * + * This file contains the OS dependent defines. This file is included + *in osd_util.h and provides the OS specific defines for that file. + * + *Copyright Distributed Processing Technology, Corp. + * 140 Candace Dr. + * Maitland, Fl. 32751 USA + * Phone: (407) 830-5522 Fax: (407) 260-5366 + * All Rights Reserved + * + *Author: Doug Anderson + *Date: 1/31/94 + * + *Editors: + * + *Remarks: + * + * + *****************************************************************************/ + + +/*Definitions - Defines & Constants ----------------------------------------- */ + + /* Define the operating system */ +#if (defined(__linux__)) +# define _DPT_LINUX +#elif (defined(__bsdi__)) +# define _DPT_BSDI +#elif (defined(__FreeBSD__)) +# define _DPT_FREE_BSD +#else +# define _DPT_SCO +#endif + +#if defined (ZIL_CURSES) +#define _DPT_CURSES +#else +#define _DPT_MOTIF +#endif + + /* Redefine 'far' to nothing - no far pointer type required in UNIX */ +#define far + + /* Define the mutually exclusive semaphore type */ +#define SEMAPHORE_T unsigned int * + /* Define a handle to a DLL */ +#define DLL_HANDLE_T unsigned int * + +#endif diff --git a/sys/dev/asr/osd_unix.h b/sys/dev/asr/osd_unix.h new file mode 100644 index 000000000000..d283aff050ae --- /dev/null +++ b/sys/dev/asr/osd_unix.h @@ -0,0 +1,590 @@ +/* $FreeBSD$ */ +/* BSDI osd_unix.h,v 1.7 1998/06/03 19:14:58 karels Exp */ + +/* + * Copyright (c) 1996-1999 Distributed Processing Technology Corporation + * All rights reserved. + * + * Redistribution and use in source form, with or without modification, are + * permitted provided that redistributions of source code must retain the + * above copyright notice, this list of conditions and the following disclaimer. + * + * This software is provided `as is' by Distributed Processing Technology 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 Distributed Processing Technology 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 + * interruptions) 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 driver software, even if advised + * of the possibility of such damage. + * + */ + +#ifndef __OSD_UNIX_H +#define __OSD_UNIX_H + +/*File - OSD_UNIX.H */ +/*****************************************************************************/ +/* */ +/*Description: */ +/* */ +/* This file contains definitions for the UNIX OS dependent layer of the */ +/*DPT engine. */ +/* */ +/*Copyright Distributed Processing Technology, Corp. */ +/* 140 Candace Dr. */ +/* Maitland, Fl. 32751 USA */ +/* Phone: (407) 830-5522 Fax: (407) 260-5366 */ +/* All Rights Reserved */ +/* */ +/*Author: Bob Pasteur */ +/*Date: 5/28/93 */ +/* */ +/*Editors: */ +/* 3/7/96 salyzyn@dpt.com */ +/* Added BSDi extensions */ +/* 30/9/99 salyzyn@dpt.com */ +/* Added I2ORESCANCMD */ +/* 7/12/99 salyzyn@dpt.com */ +/* Added I2ORESETCMD */ +/* */ +/*Remarks: */ +/* */ +/* */ +/*****************************************************************************/ + +/* Definitions - Defines & Constants ---------------------------------------*/ + +#define DPT_TurnAroundKey 0x01 /* TurnAround Message Type for engine */ +#define DPT_EngineKey 0x02 /* Message Que and Type for engine */ +#define DPT_LoggerKey 0x03 /* Message Type For Logger */ +#define DPT_CommEngineKey 0x04 /* Message Que Type Created */ + +#define MSG_RECEIVE 0x40000000 /* Ored Into Logger PID For Return Msg */ + +#define ENGMSG_ECHO 0x00 /* Turnarround Echo Engine Message */ +#define ENGMSG_OPEN 0x01 /* Turnarround Open Engine Message */ +#define ENGMSG_CLOSE 0x02 /* Turnarround Close Engine Message */ + + /* Message Que Creation Flags */ + +#define MSG_URD 00400 +#define MSG_UWR 00200 +#define MSG_GRD 00040 +#define MSG_GWR 00020 +#define MSG_ORD 00004 +#define MSG_OWR 00002 +#define MSG_ALLRD 00444 +#define MSG_ALLWR 00222 + + /* Message Que Creation Flags */ + +#define SHM_URD 00400 +#define SHM_UWR 00200 +#define SHM_GRD 00040 +#define SHM_GWR 00020 +#define SHM_ORD 00004 +#define SHM_OWR 00002 +#define SHM_ALLRD 00444 +#define SHM_ALLWR 00222 + + /* Program Exit Codes */ + +#define ExitGoodStatus 0 +#define ExitBadParameter 1 +#define ExitSignalFail 3 +#define ExitMsqAllocFail 5 +#define ExitBuffAllocFail 6 +#define ExitMsgSendFail 8 +#define ExitMsgReceiveFail 9 + +#define ExitEngOpenFail 10 +#define ExitDuplicateEngine 11 + +#define ExitCommAllocFail 12 +#define ExitDuplicateCommEng 13 +#define ExitCommConnectFail 14 + +#ifndef MAX_HAS + +#define MAX_HAS 18 +#define MAX_NAME 100 + +#endif /* ifndef MAX_HAS */ + + +typedef struct { + uCHAR ConfigLength[4]; /* Len in bytes after this field. */ + uCHAR EATAsignature[4]; + uCHAR EATAversion; + uCHAR Flags1; + uCHAR PadLength[2]; + uCHAR HBA[4]; + uCHAR CPlength[4]; /* Command Packet Length */ + uCHAR SPlength[4]; /* Status Packet Length */ + uCHAR QueueSize[2]; /* Controller Que depth */ + uCHAR SG_Size[4]; + uCHAR Flags2; + uCHAR Reserved0; /* Reserved Field */ + uCHAR Flags3; + uCHAR ScsiValues; + uCHAR MaxLUN; /* Maximun LUN Supported */ + uCHAR Flags4; + uCHAR RaidNum; /* RAID HBA Number For Stripping */ + uCHAR Reserved3; /* Reserved Field */ + } DptReadConfig_t; + +#if defined ( _DPT_SOLARIS ) + +#include <sys/types.h> +#include <sys/ddidmareq.h> +#include <sys/mutex.h> +#include <sys/scsi/scsi.h> +//#define _KERNEL +#include <sys/dditypes.h> +#include <sys/ddi_impldefs.h> +#include <sys/scsi/impl/transport.h> +//#undef _KERNEL + +#undef MSG_DISCONNECT +#define MSG_DISCONNECT 0x11L + +#define EATAUSRCMD 1 +#define DPT_SIGNATURE 2 +#define DPT_NUMCTRLS 3 +#define DPT_CTRLINFO 4 +#define DPT_SYSINFO 5 +#define DPT_BLINKLED 6 +#define I2OUSRCMD 7 +//#define I2ORESCANCMD 8 /* Use DPT_IO_ACCESS instead */ +//#define I2ORESETCMD 9 /* Use DPT_IO_ACCESS instead */ + +#define DPT_MAX_DMA_SEGS 32 /* Max used Scatter/Gather seg */ + +struct dpt_sg { + paddr_t data_addr; + uLONG data_len; + }; + +typedef struct { + uSHORT NumHBAs; + uLONG IOAddrs[18]; + } GetHbaInfo_t; + +#elif defined(_DPT_DGUX) + +#ifndef _IOWR +# define _IOWR(x,y,z) (0x0fff3900|y) +#endif +#ifndef _IOW +# define _IOW(x,y,z) (0x0fff3900|y) +#endif +#ifndef _IOR +# define _IOR(x,y,z) (0x0fff3900|y) +#endif +#ifndef _IO +# define _IO(x,y) (0x0fff3900|y) +#endif +/* EATA PassThrough Command */ +#define EATAUSRCMD _IOWR('D',65,EATA_CP) +/* Get Signature Structure */ +#define DPT_SIGNATURE _IOR('D',67,dpt_sig_S) +/* Get Number Of DPT Adapters */ +#define DPT_NUMCTRLS _IOR('D',68,int) +/* Get Adapter Info Structure */ +#define DPT_CTRLINFO _IOR('D',69,CtrlInfo) +/* Get System Info Structure */ +#define DPT_SYSINFO _IOR('D',72,sysInfo_S) +/* Get Blink LED Code */ +#define DPT_BLINKLED _IOR('D',75,int) +/* Get Statistical information (if available) */ +#define DPT_STATS_INFO _IOR('D',80,STATS_DATA) +/* Clear the statistical information */ +#define DPT_STATS_CLEAR _IO('D',81) +/* Send an I2O command */ +#define I2OUSRCMD _IO('D',76) +/* Inform driver to re-acquire LCT information */ +#define I2ORESCANCMD _IO('D',77) +/* Inform driver to reset adapter */ +#define I2ORESETCMD _IO('D',78) + +#elif defined (SNI_MIPS) + /* Unix Ioctl Command definitions */ + +#define EATAUSRCMD (('D'<<8)|65) +#define DPT_DEBUG (('D'<<8)|66) +#define DPT_SIGNATURE (('D'<<8)|67) +#define DPT_NUMCTRLS (('D'<<8)|68) +#define DPT_CTRLINFO (('D'<<8)|69) +#define DPT_STATINFO (('D'<<8)|70) +#define DPT_CLRSTAT (('D'<<8)|71) +#define DPT_SYSINFO (('D'<<8)|72) +/* Set Timeout Value */ +#define DPT_TIMEOUT (('D'<<8)|73) +/* Get config Data */ +#define DPT_CONFIG (('D'<<8)|74) +/* Get config Data */ +#define DPT_BLINKLED (('D'<<8)|75) +/* Get Statistical information (if available) */ +#define DPT_STATS_INFO (('D'<<8)|80) +/* Clear the statistical information */ +#define DPT_STATS_CLEAR (('D'<<8)|81) +/* Send an I2O command */ +#define I2OUSRCMD (('D'<<8)|76) +/* Inform driver to re-acquire LCT information */ +#define I2ORESCANCMD (('D'<<8)|77) +/* Inform driver to reset adapter */ +#define I2ORESETCMD (('D'<<8)|78) + +#else + + /* Unix Ioctl Command definitions */ + +#ifdef _DPT_AIX + +#undef _IOWR +#undef _IOW +#undef _IOR +#undef _IO +#endif + +#ifndef _IOWR +# define _IOWR(x,y,z) (((x)<<8)|y) +#endif +#ifndef _IOW +# define _IOW(x,y,z) (((x)<<8)|y) +#endif +#ifndef _IOR +# define _IOR(x,y,z) (((x)<<8)|y) +#endif +#ifndef _IO +# define _IO(x,y) (((x)<<8)|y) +#endif +/* EATA PassThrough Command */ +#define EATAUSRCMD _IOWR('D',65,EATA_CP) +/* Set Debug Level If Enabled */ +#define DPT_DEBUG _IOW('D',66,int) +/* Get Signature Structure */ +#define DPT_SIGNATURE _IOR('D',67,dpt_sig_S) +#if defined __bsdi__ +#define DPT_SIGNATURE_PACKED _IOR('D',67,dpt_sig_S_Packed) +#endif +/* Get Number Of DPT Adapters */ +#define DPT_NUMCTRLS _IOR('D',68,int) +/* Get Adapter Info Structure */ +#define DPT_CTRLINFO _IOR('D',69,CtrlInfo) +/* Get Statistics If Enabled */ +#define DPT_STATINFO _IO('D',70) +/* Clear Stats If Enabled */ +#define DPT_CLRSTAT _IO('D',71) +/* Get System Info Structure */ +#define DPT_SYSINFO _IOR('D',72,sysInfo_S) +/* Set Timeout Value */ +#define DPT_TIMEOUT _IO('D',73) +/* Get config Data */ +#define DPT_CONFIG _IO('D',74) +/* Get Blink LED Code */ +#define DPT_BLINKLED _IOR('D',75,int) +/* Get Statistical information (if available) */ +#define DPT_STATS_INFO _IOR('D',80,STATS_DATA) +/* Clear the statistical information */ +#define DPT_STATS_CLEAR _IO('D',81) +/* Get Performance metrics */ +#define DPT_PERF_INFO _IOR('D',82,dpt_perf_t) +/* Send an I2O command */ +#define I2OUSRCMD _IO('D',76) +/* Inform driver to re-acquire LCT information */ +#define I2ORESCANCMD _IO('D',77) +/* Inform driver to reset adapter */ +#define I2ORESETCMD _IO('D',78) +#if defined _DPT_LINUX +/* See if the target is mounted */ +#define DPT_TARGET_BUSY _IOR('D',79, TARGET_BUSY_T) +#endif + + +#endif /* _DPT_SOLARIS else */ + + /* Adapter Flags Field Bit Definitions */ + +#define CTLR_INSTALLED 0x00000001 /* Adapter Was Installed */ +#define CTLR_DMA 0x00000002 /* DMA Supported */ +#define CTLR_OVERLAP 0x00000004 /* Overlapped Commands Support */ +#define CTLR_SECONDARY 0x00000008 /* I/O Address Not 0x1f0 */ +#define CTLR_BLINKLED 0x00000010 /* Adapter In Blink LED State */ +#define CTLR_HBACI 0x00000020 /* Cache Inhibit Supported */ +#define CTLR_CACHE 0x00000040 /* Adapter Has Cache */ +#define CTLR_SANE 0x00000080 /* Adapter Functioning OK */ +#define CTLR_BUS_QUIET 0x00000100 /* Bus Quite On This Adapter */ +#define CTLR_ABOVE_16 0x00000200 /* Support For Mem. Above 16 MB */ +#define CTLR_SCAT_GATH 0x00000400 /* Scatter Gather Supported */ + + +/* Definitions - Structure & Typedef ---------------------------------------*/ + +typedef struct { + uLONG MsgID; + DPT_TAG_T engineTag; + DPT_TAG_T targetTag; + DPT_MSG_T engEvent; + long BufferID; + uLONG FromEngBuffOffset; + uLONG callerID; + DPT_RTN_T result; + uLONG timeOut; + } MsgHdr; + +#define MsgDataSize sizeof(MsgHdr) - 4 + +#ifndef SNI_MIPS + +/*-------------------------------------------------------------------------*/ +/* EATA Command Packet definition */ +/*-------------------------------------------------------------------------*/ + +typedef struct EATACommandPacket { + +#ifdef _DPT_UNIXWARE + + uCHAR EataID[4]; + uINT EataCmd; + uCHAR *CmdBuffer; + +#endif /* _DPT_UNIXWARE */ + +#ifdef _DPT_AIX + + uCHAR HbaTargetID; + uCHAR HbaLUN; + +#endif /* _DPT_AIX */ + + uCHAR cp_Flags1; /* Command Flags */ + uCHAR cp_Req_Len; /* AutoRequestSense Data length. */ + uCHAR cp_Resv1[3]; /* Reserved Fields */ + uCHAR cp_Flags2; + uCHAR cp_Flags3; + uCHAR cp_ScsiAddr; + uCHAR cp_msg0; /* Identify and Disconnect Message. */ + uCHAR cp_msg1; + uCHAR cp_msg2; + uCHAR cp_msg3; + uCHAR cp_cdb[12]; /* SCSI cdb for command. */ + uLONG cp_dataLen; /* Data length in Bytes for command. */ + uLONG cp_Vue; /* Vendor Unique Area */ + uCHAR *cp_DataAddr; /* Data Address For The Command. */ + uCHAR *cp_SpAddr; /* Status Packet Physical Address. */ + uCHAR *cp_SenseAddr; /* AutoRequestSense Data Phy Address. */ + +#ifdef _DPT_SOLARIS + + uCHAR HostStatus; + uCHAR TargetStatus; + uCHAR CdbLength; + uCHAR SG_Size; + struct scsi_arq_status ReqSenseData; + struct dpt_sg SG_List[DPT_MAX_DMA_SEGS]; + union { + char *b_scratch; + struct scsi_cmd *b_ownerp; + } cc; + paddr_t ccb_paddr; + uSHORT IOAddress; + +#else /* _DPT_SOLARIS */ + + uLONG TimeOut ; + uCHAR HostStatus; + uCHAR TargetStatus; + uCHAR Retries; + +#endif /* _DPT_SOLARIS else */ + + } EATA_CP; +#endif // SNI_MIPS + + + /* Control Flags 1 Definitions */ + +#define SCSI_RESET 0x01 /* Cause a SCSI Bus reset on the cmd */ +#define HBA_INIT 0x02 /* Cause Controller to reInitialize */ +#define AUTO_REQ_SENSE 0x04 /* Do Auto Request Sense on errors */ +#define SCATTER_GATHER 0x08 /* Data Ptr points to a SG Packet */ +#define INTERPRET 0x20 /* Interpret the SCSI cdb of own use */ +#define DATA_OUT 0x04 /* Data Out phase with command */ +#define DATA_IN 0x08 /* Data In phase with command */ + + /* Control Flags 2 Definitions */ + +#define FIRMWARE_NESTED 0x01 + + + /* Control Flags 3 Definitions */ + +#define PHYSICAL_UNIT 0x01 /* Send Command Directly To Target */ +#define IAT 0x02 /* Inhibit Address Translation */ +#define HBACI 0x04 /* Inhibit Caching */ + + + /* Structure Returned From Get Controller Info */ + +typedef struct { + + uCHAR state; /* Operational state */ + uCHAR id; /* Host adapter SCSI id */ + int vect; /* Interrupt vector number */ + int base; /* Base I/O address */ + int njobs; /* # of jobs sent to HA */ + int qdepth; /* Controller queue depth. */ + int wakebase; /* mpx wakeup base index. */ + uLONG SGsize; /* Scatter/Gather list size. */ + unsigned heads; /* heads for drives on cntlr. */ + unsigned sectors; /* sectors for drives on cntlr. */ + uCHAR do_drive32; /* Flag for Above 16 MB Ability */ + uCHAR BusQuiet; /* SCSI Bus Quiet Flag */ + char idPAL[4]; /* 4 Bytes Of The ID Pal */ + uCHAR primary; /* 1 For Primary, 0 For Secondary */ + uCHAR eataVersion; /* EATA Version */ + uLONG cpLength; /* EATA Command Packet Length */ + uLONG spLength; /* EATA Status Packet Length */ + uCHAR drqNum; /* DRQ Index (0,5,6,7) */ + uCHAR flag1; /* EATA Flags 1 (Byte 9) */ + uCHAR flag2; /* EATA Flags 2 (Byte 30) */ + + } CtrlInfo; + +#ifndef SNI_MIPS +#ifdef _DPT_UNIXWARE + +typedef struct { + + uINT state; /* Operational state */ + uCHAR id[4]; /* Host adapter SCSI id */ + uINT vect; /* Interrupt vector number */ + uLONG base; /* Base I/O address */ + int ha_max_jobs; /* Max number of Active Jobs */ + uLONG ha_cacheParams; + int ha_nbus; /* Number Of Busses on HBA */ + int ha_ntargets; /* Number Of Targets Supported */ + int ha_nluns; /* Number Of LUNs Supported */ + int ha_tshift; /* Shift value for target */ + int ha_bshift; /* Shift value for bus */ + uINT ha_npend; /* # of jobs sent to HA */ + int ha_active_jobs; /* Number Of Active Jobs */ + + } HbaInfo; + + /* SDI ioctl prefix for hba specific ioctl's */ + +#define SDI_IOC (('S'<<24)|('D'<<16)|('I'<<8)) + +#define SDI_HBANAME ((SDI_IOC)|0x14) /* Get HBA module name */ +#define SDI_SEND 0x0081 /* Send a SCSI command */ + +#else + +typedef struct { + + uLONG flags; /* Operational State Flags */ + uCHAR id[4]; /* Host Adapter SCSI ID */ + int vect; /* Interrupt Vector Number */ + int base; /* Base I/O Address */ + int njobs; /* # Of CCBs Outstanding To HBA */ + int qdepth; /* Controller Queue depth. */ + uLONG SGsize; /* Scatter/Gather List Size. */ + char idPAL[4]; /* 4 Bytes Of The ID Pal */ + uCHAR eataVersion; /* EATA Version */ + uLONG cpLength; /* EATA Command Packet Length */ + uLONG spLength; /* EATA Status Packet Length */ + uCHAR drqNum; /* DRQ Index (0,5,6,7) */ + uCHAR eataflag1; /* EATA Flags 1 (Byte 9) */ + uCHAR eataflag2; /* EATA Flags 2 (Byte 30) */ + uCHAR maxChannel; /* Maximum Channel Number */ + uCHAR maxID; /* Maximum Target ID */ + uCHAR maxLUN; /* Maximum LUN */ + uCHAR HbaBusType; /* HBA Bus Type, EISA, PCI, etc */ + uCHAR RaidNum; /* Host Adapter RAID Number */ + + } HbaInfo; + +#endif /* _DPT_UNIXWARE */ +#endif // SNI_MIPS + + +#ifdef _DPT_AIX + +/* + * DPT Host Adapter config information structure - this structure contains + * configuration information about an adapter. It is imbedded into the + * dpt_ctl structure. + */ + +typedef struct dpt_cfg { + uchar flags; /* Operational state flags */ + uchar id[4]; /* Host adapter SCSI IDs */ + int vect; /* Interrupt vector number */ + ulong base_addr; /* Base I/O address */ + int qdepth; /* Controller queue depth. */ + ulong SGsize; /* Max scatter/gather list sz */ + ulong SGmax; /* Max s/g we can use per req */ + uchar eataVersion; /* EATA version */ + ushort cpPadLen; /* # of pad bytes sent to HA for + PIO commands */ + ulong cpLength; /* EATA Command Packet length */ + ulong spLength; /* EATA Status Packet length */ + uchar eataflag1; /* EATA Flags 1 (Byte 9) */ + uchar eataflag2; /* EATA Flags 2 (Byte 30) */ + uchar maxChan; /* Maximum Channel number */ + uchar maxID; /* Maximum target ID */ + uchar maxLUN; /* Maximum LUN */ + uchar HbaBusType; /* HBA bus type, EISA, PCI, etc */ + uchar RaidNum; /* Host adapter RAID number */ +} DptCfg_t; + +#endif /* _DPT_AIX */ + + +#define MAX_ELEMENT_COUNT 64 +#define MAX_BUCKET_COUNT 10 + +/* + * DPT statistics structure definitions + */ +typedef struct IO_SIZE_STATS +{ + uLONG TotalIoCount; + uLONG IoCountRead; + uLONG IoCountReadSg; + uLONG IoCountWrite; + uLONG IoCountWriteSg; + uLONG UnalignedIoAddress; + uLONG SgElementCount[MAX_ELEMENT_COUNT]; + +} IO_SIZE_STATS_T, *pIO_SIZE_STATS_T; + +typedef struct STATS_DATA +{ + uLONG TotalIoCount; + uLONG TotalUnCachedIoCount; + uLONG MaxOutstandingIoCount; + uLONG CurrentOutstandingIoCount; + uLONG OutstandingIoRunningCount; + uLONG UnalignedPktCount; + uLONG UnalignedSgCount; + uLONG NonPageListAddressSgCount; + uLONG MaxMessagesPerInterrupt; + IO_SIZE_STATS_T IoSize[MAX_BUCKET_COUNT]; + +} STATS_DATA_T, *pSTATS_DATA_T; + +typedef struct TARGET_BUSY +{ + uLONG channel; + uLONG id; + uLONG lun; + uLONG isBusy; +} TARGET_BUSY_T; +#endif /* __OSD_UNIX_H */ diff --git a/sys/dev/asr/osd_util.h b/sys/dev/asr/osd_util.h new file mode 100644 index 000000000000..fb232c7f1315 --- /dev/null +++ b/sys/dev/asr/osd_util.h @@ -0,0 +1,367 @@ +/* $FreeBSD$ */ +/* BSDI osd_util.h,v 1.8 1998/06/03 19:14:58 karels Exp */ + +/* + * Copyright (c) 1996-1999 Distributed Processing Technology Corporation + * All rights reserved. + * + * Redistribution and use in source form, with or without modification, are + * permitted provided that redistributions of source code must retain the + * above copyright notice, this list of conditions and the following disclaimer. + * + * This software is provided `as is' by Distributed Processing Technology 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 Distributed Processing Technology 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 + * interruptions) 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 driver software, even if advised + * of the possibility of such damage. + * + */ + +#ifndef __OSD_UTIL_H +#define __OSD_UTIL_H + +/*File - OSD_UTIL.H + **************************************************************************** + * + *Description: + * + * This file contains defines and function prototypes that are + *operating system dependent. The resources defined in this file + *are not specific to any particular application. + * + *Copyright Distributed Processing Technology, Corp. + * 140 Candace Dr. + * Maitland, Fl. 32751 USA + * Phone: (407) 830-5522 Fax: (407) 260-5366 + * All Rights Reserved + * + *Author: Doug Anderson + *Date: 1/7/94 + * + *Editors: + * + *Remarks: + * + * + *****************************************************************************/ + + +/*Definitions - Defines & Constants ----------------------------------------- */ + +/*----------------------------- */ +/* Operating system selections: */ +/*----------------------------- */ + +/*#define _DPT_MSDOS */ +/*#define _DPT_WIN_3X */ +/*#define _DPT_WIN_4X */ +/*#define _DPT_WIN_NT */ +/*#define _DPT_NETWARE */ +/*#define _DPT_OS2 */ +/*#define _DPT_SCO */ +/*#define _DPT_UNIXWARE */ +/*#define _DPT_SOLARIS */ +/*#define _DPT_NEXTSTEP */ +/*#define _DPT_BANYAN */ + +/*-------------------------------- */ +/* Include the OS specific defines */ +/*-------------------------------- */ + +/*#define OS_SELECTION From Above List */ +/*#define SEMAPHORE_T ??? */ +/*#define DLL_HANDLE_T ??? */ + +#if (defined(KERNEL) && defined(__bsdi__)) +# include "i386/isa/dpt_osd_defs.h" +#elif ((defined(KERNEL) || defined(_KERNEL)) && defined(__FreeBSD__)) +# if (KERN_VERSION < 3) +# include "i386/isa/dpt_osd_defs.h" +# else +# include "dev/asr/osd_defs.h" +# endif +#else +# include "osd_defs.h" +#endif + +#ifndef DPT_UNALIGNED + #define DPT_UNALIGNED +#endif + +#ifndef DPT_EXPORT + #define DPT_EXPORT +#endif + +#ifndef DPT_IMPORT + #define DPT_IMPORT +#endif + +#ifndef DPT_RUNTIME_IMPORT + #define DPT_RUNTIME_IMPORT DPT_IMPORT +#endif + +/*--------------------- */ +/* OS dependent defines */ +/*--------------------- */ + +#if defined (_DPT_MSDOS) || defined (_DPT_WIN_3X) + #define _DPT_16_BIT +#else + #define _DPT_32_BIT +#endif + +#if defined (_DPT_SCO) || defined (_DPT_UNIXWARE) || defined (_DPT_SOLARIS) || defined (_DPT_AIX) || defined (SNI_MIPS) || defined (_DPT_BSDI) || defined (_DPT_FREE_BSD) || defined(_DPT_LINUX) + #define _DPT_UNIX +#endif + +#if defined (_DPT_WIN_3x) || defined (_DPT_WIN_4X) || defined (_DPT_WIN_NT) \ + || defined (_DPT_OS2) + #define _DPT_DLL_SUPPORT +#endif + +#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X) && !defined (_DPT_NETWARE) + #define _DPT_PREEMPTIVE +#endif + +#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X) + #define _DPT_MULTI_THREADED +#endif + +#if !defined (_DPT_MSDOS) + #define _DPT_MULTI_TASKING +#endif + + /* These exist for platforms that */ + /* chunk when accessing mis-aligned */ + /* data */ +#if defined (SNI_MIPS) || defined (_DPT_SOLARIS) + #if defined (_DPT_BIG_ENDIAN) + #if !defined (_DPT_STRICT_ALIGN) + #define _DPT_STRICT_ALIGN + #endif + #endif +#endif + + /* Determine if in C or C++ mode */ +#ifdef __cplusplus + #define _DPT_CPP +#else + #define _DPT_C +#endif + +/*-------------------------------------------------------------------*/ +/* Under Solaris the compiler refuses to accept code like: */ +/* { {"DPT"}, 0, NULL .... }, */ +/* and complains about the {"DPT"} part by saying "cannot use { } */ +/* to initialize char*". */ +/* */ +/* By defining these ugly macros we can get around this and also */ +/* not have to copy and #ifdef large sections of code. I know that */ +/* these macros are *really* ugly, but they should help reduce */ +/* maintenance in the long run. */ +/* */ +/* In the meantime, just pray that we can all move to Win32 as soon */ +/* as possible... */ +/*-------------------------------------------------------------------*/ +#if !defined (DPTSQO) + #if defined (_DPT_SOLARIS) + #define DPTSQO + #define DPTSQC + #else + #define DPTSQO { + #define DPTSQC } + #endif /* solaris */ +#endif /* DPTSQO */ + + +/*---------------------- */ +/* OS dependent typedefs */ +/*---------------------- */ + +#if defined (_DPT_MSDOS) || defined (_DPT_SCO) + #define BYTE unsigned char + #define WORD unsigned short +#endif + +#ifndef _DPT_TYPEDEFS + #define _DPT_TYPEDEFS + typedef unsigned char uCHAR; + typedef unsigned short uSHORT; + typedef unsigned int uINT; + typedef unsigned long uLONG; + + typedef union { + uCHAR u8[4]; + uSHORT u16[2]; + uLONG u32; + } access_U; +#endif + +#if !defined (NULL) + #define NULL 0 +#endif + + +/*Prototypes - function ----------------------------------------------------- */ + +#ifdef __cplusplus + extern "C" { /* Declare all these functions as "C" functions */ +#endif + +/*------------------------ */ +/* Byte reversal functions */ +/*------------------------ */ + + /* Reverses the byte ordering of a 2 byte variable */ +#if (!defined(osdSwap2)) + uSHORT osdSwap2(DPT_UNALIGNED uSHORT *); +#endif // !osdSwap2 + + /* Reverses the byte ordering of a 4 byte variable and shifts left 8 bits */ +#if (!defined(osdSwap3)) + uLONG osdSwap3(DPT_UNALIGNED uLONG *); +#endif // !osdSwap3 + + +#ifdef _DPT_NETWARE + #include "novpass.h" /* For DPT_Bswapl() prototype */ + /* Inline the byte swap */ + #ifdef __cplusplus + inline uLONG osdSwap4(uLONG *inLong) { + return *inLong = DPT_Bswapl(*inLong); + } + #else + #define osdSwap4(inLong) DPT_Bswapl(inLong) + #endif // cplusplus +#else + /* Reverses the byte ordering of a 4 byte variable */ +# if (!defined(osdSwap4)) + uLONG osdSwap4(DPT_UNALIGNED uLONG *); +# endif // !osdSwap4 + + /* The following functions ALWAYS swap regardless of the * + * presence of DPT_BIG_ENDIAN */ + + uSHORT trueSwap2(DPT_UNALIGNED uSHORT *); + uLONG trueSwap4(DPT_UNALIGNED uLONG *); + +#endif // netware + + +/*-------------------------------------* + * Network order swap functions * + * * + * These functions/macros will be used * + * by the structure insert()/extract() * + * functions. * + * + * We will enclose all structure * + * portability modifications inside * + * #ifdefs. When we are ready, we * + * will #define DPT_PORTABLE to begin * + * using the modifications. * + *-------------------------------------*/ +uLONG netSwap4(uLONG val); + +#if defined (_DPT_BIG_ENDIAN) + +// for big-endian we need to swap + +#ifndef NET_SWAP_2 +#define NET_SWAP_2(x) (((x) >> 8) | ((x) << 8)) +#endif // NET_SWAP_2 + +#ifndef NET_SWAP_4 +#define NET_SWAP_4(x) netSwap4((x)) +#endif // NET_SWAP_4 + +#else + +/* for little-endian we don't need to do anything */ + +#ifndef NET_SWAP_2 +#define NET_SWAP_2(x) (x) +#endif // NET_SWAP_2 + +#ifndef NET_SWAP_4 +#define NET_SWAP_4(x) (x) +#endif // NET_SWAP_4 + +#endif // big endian + + + +/*----------------------------------- */ +/* Run-time loadable module functions */ +/*----------------------------------- */ + + /* Loads the specified run-time loadable DLL */ +DLL_HANDLE_T osdLoadModule(uCHAR *); + /* Unloads the specified run-time loadable DLL */ +uSHORT osdUnloadModule(DLL_HANDLE_T); + /* Returns a pointer to a function inside a run-time loadable DLL */ +void * osdGetFnAddr(DLL_HANDLE_T,uCHAR *); + +/*--------------------------------------- */ +/* Mutually exclusive semaphore functions */ +/*--------------------------------------- */ + + /* Create a named semaphore */ +SEMAPHORE_T osdCreateNamedSemaphore(char *); + /* Create a mutually exlusive semaphore */ +SEMAPHORE_T osdCreateSemaphore(void); + /* create an event semaphore */ +SEMAPHORE_T osdCreateEventSemaphore(void); + /* create a named event semaphore */ +SEMAPHORE_T osdCreateNamedEventSemaphore(char *); + + /* Destroy the specified mutually exclusive semaphore object */ +uSHORT osdDestroySemaphore(SEMAPHORE_T); + /* Request access to the specified mutually exclusive semaphore */ +uLONG osdRequestSemaphore(SEMAPHORE_T,uLONG); + /* Release access to the specified mutually exclusive semaphore */ +uSHORT osdReleaseSemaphore(SEMAPHORE_T); + /* wait for a event to happen */ +uLONG osdWaitForEventSemaphore(SEMAPHORE_T, uLONG); + /* signal an event */ +uLONG osdSignalEventSemaphore(SEMAPHORE_T); + /* reset the event */ +uLONG osdResetEventSemaphore(SEMAPHORE_T); + +/*----------------- */ +/* Thread functions */ +/*----------------- */ + + /* Releases control to the task switcher in non-preemptive */ + /* multitasking operating systems. */ +void osdSwitchThreads(void); + + /* Starts a thread function */ +uLONG osdStartThread(void *,void *); + +/* what is my thread id */ +uLONG osdGetThreadID(void); + +/* wakes up the specifed thread */ +void osdWakeThread(uLONG); + +/* osd sleep for x miliseconds */ +void osdSleep(uLONG); + +#define DPT_THREAD_PRIORITY_LOWEST 0x00 +#define DPT_THREAD_PRIORITY_NORMAL 0x01 +#define DPT_THREAD_PRIORITY_HIGHEST 0x02 + +uCHAR osdSetThreadPriority(uLONG tid, uCHAR priority); + +#ifdef __cplusplus + } /* end the xtern "C" declaration */ +#endif + +#endif /* osd_util_h */ diff --git a/sys/dev/asr/sys_info.h b/sys/dev/asr/sys_info.h new file mode 100644 index 000000000000..41fba378c554 --- /dev/null +++ b/sys/dev/asr/sys_info.h @@ -0,0 +1,484 @@ +/* $FreeBSD$ */ +/* BSDI sys_info.h,v 1.6 1998/06/03 19:14:59 karels Exp */ + +/* + * Copyright (c) 1996-1999 Distributed Processing Technology Corporation + * All rights reserved. + * + * Redistribution and use in source form, with or without modification, are + * permitted provided that redistributions of source code must retain the + * above copyright notice, this list of conditions and the following disclaimer. + * + * This software is provided `as is' by Distributed Processing Technology 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 Distributed Processing Technology 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 + * interruptions) 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 driver software, even if advised + * of the possibility of such damage. + * + */ + +#ifndef __SYS_INFO_H +#define __SYS_INFO_H + +/*File - SYS_INFO.H + **************************************************************************** + * + *Description: + * + * This file contains structure definitions for the OS dependent + *layer system information buffers. + * + *Copyright Distributed Processing Technology, Corp. + * 140 Candace Dr. + * Maitland, Fl. 32751 USA + * Phone: (407) 830-5522 Fax: (407) 260-5366 + * All Rights Reserved + * + *Author: Don Kemper + *Date: 5/10/94 + * + *Editors: + * + *Remarks: + * + * + *****************************************************************************/ + + +/*Include Files ------------------------------------------------------------- */ + +#if (defined(KERNEL) && defined(__bsdi__)) +# include "i386/isa/dpt_osd_util.h" +#elif ((defined(KERNEL) || defined(_KERNEL)) && defined(__FreeBSD__)) +# if (KERN_VERSION < 3) +# include "i386/isa/dpt_osd_util.h" +# else +# include "dev/asr/osd_util.h" +# endif +#else +# include "osd_util.h" +#endif + +#ifndef NO_PACK +#if defined (_DPT_AIX) +#pragma options align=packed +#else +#pragma pack(1) +#endif /* aix */ +#endif // no unpack + + +/*struct - driveParam_S - start + *=========================================================================== + * + *Description: + * + * This structure defines the drive parameters seen during + *booting. + * + *---------------------------------------------------------------------------*/ + +#ifdef __cplusplus + struct driveParam_S { +#else + typedef struct { +#endif + + uSHORT cylinders; /* Upto 1024 */ + uCHAR heads; /* Upto 255 */ + uCHAR sectors; /* Upto 63 */ + +#ifdef __cplusplus + +//---------- Portability Additions ----------- in sp_sinfo.cpp +#ifdef DPT_PORTABLE + uSHORT netInsert(dptBuffer_S *buffer); + uSHORT netExtract(dptBuffer_S *buffer); +#endif // DPT PORTABLE +//-------------------------------------------- + + }; +#else + } driveParam_S; +#endif +/*driveParam_S - end */ + + +/*struct - sysInfo_S - start + *=========================================================================== + * + *Description: + * + * This structure defines the command system information that + *should be returned by every OS dependent layer. + * + *---------------------------------------------------------------------------*/ + +/*flags - bit definitions */ +#define SI_CMOS_Valid 0x0001 +#define SI_NumDrivesValid 0x0002 +#define SI_ProcessorValid 0x0004 +#define SI_MemorySizeValid 0x0008 +#define SI_DriveParamsValid 0x0010 +#define SI_SmartROMverValid 0x0020 +#define SI_OSversionValid 0x0040 +#define SI_OSspecificValid 0x0080 /* 1 if OS structure returned */ +#define SI_BusTypeValid 0x0100 + +#define SI_ALL_VALID 0x0FFF /* All Std SysInfo is valid */ +#define SI_NO_SmartROM 0x8000 + +/*busType - definitions */ +#define SI_ISA_BUS 0x00 +#define SI_MCA_BUS 0x01 +#define SI_EISA_BUS 0x02 +#define SI_PCI_BUS 0x04 + +#ifdef __cplusplus + struct sysInfo_S { +#else + typedef struct { +#endif + + uCHAR drive0CMOS; /* CMOS Drive 0 Type */ + uCHAR drive1CMOS; /* CMOS Drive 1 Type */ + uCHAR numDrives; /* 0040:0075 contents */ + uCHAR processorFamily; /* Same as DPTSIG's definition */ + uCHAR processorType; /* Same as DPTSIG's definition */ + uCHAR smartROMMajorVersion; + uCHAR smartROMMinorVersion; /* SmartROM version */ + uCHAR smartROMRevision; + uSHORT flags; /* See bit definitions above */ + uSHORT conventionalMemSize; /* in KB */ + uLONG extendedMemSize; /* in KB */ + uLONG osType; /* Same as DPTSIG's definition */ + uCHAR osMajorVersion; + uCHAR osMinorVersion; /* The OS version */ + uCHAR osRevision; +#ifdef _SINIX_ADDON + uCHAR busType; /* See defininitions above */ + uSHORT osSubRevision; + uCHAR pad[2]; /* For alignment */ +#else + uCHAR osSubRevision; + uCHAR busType; /* See defininitions above */ + uCHAR pad[3]; /* For alignment */ +#endif + driveParam_S drives[16]; /* SmartROM Logical Drives */ + +#ifdef __cplusplus + +//---------- Portability Additions ----------- in sp_sinfo.cpp +#ifdef DPT_PORTABLE + uSHORT netInsert(dptBuffer_S *buffer); + uSHORT netExtract(dptBuffer_S *buffer); +#endif // DPT PORTABLE +//-------------------------------------------- + + }; +#else + } sysInfo_S; +#endif +/*sysInfo_S - end */ + + +/*struct - DOS_Info_S - start + *=========================================================================== + * + *Description: + * + * This structure defines the system information specific to a + *DOS workstation. + * + *---------------------------------------------------------------------------*/ + +/*flags - bit definitions */ +#define DI_DOS_HIGH 0x01 /* DOS is loaded high */ +#define DI_DPMI_VALID 0x02 /* DPMI version is valid */ + +#ifdef __cplusplus + struct DOS_Info_S { +#else + typedef struct { +#endif + + uCHAR flags; /* See bit definitions above */ + uSHORT driverLocation; /* SmartROM BIOS address */ + uSHORT DOS_version; + uSHORT DPMI_version; + +#ifdef __cplusplus + +//---------- Portability Additions ----------- in sp_sinfo.cpp +#ifdef DPT_PORTABLE + uSHORT netInsert(dptBuffer_S *buffer); + uSHORT netExtract(dptBuffer_S *buffer); +#endif // DPT PORTABLE +//-------------------------------------------- + + }; +#else + } DOS_Info_S; +#endif +/*DOS_Info_S - end */ + + +/*struct - Netware_Info_S - start + *=========================================================================== + * + *Description: + * + * This structure defines the system information specific to a + *Netware machine. + * + *---------------------------------------------------------------------------*/ + +#ifdef __cplusplus + struct Netware_Info_S { +#else + typedef struct { +#endif + + uCHAR driverName[13]; /* ie PM12NW31.DSK */ + uCHAR serverName[48]; + uCHAR netwareVersion; /* The Netware OS version */ + uCHAR netwareSubVersion; + uCHAR netwareRevision; + uSHORT maxConnections; /* Probably 250 or 1000 */ + uSHORT connectionsInUse; + uSHORT maxVolumes; + uCHAR unused; + uCHAR SFTlevel; + uCHAR TTSlevel; + + uCHAR clibMajorVersion; /* The CLIB.NLM version */ + uCHAR clibMinorVersion; + uCHAR clibRevision; + +#ifdef __cplusplus + +//---------- Portability Additions ----------- in sp_sinfo.cpp +#ifdef DPT_PORTABLE + uSHORT netInsert(dptBuffer_S *buffer); + uSHORT netExtract(dptBuffer_S *buffer); +#endif // DPT PORTABLE +//-------------------------------------------- + + }; +#else + } Netware_Info_S; +#endif +/*Netware_Info_S - end */ + + +/*struct - OS2_Info_S - start + *=========================================================================== + * + *Description: + * + * This structure defines the system information specific to an + *OS/2 machine. + * + *---------------------------------------------------------------------------*/ + +#ifdef __cplusplus + struct OS2_Info_S { +#else + typedef struct { +#endif + + uCHAR something; + +#ifdef __cplusplus + +//---------- Portability Additions ----------- in sp_sinfo.cpp +#ifdef DPT_PORTABLE + uSHORT netInsert(dptBuffer_S *buffer); + uSHORT netExtract(dptBuffer_S *buffer); +#endif // DPT PORTABLE +//-------------------------------------------- + + }; +#else + } OS2_Info_S; +#endif +/*OS2_Info_S - end */ + + +/*struct - WinNT_Info_S - start + *=========================================================================== + * + *Description: + * + * This structure defines the system information specific to a + *Windows NT machine. + * + *---------------------------------------------------------------------------*/ + +#ifdef __cplusplus + struct WinNT_Info_S { +#else + typedef struct { +#endif + + uCHAR something; + +#ifdef __cplusplus + +//---------- Portability Additions ----------- in sp_sinfo.cpp +#ifdef DPT_PORTABLE + uSHORT netInsert(dptBuffer_S *buffer); + uSHORT netExtract(dptBuffer_S *buffer); +#endif // DPT PORTABLE +//-------------------------------------------- + + }; +#else + } WinNT_Info_S; +#endif +/*WinNT_Info_S - end */ + + +/*struct - SCO_Info_S - start + *=========================================================================== + * + *Description: + * + * This structure defines the system information specific to an + *SCO UNIX machine. + * + *---------------------------------------------------------------------------*/ + +#ifdef __cplusplus + struct SCO_Info_S { +#else + typedef struct { +#endif + + uCHAR something; + +#ifdef __cplusplus + +//---------- Portability Additions ----------- in sp_sinfo.cpp +#ifdef DPT_PORTABLE + uSHORT netInsert(dptBuffer_S *buffer); + uSHORT netExtract(dptBuffer_S *buffer); +#endif // DPT PORTABLE +//-------------------------------------------- + + }; +#else + } SCO_Info_S; +#endif +/*SCO_Info_S - end */ + + +/*struct - USL_Info_S - start + *=========================================================================== + * + *Description: + * + * This structure defines the system information specific to a + *USL UNIX machine. + * + *---------------------------------------------------------------------------*/ + +#ifdef __cplusplus + struct USL_Info_S { +#else + typedef struct { +#endif + + uCHAR something; + +#ifdef __cplusplus + +//---------- Portability Additions ----------- in sp_sinfo.cpp +#ifdef DPT_PORTABLE + uSHORT netInsert(dptBuffer_S *buffer); + uSHORT netExtract(dptBuffer_S *buffer); +#endif // DPT PORTABLE +//-------------------------------------------- + + }; +#else + } USL_Info_S; +#endif +/*USL_Info_S - end */ + + + /* Restore default structure packing */ +#ifndef NO_UNPACK +#if defined (_DPT_AIX) +#pragma options align=reset +#elif defined (UNPACK_FOUR) +#pragma pack(4) +#else +#pragma pack() +#endif /* aix */ +#endif // no unpack + +#ifdef DPT_MEASURE_PERFORMANCE +typedef struct dpt_metrics { + u_int32_t command_count[256]; /* We assume MAX 256 SCSI commands */ + u_int32_t max_command_time[256]; + u_int32_t min_command_time[256]; + + u_int32_t min_intr_time; + u_int32_t max_intr_time; + u_int32_t max_intr_gap; + u_int32_t max_ht_time; + u_int32_t aborted_interrupts; + u_int32_t spurious_interrupts; + u_int32_t aborted_requests; + u_int32_t retried_requests; + + u_int32_t max_waiting_count; + u_int32_t max_submit_count; + u_int32_t max_complete_count; + + u_int32_t min_waiting_time; + u_int32_t min_submit_time; + u_int32_t min_complete_time; + + u_int32_t max_waiting_time; + u_int32_t max_submit_time; + u_int32_t max_complete_time; + + u_int32_t command_collisions; + u_int32_t command_too_busy; + u_int32_t max_eata_tries; + u_int32_t min_eata_tries; + + u_int32_t read_by_size_count[10]; + u_int32_t write_by_size_count[10]; + u_int32_t read_by_size_min_time[10]; + u_int32_t read_by_size_max_time[10]; + struct timeval read_by_size_total_time[10]; + u_int32_t write_by_size_min_time[10]; + u_int32_t write_by_size_max_time[10]; + struct timeval write_by_size_total_time[10]; + +#define SIZE_512 0 +#define SIZE_1K 1 +#define SIZE_2K 2 +#define SIZE_4K 3 +#define SIZE_8K 4 +#define SIZE_16K 5 +#define SIZE_32K 6 +#define SIZE_64K 7 +#define SIZE_BIGGER 8 +#define SIZE_OTHER 9 + + struct timeval intr_started; +} dpt_perf_t; +#endif + +#endif // __SYS_INFO_H + diff --git a/sys/dev/awi/awivar.h b/sys/dev/awi/awivar.h new file mode 100644 index 000000000000..8e86f841a006 --- /dev/null +++ b/sys/dev/awi/awivar.h @@ -0,0 +1,222 @@ +/* $NetBSD: awivar.h,v 1.12 2000/07/21 04:48:56 onoe Exp $ */ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Bill Sommerfeld + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* timer values in msec */ +#define AWI_SELFTEST_TIMEOUT 5000 +#define AWI_CMD_TIMEOUT 2000 +#define AWI_LOCKOUT_TIMEOUT 50 +#define AWI_ASCAN_DURATION 100 +#define AWI_ASCAN_WAIT 3000 +#define AWI_PSCAN_DURATION 200 +#define AWI_PSCAN_WAIT 5000 +#define AWI_TRANS_TIMEOUT 2000 + +#define AWI_NTXBUFS 4 +#define AWI_MAX_KEYLEN 16 + +enum awi_status { + AWI_ST_INIT, + AWI_ST_SCAN, + AWI_ST_SETSS, + AWI_ST_SYNC, + AWI_ST_AUTH, + AWI_ST_ASSOC, + AWI_ST_RUNNING +}; + +struct awi_bss +{ + TAILQ_ENTRY(awi_bss) list; + u_int8_t esrc[ETHER_ADDR_LEN]; + u_int8_t chanset; /* channel set to use */ + u_int8_t pattern; /* hop pattern to use */ + u_int8_t index; /* index to use */ + u_int8_t rssi; /* strength of this beacon */ + u_int16_t dwell_time; /* dwell time */ + u_int8_t timestamp[8]; /* timestamp of this bss */ + u_int8_t bssid[ETHER_ADDR_LEN]; + u_int16_t capinfo; + u_int32_t rxtime; /* unit's local time */ + u_int16_t interval; /* beacon interval */ + u_int8_t txrate; + u_int8_t fails; + u_int8_t essid[IEEE80211_NWID_LEN + 2]; +}; + +struct awi_wep_algo { + char *awa_name; + int (*awa_ctxlen) __P((void)); + void (*awa_setkey) __P((void *, u_char *, int)); + void (*awa_encrypt) __P((void *, u_char *, u_char *, int)); + void (*awa_decrypt) __P((void *, u_char *, u_char *, int)); +}; + +struct awi_softc +{ +#ifdef __NetBSD__ + struct device sc_dev; + struct ethercom sc_ec; + void *sc_ih; /* interrupt handler */ +#endif +#ifdef __FreeBSD__ +#if __FreeBSD__ >= 4 + struct { + char dv_xname[64]; /*XXX*/ + } sc_dev; +#else + struct device sc_dev; +#endif + struct arpcom sc_ec; +#endif + struct am79c930_softc sc_chip; + struct ifnet *sc_ifp; + int (*sc_enable) __P((struct awi_softc *)); + void (*sc_disable) __P((struct awi_softc *)); + + struct ifmedia sc_media; + enum awi_status sc_status; + unsigned int sc_enabled:1, + sc_busy:1, + sc_cansleep:1, + sc_invalid:1, + sc_enab_intr:1, + sc_format_llc:1, + sc_start_bss:1, + sc_rawbpf:1, + sc_no_bssid:1, + sc_active_scan:1, + sc_attached:1; /* attach has succeeded */ + u_int8_t sc_cmd_inprog; + int sc_sleep_cnt; + + int sc_mgt_timer; + + TAILQ_HEAD(, awi_bss) sc_scan; + u_int8_t sc_scan_cur; + u_int8_t sc_scan_min; + u_int8_t sc_scan_max; + u_int8_t sc_scan_set; + struct awi_bss sc_bss; + u_int8_t sc_ownssid[IEEE80211_NWID_LEN + 2]; + u_int8_t sc_ownch; + + int sc_rx_timer; + u_int32_t sc_rxdoff; + u_int32_t sc_rxmoff; + struct mbuf *sc_rxpend; + + int sc_tx_timer; + u_int8_t sc_tx_rate; + struct ifqueue sc_mgtq; + u_int32_t sc_txbase; + u_int32_t sc_txend; + u_int32_t sc_txnext; + u_int32_t sc_txdone; + + int sc_wep_keylen[IEEE80211_WEP_NKID]; /* keylen */ + u_int8_t sc_wep_key[IEEE80211_WEP_NKID][AWI_MAX_KEYLEN]; + int sc_wep_defkid; + void *sc_wep_ctx; /* work area */ + struct awi_wep_algo *sc_wep_algo; + + u_char sc_banner[AWI_BANNER_LEN]; + struct awi_mib_local sc_mib_local; + struct awi_mib_addr sc_mib_addr; + struct awi_mib_mac sc_mib_mac; + struct awi_mib_stat sc_mib_stat; + struct awi_mib_mgt sc_mib_mgt; + struct awi_mib_phy sc_mib_phy; +}; + +#define awi_read_1(sc, off) ((sc)->sc_chip.sc_ops->read_1)(&sc->sc_chip, off) +#define awi_read_2(sc, off) ((sc)->sc_chip.sc_ops->read_2)(&sc->sc_chip, off) +#define awi_read_4(sc, off) ((sc)->sc_chip.sc_ops->read_4)(&sc->sc_chip, off) +#define awi_read_bytes(sc, off, ptr, len) ((sc)->sc_chip.sc_ops->read_bytes)(&sc->sc_chip, off, ptr, len) + +#define awi_write_1(sc, off, val) \ + ((sc)->sc_chip.sc_ops->write_1)(&sc->sc_chip, off, val) +#define awi_write_2(sc, off, val) \ + ((sc)->sc_chip.sc_ops->write_2)(&sc->sc_chip, off, val) +#define awi_write_4(sc, off, val) \ + ((sc)->sc_chip.sc_ops->write_4)(&sc->sc_chip, off, val) +#define awi_write_bytes(sc, off, ptr, len) \ + ((sc)->sc_chip.sc_ops->write_bytes)(&sc->sc_chip, off, ptr, len) + +#define awi_drvstate(sc, state) \ + awi_write_1(sc, AWI_DRIVERSTATE, \ + ((state) | AWI_DRV_AUTORXLED|AWI_DRV_AUTOTXLED)) + +/* unalligned little endian access */ +#define LE_READ_2(p) \ + (((u_int8_t *)(p))[0] | (((u_int8_t *)(p))[1] << 8)) +#define LE_READ_4(p) \ + (((u_int8_t *)(p))[0] | (((u_int8_t *)(p))[1] << 8) | \ + (((u_int8_t *)(p))[2] << 16) | (((u_int8_t *)(p))[3] << 24)) +#define LE_WRITE_2(p, v) \ + ((((u_int8_t *)(p))[0] = ((u_int32_t)(v) & 0xff)), \ + (((u_int8_t *)(p))[1] = (((u_int32_t)(v) >> 8) & 0xff))) +#define LE_WRITE_4(p, v) \ + ((((u_int8_t *)(p))[0] = ((u_int32_t)(v) & 0xff)), \ + (((u_int8_t *)(p))[1] = (((u_int32_t)(v) >> 8) & 0xff)), \ + (((u_int8_t *)(p))[2] = (((u_int32_t)(v) >> 16) & 0xff)), \ + (((u_int8_t *)(p))[3] = (((u_int32_t)(v) >> 24) & 0xff))) + +#define AWI_80211_RATE(rate) (((rate) & 0x7f) * 5) + +int awi_attach __P((struct awi_softc *)); +int awi_intr __P((void *)); +void awi_reset __P((struct awi_softc *)); +#ifdef __NetBSD__ +int awi_activate __P((struct device *, enum devact)); +int awi_detach __P((struct awi_softc *)); +void awi_power __P((struct awi_softc *, int)); +#endif + +void awi_stop __P((struct awi_softc *sc)); +int awi_init __P((struct awi_softc *sc)); +int awi_init_region __P((struct awi_softc *)); +int awi_wicfg __P((struct ifnet *, u_long, caddr_t)); + +int awi_wep_setnwkey __P((struct awi_softc *, struct ieee80211_nwkey *)); +int awi_wep_getnwkey __P((struct awi_softc *, struct ieee80211_nwkey *)); +int awi_wep_getalgo __P((struct awi_softc *)); +int awi_wep_setalgo __P((struct awi_softc *, int)); +int awi_wep_setkey __P((struct awi_softc *, int, unsigned char *, int)); +int awi_wep_getkey __P((struct awi_softc *, int, unsigned char *, int *)); +struct mbuf *awi_wep_encrypt __P((struct awi_softc *, struct mbuf *, int)); diff --git a/sys/dev/bktr/bktr_mem.c b/sys/dev/bktr/bktr_mem.c new file mode 100644 index 000000000000..11769aee04d8 --- /dev/null +++ b/sys/dev/bktr/bktr_mem.c @@ -0,0 +1,173 @@ +/* $FreeBSD$ */ + +/* + * This is prt of the Driver for Video Capture Cards (Frame grabbers) + * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 + * chipset. + * Copyright Roger Hardiman. + * + * bktr_mem : This kernel module allows us to keep our allocated + * contiguous memory for the video buffer, DMA programs and VBI data + * while the main bktr driver is unloaded and reloaded. + * This avoids the problem of trying to allocate contiguous each + * time the bktr driver is loaded. + */ + +/* + * 1. Redistributions of source code must retain the + * Copyright (c) 2000 Roger Hardiman + * 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 Roger Hardiman + * 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/param.h> +#include <sys/kernel.h> +#include <stdio.h> +#include <string.h> +#include <dev/bktr/bktr_mem.h> + +struct memory_pointers { + int addresses_stored; + vm_offset_t dma_prog; + vm_offset_t odd_dma_prog; + vm_offset_t vbidata; + vm_offset_t vbibuffer; + vm_offset_t buf; +} memory_pointers; + +static struct memory_pointers memory_list[BKTR_MEM_MAX_DEVICES]; + +/*************************************************************/ + +static int +bktr_mem_modevent(module_t mod, int type, void *unused){ + + switch (type) { + case MOD_LOAD: + { + printf("bktr_mem: memory holder loaded\n"); +/* + * bzero causes a panic. + bzero((caddr_t)memory_list, sizeof(memory_list)); + * So use a simple for loop for now. +*/ + {int x; + unsigned char *d = (unsigned char *)memory_list; + for (x=0; x< sizeof(memory_list); x++) { + d[x]=0; + } + } + return 0; + } + case MOD_UNLOAD: + { + printf("bktr_mem: memory holder unloaded\n"); + return 0; + } + default: + break; + } + return 0; +}; + +/*************************************************************/ + +int +bktr_has_stored_addresses(int unit) { + + if ((unit < 0) || (unit >= BKTR_MEM_MAX_DEVICES)) { + printf("bktr_mem: Unit number %d invalid\n",unit); + return 0; + } + + return memory_list[unit].addresses_stored; +} + +/*************************************************************/ + +void +bktr_store_address(int unit, int type, vm_offset_t addr) { + + if ((unit < 0) || (unit >= BKTR_MEM_MAX_DEVICES)) { + printf("bktr_mem: Unit number %d invalid for memory type %d, address 0x%x\n" + ,unit,type,addr); + return; + } + + switch (type) { + case BKTR_MEM_DMA_PROG: memory_list[unit].dma_prog = addr; + memory_list[unit].addresses_stored = 1; + break; + case BKTR_MEM_ODD_DMA_PROG: memory_list[unit].odd_dma_prog = addr; + memory_list[unit].addresses_stored = 1; + break; + case BKTR_MEM_VBIDATA: memory_list[unit].vbidata = addr; + memory_list[unit].addresses_stored = 1; + break; + case BKTR_MEM_VBIBUFFER: memory_list[unit].vbibuffer = addr; + memory_list[unit].addresses_stored = 1; + break; + case BKTR_MEM_BUF: memory_list[unit].buf = addr; + memory_list[unit].addresses_stored = 1; + break; + default: printf("bktr_mem: Invalid memory type %d for bktr%d, address 0x%xn", + type,unit,addr); + break; + } +} + +/*************************************************************/ + +vm_offset_t +bktr_retrieve_address(int unit, int type) { + + if ((unit < 0) || (unit >= BKTR_MEM_MAX_DEVICES)) { + printf("bktr_mem: Unit number %d too large for memory type %d\n",unit,type); + return NULL; + } + switch (type) { + case BKTR_MEM_DMA_PROG: return memory_list[unit].dma_prog; + case BKTR_MEM_ODD_DMA_PROG: return memory_list[unit].odd_dma_prog; + case BKTR_MEM_VBIDATA: return memory_list[unit].vbidata; + case BKTR_MEM_VBIBUFFER: return memory_list[unit].vbibuffer; + case BKTR_MEM_BUF: return memory_list[unit].buf; + default: printf("bktr_mem: Invalid memory type %d for bktr%d",type,unit); + return NULL; + } +} + +/*************************************************************/ + +static moduledata_t bktr_mem_mod = { + "bktr_mem", + bktr_mem_modevent, + 0 +}; +DECLARE_MODULE(bktr_mem, bktr_mem_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); +MODULE_VERSION(bktr_mem, 1); diff --git a/sys/dev/bktr/bktr_mem.h b/sys/dev/bktr/bktr_mem.h new file mode 100644 index 000000000000..4c6d7a508ac7 --- /dev/null +++ b/sys/dev/bktr/bktr_mem.h @@ -0,0 +1,63 @@ +/* $FreeBSD$ */ + +/* + * This is prt of the Driver for Video Capture Cards (Frame grabbers) + * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 + * chipset. + * Copyright Roger Hardiman. + * + * bktr_mem : This kernel module allows us to keep our allocated + * contiguous memory for the video buffer, DMA programs and VBI data + * while the main bktr driver is unloaded and reloaded. + * This avoids the problem of trying to allocate contiguous each + * time the bktr driver is loaded. + */ + +/* + * 1. Redistributions of source code must retain the + * Copyright (c) 2000 Roger Hardiman + * 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 Roger Hardiman + * 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. + */ + + +/* Support this number of devices */ +#define BKTR_MEM_MAX_DEVICES 8 + +/* Define a name for each block of memory we need to keep hold of */ +#define BKTR_MEM_DMA_PROG 1 +#define BKTR_MEM_ODD_DMA_PROG 2 +#define BKTR_MEM_VBIDATA 3 +#define BKTR_MEM_VBIBUFFER 4 +#define BKTR_MEM_BUF 5 + +/* Prototypes */ +int bktr_has_stored_addresses(int unit); +void bktr_store_address(int unit, int type, vm_offset_t addr); +vm_offset_t bktr_retrieve_address(int unit, int type); + diff --git a/sys/dev/sound/pci/fm801.c b/sys/dev/sound/pci/fm801.c new file mode 100644 index 000000000000..2173c0a8519f --- /dev/null +++ b/sys/dev/sound/pci/fm801.c @@ -0,0 +1,728 @@ +/* + * Copyright (c) 2000 Dmitry Dicky diwil@dataart.com + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include <dev/sound/pcm/sound.h> +#include <dev/sound/pcm/ac97.h> +#include <pci/pcireg.h> +#include <pci/pcivar.h> + +#define PCI_VENDOR_FORTEMEDIA 0x1319 +#define PCI_DEVICE_FORTEMEDIA1 0x08011319 +#define PCI_DEVICE_FORTEMEDIA2 0x08021319 /* ??? have no idea what's this... */ + +#define FM_PCM_VOLUME 0x00 +#define FM_FM_VOLUME 0x02 +#define FM_I2S_VOLUME 0x04 +#define FM_RECORD_SOURCE 0x06 + +#define FM_PLAY_CTL 0x08 +#define FM_PLAY_RATE_MASK 0x0f00 +#define FM_PLAY_BUF1_LAST 0x0001 +#define FM_PLAY_BUF2_LAST 0x0002 +#define FM_PLAY_START 0x0020 +#define FM_PLAY_PAUSE 0x0040 +#define FM_PLAY_STOPNOW 0x0080 +#define FM_PLAY_16BIT 0x4000 +#define FM_PLAY_STEREO 0x8000 + +#define FM_PLAY_DMALEN 0x0a +#define FM_PLAY_DMABUF1 0x0c +#define FM_PLAY_DMABUF2 0x10 + + +#define FM_REC_CTL 0x14 +#define FM_REC_RATE_MASK 0x0f00 +#define FM_REC_BUF1_LAST 0x0001 +#define FM_REC_BUF2_LAST 0x0002 +#define FM_REC_START 0x0020 +#define FM_REC_PAUSE 0x0040 +#define FM_REC_STOPNOW 0x0080 +#define FM_REC_16BIT 0x4000 +#define FM_REC_STEREO 0x8000 + + +#define FM_REC_DMALEN 0x16 +#define FM_REC_DMABUF1 0x18 +#define FM_REC_DMABUF2 0x1c + +#define FM_CODEC_CTL 0x22 +#define FM_VOLUME 0x26 +#define FM_VOLUME_MUTE 0x8000 + +#define FM_CODEC_CMD 0x2a +#define FM_CODEC_CMD_READ 0x0080 +#define FM_CODEC_CMD_VALID 0x0100 +#define FM_CODEC_CMD_BUSY 0x0200 + +#define FM_CODEC_DATA 0x2c + +#define FM_IO_CTL 0x52 +#define FM_CARD_CTL 0x54 + +#define FM_INTMASK 0x56 +#define FM_INTMASK_PLAY 0x0001 +#define FM_INTMASK_REC 0x0002 +#define FM_INTMASK_VOL 0x0040 +#define FM_INTMASK_MPU 0x0080 + +#define FM_INTSTATUS 0x5a +#define FM_INTSTATUS_PLAY 0x0100 +#define FM_INTSTATUS_REC 0x0200 +#define FM_INTSTATUS_VOL 0x4000 +#define FM_INTSTATUS_MPU 0x8000 + +#define FM801_BUFFSIZE 1024*4 /* Other values do not work!!! */ + +/* debug purposes */ +#define DPRINT if(0) printf + + +/* channel interface */ +static void *fm801ch_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir); +static int fm801ch_setformat(void *data, u_int32_t format); +static int fm801ch_setspeed(void *data, u_int32_t speed); +static int fm801ch_setblocksize(void *data, u_int32_t blocksize); +static int fm801ch_trigger(void *data, int go); +static int fm801ch_getptr(void *data); +static pcmchan_caps *fm801ch_getcaps(void *data); +/* +static int fm801ch_setup(pcm_channel *c); +*/ + +static u_int32_t fmts[] = { + AFMT_U8, + AFMT_STEREO | AFMT_U8, + AFMT_S16_LE, + AFMT_STEREO | AFMT_S16_LE, + 0 +}; + +static pcmchan_caps fm801ch_caps = { + 4000, 48000, + fmts, 0 +}; + +static pcm_channel fm801_chantemplate = { + fm801ch_init, + NULL, /* setdir */ + fm801ch_setformat, + fm801ch_setspeed, + fm801ch_setblocksize, + fm801ch_trigger, + fm801ch_getptr, + fm801ch_getcaps, + NULL, /* free */ + NULL, /* nop1 */ + NULL, /* nop2 */ + NULL, /* nop3 */ + NULL, /* nop4 */ + NULL, /* nop5 */ + NULL, /* nop6 */ + NULL, /* nop7 */ +}; + +struct fm801_info; + +struct fm801_chinfo { + struct fm801_info *parent; + pcm_channel *channel; + snd_dbuf *buffer; + u_int32_t spd, dir, fmt; /* speed, direction, format */ + u_int32_t shift; +}; + +struct fm801_info { + int type; + bus_space_tag_t st; + bus_space_handle_t sh; + bus_dma_tag_t parent_dmat; + + device_t dev; + int num; + u_int32_t unit; + + struct resource *reg, *irq; + int regtype, regid, irqid; + void *ih; + + u_int32_t play_flip, + play_nextblk, + play_start, + play_blksize, + play_fmt, + play_shift, + play_size; + + u_int32_t rec_flip, + rec_nextblk, + rec_start, + rec_blksize, + rec_fmt, + rec_shift, + rec_size; + + struct fm801_chinfo pch, rch; +}; + +/* Bus Read / Write routines */ +static u_int32_t +fm801_rd(struct fm801_info *fm801, int regno, int size) +{ + switch(size) { + case 1: + return (bus_space_read_1(fm801->st, fm801->sh, regno)); + case 2: + return (bus_space_read_2(fm801->st, fm801->sh, regno)); + case 4: + return (bus_space_read_4(fm801->st, fm801->sh, regno)); + default: + return 0xffffffff; + } +} + +static void +fm801_wr(struct fm801_info *fm801, int regno, u_int32_t data, int size) +{ + switch(size) { + case 1: + return bus_space_write_1(fm801->st, fm801->sh, regno, data); + case 2: + return bus_space_write_2(fm801->st, fm801->sh, regno, data); + case 4: + return bus_space_write_4(fm801->st, fm801->sh, regno, data); + default: + return; + } +} + +/* + * ac97 codec routines + */ +#define TIMO 50 +static u_int32_t +fm801_rdcd(void *devinfo, int regno) +{ + struct fm801_info *fm801 = (struct fm801_info *)devinfo; + int i; + + for (i = 0; i < TIMO && fm801_rd(fm801,FM_CODEC_CMD,2) & FM_CODEC_CMD_BUSY; i++) { + DELAY(10000); + DPRINT("fm801 rdcd: 1 - DELAY\n"); + } + if (i >= TIMO) { + printf("fm801 rdcd: codec busy\n"); + return 0; + } + + fm801_wr(fm801,FM_CODEC_CMD, regno|FM_CODEC_CMD_READ,2); + + for (i = 0; i < TIMO && !(fm801_rd(fm801,FM_CODEC_CMD,2) & FM_CODEC_CMD_VALID); i++) + { + DELAY(10000); + DPRINT("fm801 rdcd: 2 - DELAY\n"); + } + if (i >= TIMO) { + printf("fm801 rdcd: write codec invalid\n"); + return 0; + } + + return fm801_rd(fm801,FM_CODEC_DATA,2); +} + +static void +fm801_wrcd(void *devinfo, int regno, u_int32_t data) +{ + struct fm801_info *fm801 = (struct fm801_info *)devinfo; + int i; + + DPRINT("fm801_wrcd reg 0x%x val 0x%x\n",regno, data); +/* + if(regno == AC97_REG_RECSEL) return; +*/ + /* Poll until codec is ready */ + for (i = 0; i < TIMO && fm801_rd(fm801,FM_CODEC_CMD,2) & FM_CODEC_CMD_BUSY; i++) { + DELAY(10000); + DPRINT("fm801 rdcd: 1 - DELAY\n"); + } + if (i >= TIMO) { + printf("fm801 wrcd: read codec busy\n"); + return; + } + + fm801_wr(fm801,FM_CODEC_DATA,data, 2); + fm801_wr(fm801,FM_CODEC_CMD, regno,2); + + /* wait until codec is ready */ + for (i = 0; i < TIMO && fm801_rd(fm801,FM_CODEC_CMD,2) & FM_CODEC_CMD_BUSY; i++) { + DELAY(10000); + DPRINT("fm801 wrcd: 2 - DELAY\n"); + } + if (i >= TIMO) { + printf("fm801 wrcd: read codec busy\n"); + return; + } + DPRINT("fm801 wrcd release reg 0x%x val 0x%x\n",regno, data); + return; +} + +/* + * The interrupt handler + */ +static void +fm801_intr(void *p) +{ + struct fm801_info *fm801 = (struct fm801_info *)p; + u_int32_t intsrc = fm801_rd(fm801, FM_INTSTATUS, 2); + struct fm801_chinfo *ch = &(fm801->pch); + snd_dbuf *b = ch->buffer; + + DPRINT("\nfm801_intr intsrc 0x%x ", intsrc); + DPRINT("rp %d, rl %d, fp %d fl %d, size=%d\n", + b->rp,b->rl, b->fp,b->fl, b->blksz); + + if(intsrc & FM_INTSTATUS_PLAY) { + fm801->play_flip++; + if(fm801->play_flip & 1) { + fm801_wr(fm801, FM_PLAY_DMABUF1, fm801->play_start,4); + } else + fm801_wr(fm801, FM_PLAY_DMABUF2, fm801->play_nextblk,4); + chn_intr(fm801->pch.channel); + } + + if(intsrc & FM_INTSTATUS_REC) { + fm801->rec_flip++; + if(fm801->rec_flip & 1) { + fm801_wr(fm801, FM_REC_DMABUF1, fm801->rec_start,4); + } else + fm801_wr(fm801, FM_REC_DMABUF2, fm801->rec_nextblk,4); + chn_intr(fm801->rch.channel); + } + + if ( intsrc & FM_INTSTATUS_MPU ) { + /* This is a TODOish thing... */ + fm801_wr(fm801, FM_INTSTATUS, intsrc & FM_INTSTATUS_MPU,2); + } + + if ( intsrc & FM_INTSTATUS_VOL ) { + /* This is a TODOish thing... */ + fm801_wr(fm801, FM_INTSTATUS, intsrc & FM_INTSTATUS_VOL,2); + } + + DPRINT("fm801_intr clear\n\n"); + fm801_wr(fm801, FM_INTSTATUS, intsrc & (FM_INTSTATUS_PLAY | FM_INTSTATUS_REC), 2); +} + +/* + * Init routine is taken from an original NetBSD driver + */ +static int +fm801_init(struct fm801_info *fm801) +{ + u_int32_t k1; + + /* reset codec */ + fm801_wr(fm801, FM_CODEC_CTL, 0x0020,2); + DELAY(100000); + fm801_wr(fm801, FM_CODEC_CTL, 0x0000,2); + DELAY(100000); + + fm801_wr(fm801, FM_PCM_VOLUME, 0x0808,2); + fm801_wr(fm801, FM_FM_VOLUME, 0x0808,2); + fm801_wr(fm801, FM_I2S_VOLUME, 0x0808,2); + fm801_wr(fm801, 0x40,0x107f,2); /* enable legacy audio */ + + fm801_wr((void *)fm801, FM_RECORD_SOURCE, 0x0000,2); + + /* Unmask playback, record and mpu interrupts, mask the rest */ + k1 = fm801_rd((void *)fm801, FM_INTMASK,2); + fm801_wr(fm801, FM_INTMASK, + (k1 & ~(FM_INTMASK_PLAY | FM_INTMASK_REC | FM_INTMASK_MPU)) | + FM_INTMASK_VOL,2); + fm801_wr(fm801, FM_INTSTATUS, + FM_INTSTATUS_PLAY | FM_INTSTATUS_REC | FM_INTSTATUS_MPU | + FM_INTSTATUS_VOL,2); + + DPRINT("FM801 init Ok\n"); + return 0; +} + +static int +fm801_pci_attach(device_t dev) +{ + u_int32_t data; + struct ac97_info *codec = 0; + struct fm801_info *fm801; + int i; + int mapped = 0; + char status[SND_STATUSLEN]; + + if ((fm801 = (struct fm801_info *)malloc(sizeof(*fm801),M_DEVBUF, M_NOWAIT)) == NULL) { + device_printf(dev, "cannot allocate softc\n"); + return ENXIO; + } + + bzero(fm801, sizeof(*fm801)); + fm801->type = pci_get_devid(dev); + + data = pci_read_config(dev, PCIR_COMMAND, 2); + data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); + pci_write_config(dev, PCIR_COMMAND, data, 2); + data = pci_read_config(dev, PCIR_COMMAND, 2); + + for (i = 0; (mapped == 0) && (i < PCI_MAXMAPS_0); i++) { + fm801->regid = PCIR_MAPS + i*4; + fm801->regtype = SYS_RES_MEMORY; + fm801->reg = bus_alloc_resource(dev, fm801->regtype, &fm801->regid, + 0, ~0, 1, RF_ACTIVE); + if(!fm801->reg) + { + fm801->regtype = SYS_RES_IOPORT; + fm801->reg = bus_alloc_resource(dev, fm801->regtype, &fm801->regid, + 0, ~0, 1, RF_ACTIVE); + } + + if(fm801->reg) { + fm801->st = rman_get_bustag(fm801->reg); + fm801->sh = rman_get_bushandle(fm801->reg); + mapped++; + } + } + + if (mapped == 0) { + device_printf(dev, "unable to map register space\n"); + goto oops; + } + + fm801_init(fm801); + + codec = ac97_create(dev, (void *)fm801, NULL, fm801_rdcd, fm801_wrcd); + if (codec == NULL) goto oops; + + if (mixer_init(dev, &ac97_mixer, codec) == -1) goto oops; + + fm801->irqid = 0; + fm801->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &fm801->irqid, + 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); + if (!fm801->irq || + bus_setup_intr(dev, fm801->irq, INTR_TYPE_TTY, + fm801_intr, fm801, &fm801->ih)) { + device_printf(dev, "unable to map interrupt\n"); + goto oops; + } + + if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, + /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, + /*highaddr*/BUS_SPACE_MAXADDR, + /*filter*/NULL, /*filterarg*/NULL, + /*maxsize*/FM801_BUFFSIZE, /*nsegments*/1, /*maxsegz*/0x3ffff, + /*flags*/0, &fm801->parent_dmat) != 0) { + device_printf(dev, "unable to create dma tag\n"); + goto oops; + } + + snprintf(status, 64, "at %s 0x%lx irq %ld", + (fm801->regtype == SYS_RES_IOPORT)? "io" : "memory", + rman_get_start(fm801->reg), rman_get_start(fm801->irq)); + +#define FM801_MAXPLAYCH 1 + if (pcm_register(dev, fm801, FM801_MAXPLAYCH, 1)) goto oops; + pcm_addchan(dev, PCMDIR_PLAY, &fm801_chantemplate, fm801); + pcm_addchan(dev, PCMDIR_REC, &fm801_chantemplate, fm801); + pcm_setstatus(dev, status); + + return 0; + +oops: + if (codec) ac97_destroy(codec); + if (fm801->reg) bus_release_resource(dev, fm801->regtype, fm801->regid, fm801->reg); + if (fm801->ih) bus_teardown_intr(dev, fm801->irq, fm801->ih); + if (fm801->irq) bus_release_resource(dev, SYS_RES_IRQ, fm801->irqid, fm801->irq); + if (fm801->parent_dmat) bus_dma_tag_destroy(fm801->parent_dmat); + free(fm801, M_DEVBUF); + return ENXIO; +} + +static int +fm801_pci_detach(device_t dev) +{ + int r; + struct fm801_info *fm801; + + DPRINT("Forte Media FM801 detach\n"); + + r = pcm_unregister(dev); + if (r) + return r; + + fm801 = pcm_getdevinfo(dev); + bus_release_resource(dev, fm801->regtype, fm801->regid, fm801->reg); + bus_teardown_intr(dev, fm801->irq, fm801->ih); + bus_release_resource(dev, SYS_RES_IRQ, fm801->irqid, fm801->irq); + bus_dma_tag_destroy(fm801->parent_dmat); + free(fm801, M_DEVBUF); + return 0; +} + +static int +fm801_pci_probe( device_t dev ) +{ + int id; + if ((id = pci_get_devid(dev)) == PCI_DEVICE_FORTEMEDIA1 ) { + device_set_desc(dev, "Forte Media FM801 Audio Controller"); + return 0; + } +/* + if ((id = pci_get_devid(dev)) == PCI_DEVICE_FORTEMEDIA2 ) { + device_set_desc(dev, "Forte Media FM801 Joystick (Not Supported)"); + return ENXIO; + } +*/ + return ENXIO; +} + + + +/* channel interface */ +static void * +fm801ch_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +{ + struct fm801_info *fm801 = (struct fm801_info *)devinfo; + struct fm801_chinfo *ch = (dir == PCMDIR_PLAY)? &fm801->pch : &fm801->rch; + + DPRINT("fm801ch_init, direction = %d\n", dir); + ch->parent = fm801; + ch->channel = c; + ch->buffer = b; + ch->buffer->bufsize = FM801_BUFFSIZE; + ch->dir = dir; + if( chn_allocbuf(ch->buffer, fm801->parent_dmat) == -1) return NULL; + return (void *)ch; +} + +static int +fm801ch_setformat(void *data, u_int32_t format) +{ + struct fm801_chinfo *ch = data; + struct fm801_info *fm801 = ch->parent; + + DPRINT("fm801ch_setformat 0x%x : %s, %s, %s, %s\n", format, + (format & AFMT_STEREO)?"stereo":"mono", + (format & (AFMT_S16_LE | AFMT_S16_BE | AFMT_U16_LE | AFMT_U16_BE)) ? "16bit":"8bit", + (format & AFMT_SIGNED)? "signed":"unsigned", + (format & AFMT_BIGENDIAN)?"bigendiah":"littleendian" ); + + if(ch->dir == PCMDIR_PLAY) { + fm801->play_fmt = (format & AFMT_STEREO)? FM_PLAY_STEREO : 0; + fm801->play_fmt |= (format & AFMT_16BIT) ? FM_PLAY_16BIT : 0; + return 0; + } + + if(ch->dir == PCMDIR_REC ) { + fm801->rec_fmt = (format & AFMT_STEREO)? FM_REC_STEREO:0; + fm801->rec_fmt |= (format & AFMT_16BIT) ? FM_PLAY_16BIT : 0; + return 0; + } + + return 0; +} + +struct { + int limit; + int rate; +} fm801_rates[11] = { + { 6600, 5500 }, + { 8750, 8000 }, + { 10250, 9600 }, + { 13200, 11025 }, + { 17500, 16000 }, + { 20500, 19200 }, + { 26500, 22050 }, + { 35000, 32000 }, + { 41000, 38400 }, + { 46000, 44100 }, + { 48000, 48000 }, +/* anything above -> 48000 */ +}; + +static int +fm801ch_setspeed(void *data, u_int32_t speed) +{ + struct fm801_chinfo *ch = data; + struct fm801_info *fm801 = ch->parent; + register int i; + + + for (i = 0; i < 10 && fm801_rates[i].limit <= speed; i++) ; + + if(ch->dir == PCMDIR_PLAY) { + fm801->pch.spd = fm801_rates[i].rate; + fm801->play_shift = (i<<8); + fm801->play_shift &= FM_PLAY_RATE_MASK; + } + + if(ch->dir == PCMDIR_REC ) { + fm801->rch.spd = fm801_rates[i].rate; + fm801->rec_shift = (i<<8); + fm801->rec_shift &= FM_REC_RATE_MASK; + } + + ch->spd = fm801_rates[i].rate; + + return fm801_rates[i].rate; +} + +static int +fm801ch_setblocksize(void *data, u_int32_t blocksize) +{ + struct fm801_chinfo *ch = data; + struct fm801_info *fm801 = ch->parent; + + if(ch->dir == PCMDIR_PLAY) { + if(fm801->play_flip) return fm801->play_blksize; + fm801->play_blksize = blocksize; + } + + if(ch->dir == PCMDIR_REC) { + if(fm801->rec_flip) return fm801->rec_blksize; + fm801->rec_blksize = blocksize; + } + + DPRINT("fm801ch_setblocksize %d (dir %d)\n",blocksize, ch->dir); + + return blocksize; +} + +static int +fm801ch_trigger(void *data, int go) +{ + struct fm801_chinfo *ch = data; + struct fm801_info *fm801 = ch->parent; + u_int32_t baseaddr = vtophys(ch->buffer->buf); + snd_dbuf *b = ch->buffer; + u_int32_t k1; + + DPRINT("fm801ch_trigger go %d , ", go); + DPRINT("rp %d, rl %d, fp %d fl %d, dl %d, blksize=%d\n", + b->rp,b->rl, b->fp,b->fl, b->dl, b->blksz); + + if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) { + return 0; + } + + if (ch->dir == PCMDIR_PLAY) { + if (go == PCMTRIG_START) { + + fm801->play_start = baseaddr; + fm801->play_nextblk = fm801->play_start + fm801->play_blksize; + fm801->play_flip = 0; + fm801_wr(fm801, FM_PLAY_DMALEN, fm801->play_blksize - 1, 2); + fm801_wr(fm801, FM_PLAY_DMABUF1,fm801->play_start,4); + fm801_wr(fm801, FM_PLAY_DMABUF2,fm801->play_nextblk,4); + fm801_wr(fm801, FM_PLAY_CTL, + FM_PLAY_START | FM_PLAY_STOPNOW | fm801->play_fmt | fm801->play_shift, + 2 ); + } else { + fm801->play_flip = 0; + k1 = fm801_rd(fm801, FM_PLAY_CTL,2); + fm801_wr(fm801, FM_PLAY_CTL, + (k1 & ~(FM_PLAY_STOPNOW | FM_PLAY_START)) | + FM_PLAY_BUF1_LAST | FM_PLAY_BUF2_LAST, 2 ); + } + } else if(ch->dir == PCMDIR_REC) { + if (go == PCMTRIG_START) { + fm801->rec_start = baseaddr; + fm801->rec_nextblk = fm801->rec_start + fm801->rec_blksize; + fm801->rec_flip = 0; + fm801_wr(fm801, FM_REC_DMALEN, fm801->rec_blksize - 1, 2); + fm801_wr(fm801, FM_REC_DMABUF1,fm801->rec_start,4); + fm801_wr(fm801, FM_REC_DMABUF2,fm801->rec_nextblk,4); + fm801_wr(fm801, FM_REC_CTL, + FM_REC_START | FM_REC_STOPNOW | fm801->rec_fmt | fm801->rec_shift, + 2 ); + } else { + fm801->rec_flip = 0; + k1 = fm801_rd(fm801, FM_REC_CTL,2); + fm801_wr(fm801, FM_REC_CTL, + (k1 & ~(FM_REC_STOPNOW | FM_REC_START)) | + FM_REC_BUF1_LAST | FM_REC_BUF2_LAST, 2); + } + } + + return 0; +} + +/* Almost ALSA copy */ +static int +fm801ch_getptr(void *data) +{ + struct fm801_chinfo *ch = data; + struct fm801_info *fm801 = ch->parent; + int result = 0; + snd_dbuf *b = ch->buffer; + + if (ch->dir == PCMDIR_PLAY) { + result = fm801_rd(fm801, + (fm801->play_flip&1) ? + FM_PLAY_DMABUF2:FM_PLAY_DMABUF1, 4) - fm801->play_start; + } + + if (ch->dir == PCMDIR_REC) { + result = fm801_rd(fm801, + (fm801->rec_flip&1) ? + FM_REC_DMABUF2:FM_REC_DMABUF1, 4) - fm801->rec_start; + } + + DPRINT("fm801ch_getptr:%d, rp %d, rl %d, fp %d fl %d\n", + result, b->rp,b->rl, b->fp,b->fl); + + return result; +} + +static pcmchan_caps * +fm801ch_getcaps(void *data) +{ + return &fm801ch_caps; +} + +static device_method_t fm801_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, fm801_pci_probe), + DEVMETHOD(device_attach, fm801_pci_attach), + DEVMETHOD(device_detach, fm801_pci_detach), + { 0, 0} +}; + +static driver_t fm801_driver = { + "pcm", + fm801_methods, + sizeof(snddev_info), +}; + +static devclass_t pcm_devclass; + +DRIVER_MODULE(fm801, pci, fm801_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/maestro.c b/sys/dev/sound/pci/maestro.c new file mode 100644 index 000000000000..a465d5c33533 --- /dev/null +++ b/sys/dev/sound/pci/maestro.c @@ -0,0 +1,1188 @@ +/*- + * Copyright (c) 2000 Taku YAMAMOTO <taku@cent.saitama-u.ac.jp> + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $Id: maestro.c,v 1.12 2000/09/06 03:32:34 taku Exp $ + * $FreeBSD$ + */ + +/* + * Credits: + * + * Part of this code (especially in many magic numbers) was heavily inspired + * by the Linux driver originally written by + * Alan Cox <alan.cox@linux.org>, modified heavily by + * Zach Brown <zab@zabbo.net>. + * + * busdma()-ize and buffer size reduction were suggested by + * Cameron Grant <gandalf@vilnya.demon.co.uk>. + * Also he showed me the way to use busdma() suite. + * + * Internal speaker problems on NEC VersaPro's and Dell Inspiron 7500 + * were looked at by + * Munehiro Matsuda <haro@tk.kubota.co.jp>, + * who brought patches based on the Linux driver with some simplification. + */ + +#include <dev/sound/pcm/sound.h> +#include <dev/sound/pcm/ac97.h> +#include <pci/pcireg.h> +#include <pci/pcivar.h> + +#include <dev/sound/pci/maestro_reg.h> + +#define inline __inline + +/* + * PCI IDs of supported chips: + * + * MAESTRO-1 0x01001285 + * MAESTRO-2 0x1968125d + * MAESTRO-2E 0x1978125d + */ + +#define MAESTRO_1_PCI_ID 0x01001285 +#define MAESTRO_2_PCI_ID 0x1968125d +#define MAESTRO_2E_PCI_ID 0x1978125d + +#define NEC_SUBID1 0x80581033 /* Taken from Linux driver */ +#define NEC_SUBID2 0x803c1033 /* NEC VersaProNX VA26D */ + +#ifndef AGG_MAXPLAYCH +# define AGG_MAXPLAYCH 4 +#endif + +#define AGG_BUFSIZ 4096 + + +/* ----------------------------- + * Data structures. + */ +struct agg_chinfo { + struct agg_info *parent; + pcm_channel *channel; + snd_dbuf *buffer; + bus_addr_t offset; + u_int32_t blocksize; + int dir; + u_int num; + u_int16_t aputype; + u_int16_t wcreg_tpl; +}; + +struct agg_info { + device_t dev; + struct resource *reg; + int regid; + + bus_space_tag_t st; + bus_space_handle_t sh; + bus_dma_tag_t parent_dmat; + + struct resource *irq; + int irqid; + void *ih; + + u_int8_t *stat; + bus_addr_t baseaddr; + + struct ac97_info *codec; + + u_int playchns, active; + struct agg_chinfo pch[AGG_MAXPLAYCH]; + struct agg_chinfo rch; +}; + + +static u_int32_t agg_rdcodec(void *, int); +static void agg_wrcodec(void *, int, u_int32_t); + +static inline void ringbus_setdest(struct agg_info*, int, int); + +static inline u_int16_t wp_rdreg(struct agg_info*, u_int16_t); +static inline void wp_wrreg(struct agg_info*, u_int16_t, u_int16_t); +static inline u_int16_t wp_rdapu(struct agg_info*, int, u_int16_t); +static inline void wp_wrapu(struct agg_info*, int, u_int16_t, u_int16_t); +static inline void wp_settimer(struct agg_info*, u_int); +static inline void wp_starttimer(struct agg_info*); +static inline void wp_stoptimer(struct agg_info*); + +static inline u_int16_t wc_rdreg(struct agg_info*, u_int16_t); +static inline void wc_wrreg(struct agg_info*, u_int16_t, u_int16_t); +static inline u_int16_t wc_rdchctl(struct agg_info*, int); +static inline void wc_wrchctl(struct agg_info*, int, u_int16_t); + +static inline void agg_power(struct agg_info*, int); + +static void agg_init(struct agg_info*); +static u_int32_t agg_ac97_init(void *); + +static void aggch_start_dac(struct agg_chinfo*); +static void aggch_stop_dac(struct agg_chinfo*); + +static inline void suppress_jitter(struct agg_chinfo*); + +static inline u_int calc_timer_freq(struct agg_chinfo*); +static void set_timer(struct agg_info*); + +static pcmchan_init_t aggch_init; +static pcmchan_free_t aggch_free; +static pcmchan_setformat_t aggch_setplayformat; +static pcmchan_setspeed_t aggch_setspeed; +static pcmchan_setblocksize_t aggch_setblocksize; +static pcmchan_trigger_t aggch_trigger; +static pcmchan_getptr_t aggch_getplayptr; +static pcmchan_getcaps_t aggch_getcaps; + +static void agg_intr(void *); +static int agg_probe(device_t); +static int agg_attach(device_t); +static int agg_detach(device_t); +static int agg_suspend(device_t); +static int agg_resume(device_t); +static int agg_shutdown(device_t); + +static void *dma_malloc(struct agg_info*, u_int32_t, bus_addr_t*); +static void dma_free(struct agg_info*, void *); + +/* ----------------------------- + * Subsystems. + */ + +/* Codec/Ringbus */ + +static u_int32_t +agg_rdcodec(void *sc, int regno) +{ + struct agg_info *ess = sc; + unsigned t; + + /* We have to wait for a SAFE time to write addr/data */ + for (t = 0; t < 20; t++) { + if ((bus_space_read_1(ess->st, ess->sh, PORT_CODEC_STAT) + & CODEC_STAT_MASK) != CODEC_STAT_PROGLESS) + break; + DELAY(2); /* 20.8us / 13 */ + } + if (t == 20) + device_printf(ess->dev, "agg_rdcodec() PROGLESS timed out.\n"); + + bus_space_write_1(ess->st, ess->sh, PORT_CODEC_CMD, + CODEC_CMD_READ | regno); + DELAY(21); /* AC97 cycle = 20.8usec */ + + /* Wait for data retrieve */ + for (t = 0; t < 20; t++) { + if ((bus_space_read_1(ess->st, ess->sh, PORT_CODEC_STAT) + & CODEC_STAT_MASK) == CODEC_STAT_RW_DONE) + break; + DELAY(2); /* 20.8us / 13 */ + } + if (t == 20) + /* Timed out, but perform dummy read. */ + device_printf(ess->dev, "agg_rdcodec() RW_DONE timed out.\n"); + + return bus_space_read_2(ess->st, ess->sh, PORT_CODEC_REG); +} + +static void +agg_wrcodec(void *sc, int regno, u_int32_t data) +{ + unsigned t; + struct agg_info *ess = sc; + + /* We have to wait for a SAFE time to write addr/data */ + for (t = 0; t < 20; t++) { + if ((bus_space_read_1(ess->st, ess->sh, PORT_CODEC_STAT) + & CODEC_STAT_MASK) != CODEC_STAT_PROGLESS) + break; + DELAY(2); /* 20.8us / 13 */ + } + if (t == 20) { + /* Timed out. Abort writing. */ + device_printf(ess->dev, "agg_wrcodec() PROGLESS timed out.\n"); + return; + } + + bus_space_write_2(ess->st, ess->sh, PORT_CODEC_REG, data); + bus_space_write_1(ess->st, ess->sh, PORT_CODEC_CMD, + CODEC_CMD_WRITE | regno); +} + +static inline void +ringbus_setdest(struct agg_info *ess, int src, int dest) +{ + u_int32_t data; + + data = bus_space_read_4(ess->st, ess->sh, PORT_RINGBUS_CTRL); + data &= ~(0xfU << src); + data |= (0xfU & dest) << src; + bus_space_write_4(ess->st, ess->sh, PORT_RINGBUS_CTRL, data); +} + +/* Wave Processor */ + +static inline u_int16_t +wp_rdreg(struct agg_info *ess, u_int16_t reg) +{ + bus_space_write_2(ess->st, ess->sh, PORT_DSP_INDEX, reg); + return bus_space_read_2(ess->st, ess->sh, PORT_DSP_DATA); +} + +static inline void +wp_wrreg(struct agg_info *ess, u_int16_t reg, u_int16_t data) +{ + bus_space_write_2(ess->st, ess->sh, PORT_DSP_INDEX, reg); + bus_space_write_2(ess->st, ess->sh, PORT_DSP_DATA, data); +} + +static inline void +apu_setindex(struct agg_info *ess, u_int16_t reg) +{ + int t; + + wp_wrreg(ess, WPREG_CRAM_PTR, reg); + /* Sometimes WP fails to set apu register index. */ + for (t = 0; t < 1000; t++) { + if (bus_space_read_2(ess->st, ess->sh, PORT_DSP_DATA) == reg) + break; + bus_space_write_2(ess->st, ess->sh, PORT_DSP_DATA, reg); + } + if (t == 1000) + device_printf(ess->dev, "apu_setindex() timed out.\n"); +} + +static inline u_int16_t +wp_rdapu(struct agg_info *ess, int ch, u_int16_t reg) +{ + u_int16_t ret; + + apu_setindex(ess, ((unsigned)ch << 4) + reg); + ret = wp_rdreg(ess, WPREG_DATA_PORT); + return ret; +} + +static inline void +wp_wrapu(struct agg_info *ess, int ch, u_int16_t reg, u_int16_t data) +{ + int t; + + apu_setindex(ess, ((unsigned)ch << 4) + reg); + wp_wrreg(ess, WPREG_DATA_PORT, data); + for (t = 0; t < 1000; t++) { + if (bus_space_read_2(ess->st, ess->sh, PORT_DSP_DATA) == data) + break; + bus_space_write_2(ess->st, ess->sh, PORT_DSP_DATA, data); + } + if (t == 1000) + device_printf(ess->dev, "wp_wrapu() timed out.\n"); +} + +static inline void +wp_settimer(struct agg_info *ess, u_int freq) +{ + u_int clock = 48000 << 2; + u_int prescale = 0, divide = (freq != 0) ? (clock / freq) : ~0; + + RANGE(divide, 4, 32 << 8); + + for (; divide > 32 << 1; divide >>= 1) + prescale++; + divide = (divide + 1) >> 1; + + for (; prescale < 7 && divide > 2 && !(divide & 1); divide >>= 1) + prescale++; + + wp_wrreg(ess, WPREG_TIMER_ENABLE, 0); + wp_wrreg(ess, WPREG_TIMER_FREQ, + (prescale << WP_TIMER_FREQ_PRESCALE_SHIFT) | (divide - 1)); + wp_wrreg(ess, WPREG_TIMER_ENABLE, 1); +} + +static inline void +wp_starttimer(struct agg_info *ess) +{ + wp_wrreg(ess, WPREG_TIMER_START, 1); +} + +static inline void +wp_stoptimer(struct agg_info *ess) +{ + wp_wrreg(ess, WPREG_TIMER_START, 0); + bus_space_write_2(ess->st, ess->sh, PORT_INT_STAT, 1); +} + +/* WaveCache */ + +static inline u_int16_t +wc_rdreg(struct agg_info *ess, u_int16_t reg) +{ + bus_space_write_2(ess->st, ess->sh, PORT_WAVCACHE_INDEX, reg); + return bus_space_read_2(ess->st, ess->sh, PORT_WAVCACHE_DATA); +} + +static inline void +wc_wrreg(struct agg_info *ess, u_int16_t reg, u_int16_t data) +{ + bus_space_write_2(ess->st, ess->sh, PORT_WAVCACHE_INDEX, reg); + bus_space_write_2(ess->st, ess->sh, PORT_WAVCACHE_DATA, data); +} + +static inline u_int16_t +wc_rdchctl(struct agg_info *ess, int ch) +{ + return wc_rdreg(ess, ch << 3); +} + +static inline void +wc_wrchctl(struct agg_info *ess, int ch, u_int16_t data) +{ + wc_wrreg(ess, ch << 3, data); +} + +/* Power management */ + +static inline void +agg_power(struct agg_info *ess, int status) +{ + u_int8_t data; + + data = pci_read_config(ess->dev, CONF_PM_PTR, 1); + if (pci_read_config(ess->dev, data, 1) == PPMI_CID) + pci_write_config(ess->dev, data + PM_CTRL, status, 1); +} + + +/* ----------------------------- + * Controller. + */ + +static inline void +agg_initcodec(struct agg_info* ess) +{ + u_int16_t data; + + if (bus_space_read_4(ess->st, ess->sh, PORT_RINGBUS_CTRL) + & RINGBUS_CTRL_ACLINK_ENABLED) { + bus_space_write_4(ess->st, ess->sh, PORT_RINGBUS_CTRL, 0); + DELAY(104); /* 20.8us * (4 + 1) */ + } + /* XXX - 2nd codec should be looked at. */ + bus_space_write_4(ess->st, ess->sh, PORT_RINGBUS_CTRL, + RINGBUS_CTRL_AC97_SWRESET); + DELAY(2); + bus_space_write_4(ess->st, ess->sh, PORT_RINGBUS_CTRL, + RINGBUS_CTRL_ACLINK_ENABLED); + DELAY(21); + + agg_rdcodec(ess, 0); + if (bus_space_read_1(ess->st, ess->sh, PORT_CODEC_STAT) + & CODEC_STAT_MASK) { + bus_space_write_4(ess->st, ess->sh, PORT_RINGBUS_CTRL, 0); + DELAY(21); + + /* Try cold reset. */ + device_printf(ess->dev, "will perform cold reset.\n"); + data = bus_space_read_2(ess->st, ess->sh, PORT_GPIO_DIR); + if (pci_read_config(ess->dev, 0x58, 2) & 1) + data |= 0x10; + data |= 0x009 & + ~bus_space_read_2(ess->st, ess->sh, PORT_GPIO_DATA); + bus_space_write_2(ess->st, ess->sh, PORT_GPIO_MASK, 0xff6); + bus_space_write_2(ess->st, ess->sh, PORT_GPIO_DIR, + data | 0x009); + bus_space_write_2(ess->st, ess->sh, PORT_GPIO_DATA, 0x000); + DELAY(2); + bus_space_write_2(ess->st, ess->sh, PORT_GPIO_DATA, 0x001); + DELAY(1); + bus_space_write_2(ess->st, ess->sh, PORT_GPIO_DATA, 0x009); + DELAY(500000); + bus_space_write_2(ess->st, ess->sh, PORT_GPIO_DIR, data); + DELAY(84); /* 20.8us * 4 */ + bus_space_write_4(ess->st, ess->sh, PORT_RINGBUS_CTRL, + RINGBUS_CTRL_ACLINK_ENABLED); + DELAY(21); + } +} + +static void +agg_init(struct agg_info* ess) +{ + u_int32_t data; + + /* Setup PCI config registers. */ + + /* Disable all legacy emulations. */ + data = pci_read_config(ess->dev, CONF_LEGACY, 2); + data |= LEGACY_DISABLED; + pci_write_config(ess->dev, CONF_LEGACY, data, 2); + + /* Disconnect from CHI. (Makes Dell inspiron 7500 work?) + * Enable posted write. + * Prefer PCI timing rather than that of ISA. + * Don't swap L/R. */ + data = pci_read_config(ess->dev, CONF_MAESTRO, 4); + data |= MAESTRO_CHIBUS | MAESTRO_POSTEDWRITE | MAESTRO_DMA_PCITIMING; + data &= ~MAESTRO_SWAP_LR; + pci_write_config(ess->dev, CONF_MAESTRO, data, 4); + + /* Reset direct sound. */ + bus_space_write_2(ess->st, ess->sh, PORT_HOSTINT_CTRL, + HOSTINT_CTRL_DSOUND_RESET); + DELAY(10000); /* XXX - too long? */ + bus_space_write_2(ess->st, ess->sh, PORT_HOSTINT_CTRL, 0); + DELAY(10000); + + /* Enable direct sound interruption. */ + bus_space_write_2(ess->st, ess->sh, PORT_HOSTINT_CTRL, + HOSTINT_CTRL_DSOUND_INT_ENABLED); + + /* Setup Wave Processor. */ + + /* Enable WaveCache, set DMA base address. */ + wp_wrreg(ess, WPREG_WAVE_ROMRAM, + WP_WAVE_VIRTUAL_ENABLED | WP_WAVE_DRAM_ENABLED); + bus_space_write_2(ess->st, ess->sh, PORT_WAVCACHE_CTRL, + WAVCACHE_ENABLED | WAVCACHE_WTSIZE_4MB); + + for (data = WAVCACHE_PCMBAR; data < WAVCACHE_PCMBAR + 4; data++) + wc_wrreg(ess, data, ess->baseaddr >> WAVCACHE_BASEADDR_SHIFT); + + /* Setup Codec/Ringbus. */ + agg_initcodec(ess); + bus_space_write_4(ess->st, ess->sh, PORT_RINGBUS_CTRL, + RINGBUS_CTRL_RINGBUS_ENABLED | RINGBUS_CTRL_ACLINK_ENABLED); + + wp_wrreg(ess, WPREG_BASE, 0x8500); /* Parallel I/O */ + ringbus_setdest(ess, RINGBUS_SRC_ADC, + RINGBUS_DEST_STEREO | RINGBUS_DEST_DSOUND_IN); + ringbus_setdest(ess, RINGBUS_SRC_DSOUND, + RINGBUS_DEST_STEREO | RINGBUS_DEST_DAC); + + /* Setup ASSP. Needed for Dell Inspiron 7500? */ + bus_space_write_1(ess->st, ess->sh, PORT_ASSP_CTRL_B, 0x00); + bus_space_write_1(ess->st, ess->sh, PORT_ASSP_CTRL_A, 0x03); + bus_space_write_1(ess->st, ess->sh, PORT_ASSP_CTRL_C, 0x00); + + /* + * Setup GPIO. + * There seems to be speciality with NEC systems. + */ + switch (pci_get_subvendor(ess->dev) + | (pci_get_subdevice(ess->dev) << 16)) { + case NEC_SUBID1: + case NEC_SUBID2: + /* Matthew Braithwaite <matt@braithwaite.net> reported that + * NEC Versa LX doesn't need GPIO operation. */ + bus_space_write_2(ess->st, ess->sh, PORT_GPIO_MASK, 0x9ff); + bus_space_write_2(ess->st, ess->sh, PORT_GPIO_DIR, + bus_space_read_2(ess->st, ess->sh, PORT_GPIO_DIR) | 0x600); + bus_space_write_2(ess->st, ess->sh, PORT_GPIO_DATA, 0x200); + break; + } +} + +/* Channel controller. */ + +static void +aggch_start_dac(struct agg_chinfo *ch) +{ + u_int wpwa = APU_USE_SYSMEM | (ch->offset >> 9); + u_int size = AGG_BUFSIZ >> 1; + u_int speed = ch->channel->speed; + u_int offset = ch->offset >> 1; + u_int cp = ch->buffer->rp >> 1; + u_int16_t apuch = ch->num << 1; + u_int dv; + int pan = 0; + + switch (ch->aputype) { + case APUTYPE_16BITSTEREO: + wpwa >>= 1; + size >>= 1; + offset >>= 1; + cp >>= 1; + /* FALLTHROUGH */ + case APUTYPE_8BITSTEREO: + pan = 8; + apuch++; + break; + case APUTYPE_8BITLINEAR: + speed >>= 1; + break; + } + + dv = (((speed % 48000) << 16) + 24000) / 48000 + + ((speed / 48000) << 16); + + do { + wp_wrapu(ch->parent, apuch, APUREG_WAVESPACE, wpwa & 0xff00); + wp_wrapu(ch->parent, apuch, APUREG_CURPTR, offset + cp); + wp_wrapu(ch->parent, apuch, APUREG_ENDPTR, offset + size); + wp_wrapu(ch->parent, apuch, APUREG_LOOPLEN, size); + wp_wrapu(ch->parent, apuch, APUREG_AMPLITUDE, 0xe800); + wp_wrapu(ch->parent, apuch, APUREG_POSITION, 0x8f00 + | (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT) + | ((PAN_FRONT + pan) << APU_PAN_SHIFT)); + wp_wrapu(ch->parent, apuch, APUREG_FREQ_LOBYTE, APU_plus6dB + | ((dv & 0xff) << APU_FREQ_LOBYTE_SHIFT)); + wp_wrapu(ch->parent, apuch, APUREG_FREQ_HIWORD, dv >> 8); + + if (ch->aputype == APUTYPE_16BITSTEREO) + wpwa |= APU_STEREO >> 1; + pan = -pan; + } while (pan < 0 && apuch--); + + wc_wrchctl(ch->parent, apuch, ch->wcreg_tpl); + wc_wrchctl(ch->parent, apuch + 1, ch->wcreg_tpl); + + wp_wrapu(ch->parent, apuch, APUREG_APUTYPE, + (ch->aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); + if (ch->wcreg_tpl & WAVCACHE_CHCTL_STEREO) + wp_wrapu(ch->parent, apuch + 1, APUREG_APUTYPE, + (ch->aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); +} + +static void +aggch_stop_dac(struct agg_chinfo *ch) +{ + wp_wrapu(ch->parent, (ch->num << 1), APUREG_APUTYPE, + APUTYPE_INACTIVE << APU_APUTYPE_SHIFT); + wp_wrapu(ch->parent, (ch->num << 1) + 1, APUREG_APUTYPE, + APUTYPE_INACTIVE << APU_APUTYPE_SHIFT); +} + +/* + * Stereo jitter suppressor. + * Sometimes playback pointers differ in stereo-paired channels. + * Calling this routine within intr fixes the problem. + */ +static inline void +suppress_jitter(struct agg_chinfo *ch) +{ + if (ch->wcreg_tpl & WAVCACHE_CHCTL_STEREO) { + int cp, diff, halfsize = AGG_BUFSIZ >> 2; + + if (ch->aputype == APUTYPE_16BITSTEREO) + halfsize >>= 1; + cp = wp_rdapu(ch->parent, (ch->num << 1), APUREG_CURPTR); + diff = wp_rdapu(ch->parent, (ch->num << 1) + 1, APUREG_CURPTR); + diff -= cp; + if (diff >> 1 && diff > -halfsize && diff < halfsize) + bus_space_write_2(ch->parent->st, ch->parent->sh, + PORT_DSP_DATA, cp); + } +} + +static inline u_int +calc_timer_freq(struct agg_chinfo *ch) +{ + u_int ss = 2; + + if (ch->aputype == APUTYPE_16BITSTEREO) + ss <<= 1; + if (ch->aputype == APUTYPE_8BITLINEAR) + ss >>= 1; + + return (ch->channel->speed * ss + ch->blocksize - 1) / ch->blocksize; +} + +static void +set_timer(struct agg_info *ess) +{ + int i; + u_int freq = 0; + + for (i = 0; i < ess->playchns; i++) + if ((ess->active & (1 << i)) && + (freq < calc_timer_freq(ess->pch + i))) + freq = calc_timer_freq(ess->pch + i); + + wp_settimer(ess, freq); +} + + +/* ----------------------------- + * Newpcm glue. + */ + +static u_int32_t +agg_ac97_init(void *sc) +{ + struct agg_info *ess = sc; + + return (bus_space_read_1(ess->st, ess->sh, PORT_CODEC_STAT) & CODEC_STAT_MASK)? 0 : 1; +} + +static void * +aggch_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +{ + struct agg_info *ess = devinfo; + struct agg_chinfo *ch; + bus_addr_t physaddr; + + ch = (dir == PCMDIR_PLAY)? ess->pch + ess->playchns : &ess->rch; + + ch->parent = ess; + ch->channel = c; + ch->buffer = b; + ch->num = ess->playchns; + ch->dir = dir; + + b->buf = dma_malloc(ess, AGG_BUFSIZ, &physaddr); + if (b->buf == NULL) + return NULL; + + ch->offset = physaddr - ess->baseaddr; + if (physaddr < ess->baseaddr || ch->offset > WPWA_MAXADDR) { + device_printf(ess->dev, + "offset %#x exceeds limit. ", ch->offset); + dma_free(ess, b->buf); + b->buf = NULL; + return NULL; + } + + b->bufsize = AGG_BUFSIZ; + ch->wcreg_tpl = (physaddr - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK; + + if (dir == PCMDIR_PLAY) { + ess->playchns++; + if (bootverbose) + device_printf(ess->dev, "pch[%d].offset = %#x\n", ch->num, ch->offset); + } else if (bootverbose) + device_printf(ess->dev, "rch.offset = %#x\n", ch->offset); + + return ch; +} + +static int +aggch_free(void *data) +{ + struct agg_chinfo *ch = data; + struct agg_info *ess = ch->parent; + + /* free up buffer - called after channel stopped */ + dma_free(ess, ch->buffer->buf); + + /* return 0 if ok */ + return 0; +} + +static int +aggch_setplayformat(void *data, u_int32_t format) +{ + struct agg_chinfo *ch = data; + u_int16_t wcreg_tpl; + u_int16_t aputype = APUTYPE_16BITLINEAR; + + wcreg_tpl = ch->wcreg_tpl & WAVCACHE_CHCTL_ADDRTAG_MASK; + + if (format & AFMT_STEREO) { + wcreg_tpl |= WAVCACHE_CHCTL_STEREO; + aputype += 1; + } + if (format & AFMT_U8 || format & AFMT_S8) { + aputype += 2; + if (format & AFMT_U8) + wcreg_tpl |= WAVCACHE_CHCTL_U8; + } + if (format & AFMT_BIGENDIAN || format & AFMT_U16_LE) { + format &= ~AFMT_BIGENDIAN & ~AFMT_U16_LE; + format |= AFMT_S16_LE; + } + ch->wcreg_tpl = wcreg_tpl; + ch->aputype = aputype; + return format; +} + +static int +aggch_setspeed(void *data, u_int32_t speed) +{ + return speed; +} + +static int +aggch_setblocksize(void *data, u_int32_t blocksize) +{ + return ((struct agg_chinfo*)data)->blocksize = blocksize; +} + +static int +aggch_trigger(void *data, int go) +{ + struct agg_chinfo *ch = data; + + switch (go) { + case PCMTRIG_EMLDMAWR: + return 0; + case PCMTRIG_START: + ch->parent->active |= (1 << ch->num); + if (ch->dir == PCMDIR_PLAY) + aggch_start_dac(ch); +#if 0 /* XXX - RECORDING */ + else + aggch_start_adc(ch); +#endif + break; + case PCMTRIG_ABORT: + case PCMTRIG_STOP: + ch->parent->active &= ~(1 << ch->num); + if (ch->dir == PCMDIR_PLAY) + aggch_stop_dac(ch); +#if 0 /* XXX - RECORDING */ + else + aggch_stop_adc(ch); +#endif + break; + } + + if (ch->parent->active) { + set_timer(ch->parent); + wp_starttimer(ch->parent); + } else + wp_stoptimer(ch->parent); + + return 0; +} + +static int +aggch_getplayptr(void *data) +{ + struct agg_chinfo *ch = data; + u_int cp; + + cp = wp_rdapu(ch->parent, (ch->num << 1), APUREG_CURPTR); + if (ch->aputype == APUTYPE_16BITSTEREO) + cp = (0xffff << 2) & ((cp << 2) - ch->offset); + else + cp = (0xffff << 1) & ((cp << 1) - ch->offset); + + return cp; +} + +static pcmchan_caps * +aggch_getcaps(void *data) +{ + static u_int32_t playfmt[] = { + AFMT_U8, + AFMT_STEREO | AFMT_U8, + AFMT_S8, + AFMT_STEREO | AFMT_S8, + AFMT_S16_LE, + AFMT_STEREO | AFMT_S16_LE, + 0 + }; + static pcmchan_caps playcaps = {2000, 96000, playfmt, 0}; + + static u_int32_t recfmt[] = { + AFMT_S8, + AFMT_STEREO | AFMT_S8, + AFMT_S16_LE, + AFMT_STEREO | AFMT_S16_LE, + 0 + }; + static pcmchan_caps reccaps = {4000, 48000, recfmt, 0}; + + return (((struct agg_chinfo*)data)->dir == PCMDIR_PLAY)? + &playcaps : &reccaps; +} + + +/* ----------------------------- + * Bus space. + */ + +static void +agg_intr(void *sc) +{ + struct agg_info* ess = sc; + u_int16_t status; + int i; + + status = bus_space_read_1(ess->st, ess->sh, PORT_HOSTINT_STAT); + if (!status) + return; + + /* Acknowledge all. */ + bus_space_write_2(ess->st, ess->sh, PORT_INT_STAT, 1); + bus_space_write_1(ess->st, ess->sh, PORT_HOSTINT_STAT, 0); +#if 0 /* XXX - HWVOL */ + if (status & HOSTINT_STAT_HWVOL) { + u_int delta; + delta = bus_space_read_1(ess->st, ess->sh, PORT_HWVOL_MASTER) + - 0x88; + if (delta & 0x11) + mixer_set(device_get_softc(ess->dev), + SOUND_MIXER_VOLUME, 0); + else { + mixer_set(device_get_softc(ess->dev), + SOUND_MIXER_VOLUME, + mixer_get(device_get_softc(ess->dev), + SOUND_MIXER_VOLUME) + + ((delta >> 5) & 0x7) - 4 + + ((delta << 7) & 0x700) - 0x400); + } + bus_space_write_1(ess->st, ess->sh, PORT_HWVOL_MASTER, 0x88); + } +#endif /* XXX - HWVOL */ + + for (i = 0; i < ess->playchns; i++) + if (ess->active & (1 << i)) { + suppress_jitter(ess->pch + i); + chn_intr(ess->pch[i].channel); + } +#if 0 /* XXX - RECORDING */ + if (ess->active & (1 << i)) + chn_intr(ess->rch.channel); +#endif +} + +static void +setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + bus_addr_t *phys = arg; + + *phys = error? 0 : segs->ds_addr; + + if (bootverbose) { + printf("setmap (%lx, %lx), nseg=%d, error=%d\n", + (unsigned long)segs->ds_addr, (unsigned long)segs->ds_len, + nseg, error); + } +} + +static void * +dma_malloc(struct agg_info *sc, u_int32_t sz, bus_addr_t *phys) +{ + void *buf; + bus_dmamap_t map; + + if (bus_dmamem_alloc(sc->parent_dmat, &buf, BUS_DMA_NOWAIT, &map)) + return NULL; + if (bus_dmamap_load(sc->parent_dmat, map, buf, sz, setmap, phys, 0) + || !*phys) { + bus_dmamem_free(sc->parent_dmat, buf, map); + return NULL; + } + return buf; +} + +static void +dma_free(struct agg_info *sc, void *buf) +{ + bus_dmamem_free(sc->parent_dmat, buf, NULL); +} + +static int +agg_probe(device_t dev) +{ + char *s = NULL; + + switch (pci_get_devid(dev)) { + case MAESTRO_1_PCI_ID: + s = "ESS Technology Maestro-1"; + break; + + case MAESTRO_2_PCI_ID: + s = "ESS Technology Maestro-2"; + break; + + case MAESTRO_2E_PCI_ID: + s = "ESS Technology Maestro-2E"; + break; + } + + if (s != NULL && pci_get_class(dev) == PCIC_MULTIMEDIA) { + device_set_desc(dev, s); + return 0; + } + return ENXIO; +} + +static int +agg_attach(device_t dev) +{ + struct agg_info *ess = NULL; + u_int32_t data; + int mapped = 0; + int regid = PCIR_MAPS; + struct resource *reg = NULL; + struct ac97_info *codec = NULL; + int irqid = 0; + struct resource *irq = NULL; + void *ih = NULL; + char status[SND_STATUSLEN]; + static pcm_channel agg_pchtpl = { + aggch_init, + NULL, /* setdir */ + aggch_setplayformat, + aggch_setspeed, + aggch_setblocksize, + aggch_trigger, + aggch_getplayptr, + aggch_getcaps, + aggch_free, /* free */ + NULL, /* nop1 */ + NULL, /* nop2 */ + NULL, /* nop3 */ + NULL, /* nop4 */ + NULL, /* nop5 */ + NULL, /* nop6 */ + NULL, /* nop7 */ + }; + + if ((ess = malloc(sizeof *ess, M_DEVBUF, M_NOWAIT)) == NULL) { + device_printf(dev, "cannot allocate softc\n"); + return ENXIO; + } + bzero(ess, sizeof *ess); + ess->dev = dev; + + if (bus_dma_tag_create(/*parent*/NULL, + /*alignment*/1 << WAVCACHE_BASEADDR_SHIFT, + /*boundary*/WPWA_MAXADDR + 1, + /*lowaddr*/MAESTRO_MAXADDR, /*highaddr*/BUS_SPACE_MAXADDR, + /*filter*/NULL, /*filterarg*/NULL, + /*maxsize*/AGG_BUFSIZ * 2, /*nsegments*/1, /*maxsegz*/0x3ffff, + /*flags*/0, &ess->parent_dmat) != 0) { + device_printf(dev, "unable to create dma tag\n"); + goto bad; + } + + ess->stat = dma_malloc(ess, AGG_BUFSIZ, &ess->baseaddr); + if (ess->stat == NULL) { + device_printf(dev, "cannot allocate status buffer\n"); + goto bad; + } + if (bootverbose) + device_printf(dev, "Maestro DMA base: %#x\n", ess->baseaddr); + + agg_power(ess, PPMI_D0); + DELAY(100000); + + data = pci_read_config(dev, PCIR_COMMAND, 2); + data |= (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN); + pci_write_config(dev, PCIR_COMMAND, data, 2); + data = pci_read_config(dev, PCIR_COMMAND, 2); + + if (data & PCIM_CMD_PORTEN) { + reg = bus_alloc_resource(dev, SYS_RES_IOPORT, ®id, + 0, BUS_SPACE_UNRESTRICTED, 256, RF_ACTIVE); + if (reg != NULL) { + ess->reg = reg; + ess->regid = regid; + ess->st = rman_get_bustag(reg); + ess->sh = rman_get_bushandle(reg); + mapped++; + } + } + if (mapped == 0) { + device_printf(dev, "unable to map register space\n"); + goto bad; + } + + agg_init(ess); + if (agg_rdcodec(ess, 0) == 0x80) { + device_printf(dev, "PT101 codec detected!\n"); + goto bad; + } + codec = ac97_create(dev, ess, agg_ac97_init, agg_rdcodec, agg_wrcodec); + if (codec == NULL) + goto bad; + if (mixer_init(dev, &ac97_mixer, codec) == -1) + goto bad; + ess->codec = codec; + + irq = bus_alloc_resource(dev, SYS_RES_IRQ, &irqid, + 0, BUS_SPACE_UNRESTRICTED, 1, RF_ACTIVE | RF_SHAREABLE); + if (irq == NULL + || bus_setup_intr(dev, irq, INTR_TYPE_TTY, agg_intr, ess, &ih)) { + device_printf(dev, "unable to map interrupt\n"); + goto bad; + } + ess->irq = irq; + ess->irqid = irqid; + ess->ih = ih; + + snprintf(status, SND_STATUSLEN, "at I/O port 0x%lx irq %ld", + rman_get_start(reg), rman_get_start(irq)); + + if (pcm_register(dev, ess, AGG_MAXPLAYCH, 1)) + goto bad; + + for (data = 0; data < AGG_MAXPLAYCH; data++) + pcm_addchan(dev, PCMDIR_PLAY, &agg_pchtpl, ess); +#if 0 /* XXX - RECORDING */ + pcm_addchan(dev, PCMDIR_REC, &agg_rchtpl, ess); +#endif + pcm_setstatus(dev, status); + + return 0; + + bad: + if (codec != NULL) + ac97_destroy(codec); + if (ih != NULL) + bus_teardown_intr(dev, irq, ih); + if (irq != NULL) + bus_release_resource(dev, SYS_RES_IRQ, irqid, irq); + if (reg != NULL) + bus_release_resource(dev, SYS_RES_IOPORT, regid, reg); + if (ess != NULL) { + agg_power(ess, PPMI_D3); + if (ess->stat != NULL) + dma_free(ess, ess->stat); + if (ess->parent_dmat != NULL) + bus_dma_tag_destroy(ess->parent_dmat); + free(ess, M_DEVBUF); + } + + return ENXIO; +} + +static int +agg_detach(device_t dev) +{ + struct agg_info *ess = pcm_getdevinfo(dev); + int r; + + r = pcm_unregister(dev); + if (r) + return r; + + ess = pcm_getdevinfo(dev); + dma_free(ess, ess->stat); + + /* Power down everything except clock and vref. */ + agg_wrcodec(ess, AC97_REG_POWER, 0xd700); + DELAY(20); + bus_space_write_4(ess->st, ess->sh, PORT_RINGBUS_CTRL, 0); + agg_power(ess, PPMI_D3); + + bus_teardown_intr(dev, ess->irq, ess->ih); + bus_release_resource(dev, SYS_RES_IRQ, ess->irqid, ess->irq); + bus_release_resource(dev, SYS_RES_IOPORT, ess->regid, ess->reg); + bus_dma_tag_destroy(ess->parent_dmat); + free(ess, M_DEVBUF); + return 0; +} + +static int +agg_suspend(device_t dev) +{ + struct agg_info *ess = pcm_getdevinfo(dev); + int i, x; + + x = spltty(); + wp_stoptimer(ess); + bus_space_write_2(ess->st, ess->sh, PORT_HOSTINT_CTRL, 0); + + for (i = 0; i < ess->playchns; i++) + aggch_stop_dac(ess->pch + i); + +#if 0 /* XXX - RECORDING */ + aggch_stop_adc(&ess->rch); +#endif + splx(x); + /* Power down everything except clock. */ + agg_wrcodec(ess, AC97_REG_POWER, 0xdf00); + DELAY(20); + bus_space_write_4(ess->st, ess->sh, PORT_RINGBUS_CTRL, 0); + DELAY(1); + agg_power(ess, PPMI_D3); + + return 0; +} + +static int +agg_resume(device_t dev) +{ + int i, x; + struct agg_info *ess = pcm_getdevinfo(dev); + + agg_power(ess, PPMI_D0); + DELAY(100000); + agg_init(ess); + if (mixer_reinit(dev)) { + device_printf(dev, "unable to reinitialize the mixer\n"); + return ENXIO; + } + + x = spltty(); + for (i = 0; i < ess->playchns; i++) + if (ess->active & (1 << i)) + aggch_start_dac(ess->pch + i); +#if 0 /* XXX - RECORDING */ + if (ess->active & (1 << i)) + aggch_start_adc(&ess->rch); +#endif + if (ess->active) { + set_timer(ess); + wp_starttimer(ess); + } + splx(x); + return 0; +} + +static int +agg_shutdown(device_t dev) +{ + struct agg_info *ess = pcm_getdevinfo(dev); + int i; + + wp_stoptimer(ess); + bus_space_write_2(ess->st, ess->sh, PORT_HOSTINT_CTRL, 0); + + for (i = 0; i < ess->playchns; i++) + aggch_stop_dac(ess->pch + i); + +#if 0 /* XXX - RECORDING */ + aggch_stop_adc(&ess->rch); +#endif + return 0; +} + + +static device_method_t agg_methods[] = { + DEVMETHOD(device_probe, agg_probe), + DEVMETHOD(device_attach, agg_attach), + DEVMETHOD(device_detach, agg_detach), + DEVMETHOD(device_suspend, agg_suspend), + DEVMETHOD(device_resume, agg_resume), + DEVMETHOD(device_shutdown, agg_shutdown), + + { 0, 0 } +}; + +static driver_t agg_driver = { + "pcm", + agg_methods, + sizeof(snddev_info), +}; + +static devclass_t pcm_devclass; + +DRIVER_MODULE(snd_maestro, pci, agg_driver, pcm_devclass, 0, 0); +MODULE_DEPEND(snd_maestro, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER); +MODULE_VERSION(snd_maestro, 1); diff --git a/sys/dev/sound/pci/maestro_reg.h b/sys/dev/sound/pci/maestro_reg.h new file mode 100644 index 000000000000..579723388d8e --- /dev/null +++ b/sys/dev/sound/pci/maestro_reg.h @@ -0,0 +1,345 @@ +/*- + * Copyright (c) 1999-2000 Taku YAMAMOTO <taku@cent.saitama-u.ac.jp> + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $Id: maestro_reg.h,v 1.10 2000/08/29 17:27:29 taku Exp $ + * $FreeBSD$ + */ + +#ifndef MAESTRO_REG_H_INCLUDED +#define MAESTRO_REG_H_INCLUDED + +/* ----------------------------- + * PCI config registers + */ + +/* Legacy emulation */ +#define CONF_LEGACY 0x40 + +#define LEGACY_DISABLED 0x8000 + +/* Chip configurations */ +#define CONF_MAESTRO 0x50 +#define MAESTRO_CHIBUS 0x00100000 +#define MAESTRO_POSTEDWRITE 0x00000080 +#define MAESTRO_DMA_PCITIMING 0x00000040 +#define MAESTRO_SWAP_LR 0x00000010 + +/* ACPI configurations */ +#define CONF_ACPI_STOPCLOCK 0x54 +#define ACPI_PART_2ndC_CLOCK 15 +#define ACPI_PART_CODEC_CLOCK 14 +#define ACPI_PART_978 13 /* Docking station or something */ +#define ACPI_PART_SPDIF 12 +#define ACPI_PART_GLUE 11 /* What? */ +#define ACPI_PART_DAA 10 +#define ACPI_PART_PCI_IF 9 +#define ACPI_PART_HW_VOL 8 +#define ACPI_PART_GPIO 7 +#define ACPI_PART_ASSP 6 +#define ACPI_PART_SB 5 +#define ACPI_PART_FM 4 +#define ACPI_PART_RINGBUS 3 +#define ACPI_PART_MIDI 2 +#define ACPI_PART_GAME_PORT 1 +#define ACPI_PART_WP 0 + +/* Power management */ +#define CONF_PM_PTR 0x34 /* BYTE R */ +#define PM_CID 0 /* BYTE R */ +#define PPMI_CID 1 +#define PM_CTRL 4 /* BYTE RW */ +#define PPMI_D0 0 /* Full power */ +#define PPMI_D1 1 /* Medium power */ +#define PPMI_D2 2 /* Low power */ +#define PPMI_D3 3 /* Turned off */ + + +/* ----------------------------- + * I/O ports + */ + +/* Direct Sound Processor (aka WP) */ +#define PORT_DSP_DATA 0x00 /* WORD RW */ +#define PORT_DSP_INDEX 0x02 /* WORD RW */ +#define PORT_INT_STAT 0x04 /* WORD RW */ +#define PORT_SAMPLE_CNT 0x06 /* WORD RO */ + +/* WaveCache */ +#define PORT_WAVCACHE_INDEX 0x10 /* WORD RW */ +#define PORT_WAVCACHE_DATA 0x12 /* WORD RW */ +#define WAVCACHE_PCMBAR 0x1fc +#define WAVCACHE_WTBAR 0x1f0 +#define WAVCACHE_BASEADDR_SHIFT 12 + +#define WAVCACHE_CHCTL_ADDRTAG_MASK 0xfff8 +#define WAVCACHE_CHCTL_U8 0x0004 +#define WAVCACHE_CHCTL_STEREO 0x0002 +#define WAVCACHE_CHCTL_DECREMENTAL 0x0001 + +#define PORT_WAVCACHE_CTRL 0x14 /* WORD RW */ +#define WAVCACHE_EXTRA_CH_ENABLED 0x0200 +#define WAVCACHE_ENABLED 0x0100 +#define WAVCACHE_CH_60_ENABLED 0x0080 +#define WAVCACHE_WTSIZE_MASK 0x0060 +#define WAVCACHE_WTSIZE_1MB 0x0000 +#define WAVCACHE_WTSIZE_2MB 0x0020 +#define WAVCACHE_WTSIZE_4MB 0x0040 +#define WAVCACHE_WTSIZE_8MB 0x0060 +#define WAVCACHE_SGC_MASK 0x000c +#define WAVCACHE_SGC_DISABLED 0x0000 +#define WAVCACHE_SGC_40_47 0x0004 +#define WAVCACHE_SGC_32_47 0x0008 +#define WAVCACHE_TESTMODE 0x0001 + +/* Host Interruption */ +#define PORT_HOSTINT_CTRL 0x18 /* WORD RW */ +#define HOSTINT_CTRL_SOFT_RESET 0x8000 +#define HOSTINT_CTRL_DSOUND_RESET 0x4000 +#define HOSTINT_CTRL_HW_VOL_TO_PME 0x0400 +#define HOSTINT_CTRL_CLKRUN_ENABLED 0x0100 +#define HOSTINT_CTRL_HWVOL_ENABLED 0x0040 +#define HOSTINT_CTRL_ASSP_INT_ENABLED 0x0010 +#define HOSTINT_CTRL_ISDN_INT_ENABLED 0x0008 +#define HOSTINT_CTRL_DSOUND_INT_ENABLED 0x0004 +#define HOSTINT_CTRL_MPU401_INT_ENABLED 0x0002 +#define HOSTINT_CTRL_SB_INT_ENABLED 0x0001 + +#define PORT_HOSTINT_STAT 0x1a /* BYTE RW */ +#define HOSTINT_STAT_HWVOL 0x40 +#define HOSTINT_STAT_ASSP 0x10 +#define HOSTINT_STAT_ISDN 0x08 +#define HOSTINT_STAT_DSOUND 0x04 +#define HOSTINT_STAT_MPU401 0x02 +#define HOSTINT_STAT_SB 0x01 + +/* Hardware volume */ +#define PORT_HWVOL_VOICE_SHADOW 0x1c /* BYTE RW */ +#define PORT_HWVOL_VOICE 0x1d /* BYTE RW */ +#define PORT_HWVOL_MASTER_SHADOW 0x1e /* BYTE RW */ +#define PORT_HWVOL_MASTER 0x1f /* BYTE RW */ + +/* CODEC */ +#define PORT_CODEC_CMD 0x30 /* BYTE W */ +#define CODEC_CMD_READ 0x80 +#define CODEC_CMD_WRITE 0x00 +#define CODEC_CMD_ADDR_MASK 0x7f + +#define PORT_CODEC_STAT 0x30 /* BYTE R */ +#define CODEC_STAT_MASK 0x01 +#define CODEC_STAT_RW_DONE 0x00 +#define CODEC_STAT_PROGLESS 0x01 + +#define PORT_CODEC_REG 0x32 /* WORD RW */ + +/* Ring bus control */ +#define PORT_RINGBUS_CTRL 0x34 /* DWORD RW */ +#define RINGBUS_CTRL_I2S_ENABLED 0x80000000 +#define RINGBUS_CTRL_RINGBUS_ENABLED 0x20000000 +#define RINGBUS_CTRL_ACLINK_ENABLED 0x10000000 +#define RINGBUS_CTRL_AC97_SWRESET 0x08000000 +#define RINGBUS_CTRL_IODMA_PLAYBACK_ENABLED 0x04000000 +#define RINGBUS_CTRL_IODMA_RECORD_ENABLED 0x02000000 + +#define RINGBUS_SRC_MIC 20 +#define RINGBUS_SRC_I2S 16 +#define RINGBUS_SRC_ADC 12 +#define RINGBUS_SRC_MODEM 8 +#define RINGBUS_SRC_DSOUND 4 +#define RINGBUS_SRC_ASSP 0 + +#define RINGBUS_DEST_MONORAL 000 +#define RINGBUS_DEST_STEREO 010 +#define RINGBUS_DEST_NONE 0 +#define RINGBUS_DEST_DAC 1 +#define RINGBUS_DEST_MODEM_IN 2 +#define RINGBUS_DEST_RESERVED3 3 +#define RINGBUS_DEST_DSOUND_IN 4 +#define RINGBUS_DEST_ASSP_IN 5 + +/* General Purpose I/O */ +#define PORT_GPIO_DATA 0x60 /* WORD RW */ +#define PORT_GPIO_MASK 0x64 /* WORD RW */ +#define PORT_GPIO_DIR 0x68 /* WORD RW */ + +/* Application Specific Signal Processor */ +#define PORT_ASSP_MEM_INDEX 0x80 /* DWORD RW */ +#define PORT_ASSP_MEM_DATA 0x84 /* WORD RW */ +#define PORT_ASSP_CTRL_A 0xa2 /* BYTE RW */ +#define PORT_ASSP_CTRL_B 0xa4 /* BYTE RW */ +#define PORT_ASSP_CTRL_C 0xa6 /* BYTE RW */ +#define PORT_ASSP_HOST_WR_INDEX 0xa8 /* BYTE W */ +#define PORT_ASSP_HOST_WR_DATA 0xaa /* BYTE RW */ +#define PORT_ASSP_INT_STAT 0xac /* BYTE RW */ + + +/* ----------------------------- + * Wave Processor Indexed Data Registers. + */ + +#define WPREG_DATA_PORT 0 +#define WPREG_CRAM_PTR 1 +#define WPREG_CRAM_DATA 2 +#define WPREG_WAVE_DATA 3 +#define WPREG_WAVE_PTR_LOW 4 +#define WPREG_WAVE_PTR_HIGH 5 + +#define WPREG_TIMER_FREQ 6 +#define WP_TIMER_FREQ_PRESCALE_MASK 0x00e0 /* actual - 9 */ +#define WP_TIMER_FREQ_PRESCALE_SHIFT 5 +#define WP_TIMER_FREQ_DIVIDE_MASK 0x001f +#define WP_TIMER_FREQ_DIVIDE_SHIFT 0 + +#define WPREG_WAVE_ROMRAM 7 +#define WP_WAVE_VIRTUAL_ENABLED 0x0400 +#define WP_WAVE_8BITRAM_ENABLED 0x0200 +#define WP_WAVE_DRAM_ENABLED 0x0100 +#define WP_WAVE_RAMSPLIT_MASK 0x00ff +#define WP_WAVE_RAMSPLIT_SHIFT 0 + +#define WPREG_BASE 12 +#define WP_PARAOUT_BASE_MASK 0xf000 +#define WP_PARAOUT_BASE_SHIFT 12 +#define WP_PARAIN_BASE_MASK 0x0f00 +#define WP_PARAIN_BASE_SHIFT 8 +#define WP_SERIAL0_BASE_MASK 0x00f0 +#define WP_SERIAL0_BASE_SHIFT 4 +#define WP_SERIAL1_BASE_MASK 0x000f +#define WP_SERIAL1_BASE_SHIFT 0 + +#define WPREG_TIMER_ENABLE 17 +#define WPREG_TIMER_START 23 + + +/* ----------------------------- + * Audio Processing Unit. + */ +#define APUREG_APUTYPE 0 +#define APU_DMA_ENABLED 0x4000 +#define APU_INT_ON_LOOP 0x2000 +#define APU_ENDCURVE 0x1000 +#define APU_APUTYPE_MASK 0x00f0 +#define APU_FILTERTYPE_MASK 0x000c +#define APU_FILTERQ_MASK 0x0003 + +/* APU types */ +#define APU_APUTYPE_SHIFT 4 + +#define APUTYPE_INACTIVE 0 +#define APUTYPE_16BITLINEAR 1 +#define APUTYPE_16BITSTEREO 2 +#define APUTYPE_8BITLINEAR 3 +#define APUTYPE_8BITSTEREO 4 +#define APUTYPE_8BITDIFF 5 +#define APUTYPE_DIGITALDELAY 6 +#define APUTYPE_DUALTAP_READER 7 +#define APUTYPE_CORRELATOR 8 +#define APUTYPE_INPUTMIXER 9 +#define APUTYPE_WAVETABLE 10 +#define APUTYPE_RATECONV 11 +#define APUTYPE_16BITPINGPONG 12 +/* APU type 13 through 15 are reserved. */ + +/* Filter types */ +#define APU_FILTERTYPE_SHIFT 2 + +#define FILTERTYPE_2POLE_LOPASS 0 +#define FILTERTYPE_2POLE_BANDPASS 1 +#define FILTERTYPE_2POLE_HIPASS 2 +#define FILTERTYPE_1POLE_LOPASS 3 +#define FILTERTYPE_1POLE_HIPASS 4 +#define FILTERTYPE_PASSTHROUGH 5 + +/* Filter Q */ +#define APU_FILTERQ_SHIFT 0 + +#define FILTERQ_LESSQ 0 +#define FILTERQ_MOREQ 3 + +/* APU register 2 */ +#define APUREG_FREQ_LOBYTE 2 +#define APU_FREQ_LOBYTE_MASK 0xff00 +#define APU_plus6dB 0x0010 + +/* APU register 3 */ +#define APUREG_FREQ_HIWORD 3 +#define APU_FREQ_HIWORD_MASK 0x0fff + +/* Frequency */ +#define APU_FREQ_LOBYTE_SHIFT 8 +#define APU_FREQ_HIWORD_SHIFT 0 +#define FREQ_Hz2DIV(freq) (((u_int64_t)(freq) << 16) / 48000) + +/* APU register 4 */ +#define APUREG_WAVESPACE 4 +#define APU_STEREO 0x8000 +#define APU_USE_SYSMEM 0x4000 +#define APU_PCMBAR_MASK 0x6000 +#define APU_64KPAGE_MASK 0xff00 + +/* PCM Base Address Register selection */ +#define APU_PCMBAR_SHIFT 13 + +/* 64KW (==128KB) Page */ +#define APU_64KPAGE_SHIFT 8 + +/* APU register 5 - 7 */ +#define APUREG_CURPTR 5 +#define APUREG_ENDPTR 6 +#define APUREG_LOOPLEN 7 + +/* APU register 9 */ +#define APUREG_AMPLITUDE 9 +#define APU_AMPLITUDE_NOW_MASK 0xff00 +#define APU_AMPLITUDE_DEST_MASK 0x00ff + +/* Amplitude now? */ +#define APU_AMPLITUDE_NOW_SHIFT 8 + +/* APU register 10 */ +#define APUREG_POSITION 10 +#define APU_RADIUS_MASK 0x00c0 +#define APU_PAN_MASK 0x003f + +/* Radius control. */ +#define APU_RADIUS_SHIFT 6 +#define RADIUS_CENTERCIRCLE 0 +#define RADIUS_MIDDLE 1 +#define RADIUS_OUTSIDE 2 + +/* Polar pan. */ +#define APU_PAN_SHIFT 0 +#define PAN_RIGHT 0x00 +#define PAN_FRONT 0x08 +#define PAN_LEFT 0x10 + + +/* ----------------------------- + * Limits. + */ +#define WPWA_MAX ((1 << 22) - 1) +#define WPWA_MAXADDR ((1 << 23) - 1) +#define MAESTRO_MAXADDR ((1 << 28) - 1) + +#endif /* MAESTRO_REG_H_INCLUDED */ diff --git a/sys/dev/sound/pci/via82c686.c b/sys/dev/sound/pci/via82c686.c new file mode 100644 index 000000000000..df721366c3cf --- /dev/null +++ b/sys/dev/sound/pci/via82c686.c @@ -0,0 +1,689 @@ +/* + * Copyright (c) 2000 David Jones <dej@ox.org> + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include <dev/sound/pcm/sound.h> +#include <dev/sound/pcm/ac97.h> + +#include <pci/pcireg.h> +#include <pci/pcivar.h> +#include <sys/sysctl.h> + +#include <dev/sound/pci/via82c686.h> + +#define VIA_PCI_ID 0x30581106 +#define NSEGS 16 /* Number of segments in SGD table */ + +#define SEGS_PER_CHAN (NSEGS/2) + +#undef DEB +#define DEB(x) + +struct via_info; + +struct via_chinfo { + struct via_info *parent; + pcm_channel *channel; + snd_dbuf *buffer; + int dir; +}; + +struct via_info { + bus_space_tag_t st; + bus_space_handle_t sh; + bus_dma_tag_t parent_dmat; + bus_dma_tag_t sgd_dmat; + + struct resource *reg, *irq; + int regid, irqid; + void *ih; + + struct via_chinfo pch, rch; + struct via_dma_op *sgd_table; + u_int16_t codec_caps; +}; + +static u_int32_t via_rd(struct via_info *via, int regno, int size); +static void via_wr(struct via_info *, int regno, u_int32_t data, int size); + +int via_waitready_codec(struct via_info *via); +int via_waitvalid_codec(struct via_info *via); +u_int32_t via_read_codec(void *addr, int reg); +void via_write_codec(void *addr, int reg, u_int32_t val); + +static void via_intr(void *); +bus_dmamap_callback_t dma_cb; + + +/* channel interface */ +static void *viachan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir); +static int viachan_setdir(void *data, int dir); +static int viachan_setformat(void *data, u_int32_t format); +static int viachan_setspeed(void *data, u_int32_t speed); +static int viachan_setblocksize(void *data, u_int32_t blocksize); +static int viachan_trigger(void *data, int go); +static int viachan_getptr(void *data); +static pcmchan_caps *viachan_getcaps(void *data); + +static u_int32_t via_playfmt[] = { + AFMT_U8, + AFMT_STEREO | AFMT_U8, + AFMT_S16_LE, + AFMT_STEREO | AFMT_S16_LE, + 0 +}; +static pcmchan_caps via_playcaps = {4000, 48000, via_playfmt, 0}; + +static u_int32_t via_recfmt[] = { + AFMT_U8, + AFMT_STEREO | AFMT_U8, + AFMT_S16_LE, + AFMT_STEREO | AFMT_S16_LE, + 0 +}; +static pcmchan_caps via_reccaps = {4000, 48000, via_recfmt, 0}; + +static pcm_channel via_chantemplate = { + viachan_init, + viachan_setdir, + viachan_setformat, + viachan_setspeed, + viachan_setblocksize, + viachan_trigger, + viachan_getptr, + viachan_getcaps, + NULL, /* free */ + NULL, /* nop1 */ + NULL, /* nop2 */ + NULL, /* nop3 */ + NULL, /* nop4 */ + NULL, /* nop5 */ + NULL, /* nop6 */ + NULL, /* nop7 */ +}; + + +/* + * Probe and attach the card + */ +static int +via_probe(device_t dev) +{ + if (pci_get_devid(dev) == VIA_PCI_ID) { + device_set_desc(dev, "VIA VT82C686A AC'97 Audio"); + return 0; + } + return ENXIO; +} + + +void dma_cb(void *p, bus_dma_segment_t *bds, int a, int b) +{ +} + + +static int +via_attach(device_t dev) +{ + struct via_info *via = 0; + struct ac97_info *codec = 0; + char status[SND_STATUSLEN]; + + u_int32_t data; + + u_int16_t v; + bus_dmamap_t sgd_dma_map; + + if ((via = malloc(sizeof *via, M_DEVBUF, M_NOWAIT)) == NULL) { + device_printf(dev, "cannot allocate softc\n"); + return ENXIO; + } + bzero(via, sizeof *via); + + /* Get resources */ + data = pci_read_config(dev, PCIR_COMMAND, 2); + data |= (PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN); + pci_write_config(dev, PCIR_COMMAND, data, 2); + data = pci_read_config(dev, PCIR_COMMAND, 2); + + pci_write_config(dev, VIA_PCICONF_MISC, + VIA_PCICONF_ACLINKENAB | VIA_PCICONF_ACSGD | + VIA_PCICONF_ACNOTRST | VIA_PCICONF_ACVSR, 1); + + via->regid = PCIR_MAPS; + via->reg = bus_alloc_resource(dev, SYS_RES_IOPORT, &via->regid, + 0, ~0, 1, RF_ACTIVE); + if (!via->reg) { + device_printf(dev, "via: Cannot allocate bus resource."); + goto bad; + } + via->st = rman_get_bustag(via->reg); + via->sh = rman_get_bushandle(via->reg); + + via->irqid = 0; + via->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &via->irqid, + 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); + if (!via->irq + || bus_setup_intr(dev, via->irq, INTR_TYPE_TTY, via_intr, via, &via->ih)){ + device_printf(dev, "unable to map interrupt\n"); + goto bad; + } + + via_wr(via, VIA_PLAY_MODE, + VIA_RPMODE_AUTOSTART | + VIA_RPMODE_INTR_FLAG | VIA_RPMODE_INTR_EOL, 1); + via_wr(via, VIA_RECORD_MODE, + VIA_RPMODE_AUTOSTART | + VIA_RPMODE_INTR_FLAG | VIA_RPMODE_INTR_EOL, 1); + + codec = ac97_create(dev, via, NULL, + via_read_codec, via_write_codec); + if (!codec) goto bad; + + mixer_init(dev, &ac97_mixer, codec); + + /* + * The mixer init resets the codec. So enabling VRA must be done + * afterwards. + */ + v = via_read_codec(via, AC97_REG_EXT_AUDIO_ID); + v &= (AC97_ENAB_VRA | AC97_ENAB_MICVRA); + via_write_codec(via, AC97_REG_EXT_AUDIO_STAT, v); + via->codec_caps = v; + { + v = via_read_codec(via, AC97_REG_EXT_AUDIO_STAT); + DEB(printf("init: codec stat: %d\n", v)); + } + + if (!(v & AC97_CODEC_DOES_VRA)) { + /* no VRA => can do only 48 kbps */ + via_playcaps.minspeed = 48000; + via_reccaps.minspeed = 48000; + } + + /* DMA tag for buffers */ + if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, + /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, + /*highaddr*/BUS_SPACE_MAXADDR, + /*filter*/NULL, /*filterarg*/NULL, + /*maxsize*/VIA_BUFFSIZE, /*nsegments*/1, /*maxsegz*/0x3ffff, + /*flags*/0, &via->parent_dmat) != 0) { + device_printf(dev, "unable to create dma tag\n"); + goto bad; + } + + /* + * DMA tag for SGD table. The 686 uses scatter/gather DMA and + * requires a list in memory of work to do. We need only 16 bytes + * for this list, and it is wasteful to allocate 16K. + */ + if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, + /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, + /*highaddr*/BUS_SPACE_MAXADDR, + /*filter*/NULL, /*filterarg*/NULL, + /*maxsize*/NSEGS * sizeof(struct via_dma_op), + /*nsegments*/1, /*maxsegz*/0x3ffff, + /*flags*/0, &via->sgd_dmat) != 0) { + device_printf(dev, "unable to create dma tag\n"); + goto bad; + } + + if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table, + BUS_DMA_NOWAIT, &sgd_dma_map) == -1) goto bad; + if (bus_dmamap_load(via->sgd_dmat, sgd_dma_map, via->sgd_table, + NSEGS * sizeof(struct via_dma_op), dma_cb, 0, 0)) goto bad; + + snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld", + rman_get_start(via->reg), rman_get_start(via->irq)); + + /* Register */ + if (pcm_register(dev, via, 1, 1)) goto bad; + pcm_addchan(dev, PCMDIR_PLAY, &via_chantemplate, via); + pcm_addchan(dev, PCMDIR_REC, &via_chantemplate, via); + pcm_setstatus(dev, status); + return 0; +bad: + if (codec) ac97_destroy(codec); + if (via->reg) bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); + if (via->ih) bus_teardown_intr(dev, via->irq, via->ih); + if (via->irq) bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); + if (via->parent_dmat) bus_dma_tag_destroy(via->parent_dmat); + if (via->sgd_dmat) bus_dma_tag_destroy(via->sgd_dmat); + if (via) free(via, M_DEVBUF); + return ENXIO; +} + +static int +via_detach(device_t dev) +{ + int r; + struct via_info *via = 0; + + r = pcm_unregister(dev); + if (r) + return r; + + via = pcm_getdevinfo(dev); + bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); + bus_teardown_intr(dev, via->irq, via->ih); + bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); + bus_dma_tag_destroy(via->parent_dmat); + bus_dma_tag_destroy(via->sgd_dmat); + free(via, M_DEVBUF); + return 0; +} + + +static device_method_t via_methods[] = { + DEVMETHOD(device_probe, via_probe), + DEVMETHOD(device_attach, via_attach), + DEVMETHOD(device_detach, via_detach), + { 0, 0} +}; + +static driver_t via_driver = { + "pcm", + via_methods, + sizeof(snddev_info), +}; + +static devclass_t pcm_devclass; + +DRIVER_MODULE(via, pci, via_driver, pcm_devclass, 0, 0); +MODULE_DEPEND(via, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER); +MODULE_VERSION(via, 1); + + +static u_int32_t +via_rd(struct via_info *via, int regno, int size) +{ + + switch (size) { + case 1: + return bus_space_read_1(via->st, via->sh, regno); + case 2: + return bus_space_read_2(via->st, via->sh, regno); + case 4: + return bus_space_read_4(via->st, via->sh, regno); + default: + return 0xFFFFFFFF; + } +} + + +static void +via_wr(struct via_info *via, int regno, u_int32_t data, int size) +{ + + switch (size) { + case 1: + bus_space_write_1(via->st, via->sh, regno, data); + break; + case 2: + bus_space_write_2(via->st, via->sh, regno, data); + break; + case 4: + bus_space_write_4(via->st, via->sh, regno, data); + break; + } +} + + +/* Codec interface */ +int +via_waitready_codec(struct via_info *via) +{ + int i; + + /* poll until codec not busy */ + for (i = 0; (i < TIMEOUT) && + (via_rd(via, VIA_CODEC_CTL, 4) & VIA_CODEC_BUSY); i++) + DELAY(1); + if (i >= TIMEOUT) { + printf("via: codec busy\n"); + return 1; + } + + return 0; +} + + +int +via_waitvalid_codec(struct via_info *via) +{ + int i; + + /* poll until codec valid */ + for (i = 0; (i < TIMEOUT) && + !(via_rd(via, VIA_CODEC_CTL, 4) & VIA_CODEC_PRIVALID); i++) + DELAY(1); + if (i >= TIMEOUT) { + printf("via: codec invalid\n"); + return 1; + } + + return 0; +} + + +void +via_write_codec(void *addr, int reg, u_int32_t val) +{ + struct via_info *via = addr; + + if (via_waitready_codec(via)) return; + + via_wr(via, VIA_CODEC_CTL, + VIA_CODEC_PRIVALID | VIA_CODEC_INDEX(reg) | val, 4); +} + + +u_int32_t +via_read_codec(void *addr, int reg) +{ + struct via_info *via = addr; + + if (via_waitready_codec(via)) + return 1; + + via_wr(via, VIA_CODEC_CTL, + VIA_CODEC_PRIVALID | VIA_CODEC_READ | VIA_CODEC_INDEX(reg),4); + + if (via_waitready_codec(via)) + return 1; + + if (via_waitvalid_codec(via)) + return 1; + + return via_rd(via, VIA_CODEC_CTL, 2); +} + + +/* channel interface */ +static void * +viachan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) +{ + struct via_info *via = devinfo; + struct via_chinfo *ch = (dir == PCMDIR_PLAY) ? &via->pch : &via->rch; + + ch->parent = via; + ch->channel = c; + ch->buffer = b; + b->bufsize = VIA_BUFFSIZE; + + if (chn_allocbuf(ch->buffer, via->parent_dmat) == -1) return NULL; + return ch; +} + +static int +viachan_setdir(void *data, int dir) +{ + struct via_chinfo *ch = data; + struct via_info *via = ch->parent; + struct via_dma_op *ado; + int i, chunk_size; + int phys_addr, flag; + + ch->dir = dir; + /* + * Build the scatter/gather DMA (SGD) table. + * There are four slots in the table: two for play, two for record. + * This creates two half-buffers, one of which is playing; the other + * is feeding. + */ + ado = via->sgd_table; + chunk_size = ch->buffer->bufsize / SEGS_PER_CHAN; + + if (dir == PCMDIR_REC) { + ado += SEGS_PER_CHAN; + } + +DEB(printf("SGD table located at va %p\n", ado)); + phys_addr = vtophys(ch->buffer->buf); + for (i = 0; i < SEGS_PER_CHAN; i++) { + ado->ptr = phys_addr; + flag = (i == SEGS_PER_CHAN-1) ? + VIA_DMAOP_EOL : VIA_DMAOP_FLAG; + ado->flags = flag | chunk_size; +DEB(printf("ado->ptr/flags = %x/%x\n", phys_addr, flag)); + phys_addr += chunk_size; + ado++; + } + return 0; +} + +static int +viachan_setformat(void *data, u_int32_t format) +{ + struct via_chinfo *ch = data; + struct via_info *via = ch->parent; + int mode, mode_set; + + mode_set = 0; + if (format & AFMT_STEREO) + mode_set |= VIA_RPMODE_STEREO; + if (format & AFMT_S16_LE) + mode_set |= VIA_RPMODE_16BIT; + + /* Set up for output format */ + if (ch->dir == PCMDIR_PLAY) { +DEB(printf("set play format: %x\n", format)); + mode = via_rd(via, VIA_PLAY_MODE, 1); + mode &= ~(VIA_RPMODE_16BIT | VIA_RPMODE_STEREO); + mode |= mode_set; + via_wr(via, VIA_PLAY_MODE, mode, 1); + } + else { +DEB(printf("set record format: %x\n", format)); + mode = via_rd(via, VIA_RECORD_MODE, 1); + mode &= ~(VIA_RPMODE_16BIT | VIA_RPMODE_STEREO); + mode |= mode_set; + via_wr(via, VIA_RECORD_MODE, mode, 1); + } + + return 0; +} + +static int +viachan_setspeed(void *data, u_int32_t speed) +{ + struct via_chinfo *ch = data; + struct via_info *via = ch->parent; + + /* + * Basic AC'97 defines a 48 kHz sample rate only. For other rates, + * upsampling is required. + * + * The VT82C686A does not perform upsampling, and neither do we. + * If the codec supports variable-rate audio (i.e. does the upsampling + * itself), then negotiate the rate with the codec. Otherwise, + * return 48 kHz cuz that's all you got. + */ + if (ch->dir == PCMDIR_PLAY) { +DEB(printf("requested play speed: %d\n", speed)); + if (via->codec_caps & AC97_CODEC_DOES_VRA) { + via_write_codec(via, AC97_REG_EXT_DAC_RATE, speed); + speed = via_read_codec(via, AC97_REG_EXT_DAC_RATE); + } + else { +DEB(printf("VRA not supported!\n")); + speed = 48000; + } +DEB(printf("obtained play speed: %d\n", speed)); + } + else { +DEB(printf("requested record speed: %d\n", speed)); + if (via->codec_caps & AC97_CODEC_DOES_VRA) { + via_write_codec(via, AC97_REG_EXT_ADC_RATE, speed); + speed = via_read_codec(via, AC97_REG_EXT_ADC_RATE); + } + else { +DEB(printf("VRA not supported!\n")); + speed = 48000; + } +DEB(printf("obtained record speed: %d\n", speed)); + } + return speed; +} + +static int +viachan_setblocksize(void *data, u_int32_t blocksize) +{ + struct via_chinfo *ch = data; + + return ch->buffer->bufsize / 2; +} + +static int +viachan_trigger(void *data, int go) +{ + struct via_chinfo *ch = data; + struct via_info *via = ch->parent; + struct via_dma_op *ado; + + if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) return 0; + if (ch->dir == PCMDIR_PLAY) { + if (go == PCMTRIG_START) { + ado = &via->sgd_table[0]; +DEB(printf("ado located at va=%p pa=%x\n", ado, vtophys(ado))); + via_wr(via, VIA_PLAY_DMAOPS_BASE, vtophys(ado),4); + via_wr(via, VIA_PLAY_CONTROL, + VIA_RPCTRL_START, 1); + } + else { + /* Stop DMA */ + via_wr(via, VIA_PLAY_CONTROL, + VIA_RPCTRL_TERMINATE, 1); + } + } else { + if (go == PCMTRIG_START) { + ado = &via->sgd_table[SEGS_PER_CHAN]; +DEB(printf("ado located at va=%p pa=%x\n", ado, vtophys(ado))); + via_wr(via, VIA_RECORD_DMAOPS_BASE, + vtophys(ado),4); + via_wr(via, VIA_RECORD_CONTROL, + VIA_RPCTRL_START, 1); + } + else { + /* Stop DMA */ + via_wr(via, VIA_RECORD_CONTROL, + VIA_RPCTRL_TERMINATE, 1); + } + } + +DEB(printf("viachan_trigger: go=%d\n", go)); + return 0; +} + +static int +viachan_getptr(void *data) +{ + struct via_chinfo *ch = data; + struct via_info *via = ch->parent; + struct via_dma_op *ado; + int ptr, base, len, seg; + int base1; + + if (ch->dir == PCMDIR_PLAY) { + ado = &via->sgd_table[0]; + base1 = via_rd(via, VIA_PLAY_DMAOPS_BASE, 4); + len = via_rd(via, VIA_PLAY_DMAOPS_COUNT, 4); + base = via_rd(via, VIA_PLAY_DMAOPS_BASE, 4); + if (base != base1) { /* Avoid race hazzard */ + len = via_rd(via, VIA_PLAY_DMAOPS_COUNT, 4); + } +DEB(printf("viachan_getptr: len / base = %x / %x\n", len, base)); + + /* Base points to SGD segment to do, one past current */ + + /* Determine how many segments have been done */ + seg = (base - vtophys(ado)) / sizeof(struct via_dma_op); + if (seg == 0) seg = SEGS_PER_CHAN; + + /* Now work out offset: seg less count */ + ptr = seg * ch->buffer->bufsize / SEGS_PER_CHAN - len; +DEB(printf("return ptr=%d\n", ptr)); + return ptr; + } + else { + base1 = via_rd(via, VIA_RECORD_DMAOPS_BASE, 4); + ado = &via->sgd_table[SEGS_PER_CHAN]; + len = via_rd(via, VIA_RECORD_DMAOPS_COUNT, 4); + base = via_rd(via, VIA_RECORD_DMAOPS_BASE, 4); + if (base != base1) { /* Avoid race hazzard */ + len = via_rd(via, VIA_RECORD_DMAOPS_COUNT, 4); + } +DEB(printf("viachan_getptr: len / base = %x / %x\n", len, base)); + + /* Base points to next block to do, one past current */ + + /* Determine how many segments have been done */ + seg = (base - vtophys(ado)) / sizeof(struct via_dma_op); + if (seg == 0) seg = SEGS_PER_CHAN; + + /* Now work out offset: seg less count */ + ptr = seg * ch->buffer->bufsize / SEGS_PER_CHAN - len; + + /* DMA appears to operate on memory 'lines' of 32 bytes */ + /* so don't return any part line - it isn't in RAM yet */ + ptr = ptr & ~0x1f; +DEB(printf("return ptr=%d\n", ptr)); + return ptr; + } + return 0; +} + +static pcmchan_caps * +viachan_getcaps(void *data) +{ + struct via_chinfo *ch = data; + return (ch->dir == PCMDIR_PLAY) ? &via_playcaps : &via_reccaps; +} + +static void +via_intr(void *p) +{ + struct via_info *via = p; + int st; + +DEB(printf("viachan_intr\n")); + /* Read channel */ + st = via_rd(via, VIA_PLAY_STAT, 1); + if (st & VIA_RPSTAT_INTR) { + via_wr(via, VIA_PLAY_STAT, VIA_RPSTAT_INTR, 1); + chn_intr(via->pch.channel); + } + + /* Write channel */ + st = via_rd(via, VIA_RECORD_STAT, 1); + if (st & VIA_RPSTAT_INTR) { + via_wr(via, VIA_RECORD_STAT, VIA_RPSTAT_INTR, 1); + chn_intr(via->rch.channel); + } +} + + diff --git a/sys/modules/asr/Makefile b/sys/modules/asr/Makefile new file mode 100644 index 000000000000..ee0cd1c86a87 --- /dev/null +++ b/sys/modules/asr/Makefile @@ -0,0 +1,9 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/asr +KMOD = asr +SRCS = asr.c +SRCS += opt_scsi.h opt_cam.h opt_asr.h +SRCS += device_if.h bus_if.h pci_if.h + +.include <bsd.kmod.mk> diff --git a/sys/modules/bktr/bktr/Makefile b/sys/modules/bktr/bktr/Makefile new file mode 100644 index 000000000000..253e479d6839 --- /dev/null +++ b/sys/modules/bktr/bktr/Makefile @@ -0,0 +1,21 @@ +# Makefile for the bktr Brooktree Bt848/Bt878 PCI video capture device + +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../dev/bktr +KMOD= bktr +SRCS= bktr_core.c bktr_os.c bktr_audio.c bktr_tuner.c bktr_card.c \ + bktr.h opt_devfs.h opt_bktr.h smbus.h bus_if.h device_if.h \ + pci_if.h vnode_if.h +CLEANFILES= bktr.h smbus.h + +bktr.h: + echo "#define NBKTR 1" > bktr.h + echo "#define BKTR_FREEBSD_MODULE 1" >> bktr.h + +# Does not use SMBUS/IICBUS. Uses the old i2c code self contained in +# the bt848 driver. +smbus.h: + echo "#define NSMBUS 0" > smbus.h + +.include <bsd.kmod.mk> diff --git a/sys/modules/bktr/bktr_mem/Makefile b/sys/modules/bktr/bktr_mem/Makefile new file mode 100644 index 000000000000..4d2bba314441 --- /dev/null +++ b/sys/modules/bktr/bktr_mem/Makefile @@ -0,0 +1,9 @@ +# $FreeBSD$ + +MAINTAINER = roger@freebsd.org + +.PATH: ${.CURDIR}/../../../dev/bktr +KMOD= bktr_mem +SRCS= bktr_mem.c + +.include <bsd.kmod.mk> diff --git a/sys/modules/netgraph/bridge/Makefile b/sys/modules/netgraph/bridge/Makefile new file mode 100644 index 000000000000..5afd54163f5c --- /dev/null +++ b/sys/modules/netgraph/bridge/Makefile @@ -0,0 +1,7 @@ +# $FreeBSD$ + +KMOD= ng_bridge +SRCS= ng_bridge.c +NOMAN= + +.include <bsd.kmod.mk> diff --git a/sys/modules/sound/driver/maestro/Makefile b/sys/modules/sound/driver/maestro/Makefile new file mode 100644 index 000000000000..01de2704a9bb --- /dev/null +++ b/sys/modules/sound/driver/maestro/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../../dev/sound/pci +KMOD = snd_maestro +SRCS = device_if.h bus_if.h isa_if.h pci_if.h +SRCS += maestro.c + +.include <bsd.kmod.mk> diff --git a/sys/modules/sound/pcm/Makefile b/sys/modules/sound/pcm/Makefile new file mode 100644 index 000000000000..6886105d53fc --- /dev/null +++ b/sys/modules/sound/pcm/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../dev/sound/pcm +KMOD = snd_pcm +SRCS = device_if.h bus_if.h isa_if.h pci_if.h +SRCS += ac97.c channel.c dsp.c fake.c feeder.c mixer.c sound.c + +.include <bsd.kmod.mk> diff --git a/sys/netgraph/ng_bridge.c b/sys/netgraph/ng_bridge.c new file mode 100644 index 000000000000..81ffa6894382 --- /dev/null +++ b/sys/netgraph/ng_bridge.c @@ -0,0 +1,1014 @@ + +/* + * ng_bridge.c + * + * Copyright (c) 2000 Whistle Communications, Inc. + * All rights reserved. + * + * Subject to the following obligations and disclaimer of warranty, use and + * redistribution of this software, in source or object code forms, with or + * without modifications are expressly permitted by Whistle Communications; + * provided, however, that: + * 1. Any and all reproductions of the source or object code must include the + * copyright notice above and the following disclaimer of warranties; and + * 2. No rights are granted, in any manner or form, to use Whistle + * Communications, Inc. trademarks, including the mark "WHISTLE + * COMMUNICATIONS" on advertising, endorsements, or otherwise except as + * such appears in the above copyright notice or in the software. + * + * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND + * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO + * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, + * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY + * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS + * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. + * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES + * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING + * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Archie Cobbs <archie@freebsd.org> + * + * $FreeBSD$ + */ + +/* + * ng_bridge(4) netgraph node type + * + * The node performs standard intelligent Ethernet bridging over + * each of its connected hooks, or links. A simple loop detection + * algorithm is included which disables a link for priv->conf.loopTimeout + * seconds when a host is seen to have jumped from one link to + * another within priv->conf.minStableAge seconds. + * + * We keep a hashtable that maps Ethernet addresses to host info, + * which is contained in struct ng_bridge_host's. These structures + * tell us on which link the host may be found. A host's entry will + * expire after priv->conf.maxStaleness seconds. + * + * This node is optimzed for stable networks, where machines jump + * from one port to the other only rarely. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/mbuf.h> +#include <sys/errno.h> +#include <sys/syslog.h> +#include <sys/socket.h> +#include <sys/ctype.h> + +#include <net/if.h> +#include <net/ethernet.h> + +#include <netinet/in.h> +#include <netinet/ip_fw.h> + +#include <netgraph/ng_message.h> +#include <netgraph/netgraph.h> +#include <netgraph/ng_parse.h> +#include <netgraph/ng_bridge.h> +#include <netgraph/ng_ether.h> + +/* Per-link private data */ +struct ng_bridge_link { + hook_p hook; /* netgraph hook */ + u_int16_t loopCount; /* loop ignore timer */ + struct ng_bridge_link_stats stats; /* link stats */ +}; + +/* Per-node private data */ +struct ng_bridge_private { + struct ng_bridge_bucket *tab; /* hash table bucket array */ + struct ng_bridge_link *links[NG_BRIDGE_MAX_LINKS]; + struct ng_bridge_config conf; /* node configuration */ + node_p node; /* netgraph node */ + u_int numHosts; /* num entries in table */ + u_int numBuckets; /* num buckets in table */ + u_int hashMask; /* numBuckets - 1 */ + int numLinks; /* num connected links */ + struct callout timer; /* one second periodic timer */ +}; +typedef struct ng_bridge_private *priv_p; + +/* Information about a host, stored in a hash table entry */ +struct ng_bridge_hent { + struct ng_bridge_host host; /* actual host info */ + SLIST_ENTRY(ng_bridge_hent) next; /* next entry in bucket */ +}; + +/* Hash table bucket declaration */ +SLIST_HEAD(ng_bridge_bucket, ng_bridge_hent); + +/* Netgraph node methods */ +static ng_constructor_t ng_bridge_constructor; +static ng_rcvmsg_t ng_bridge_rcvmsg; +static ng_shutdown_t ng_bridge_rmnode; +static ng_newhook_t ng_bridge_newhook; +static ng_rcvdata_t ng_bridge_rcvdata; +static ng_disconnect_t ng_bridge_disconnect; + +/* Other internal functions */ +static struct ng_bridge_host *ng_bridge_get(priv_p priv, const u_char *addr); +static int ng_bridge_put(priv_p priv, const u_char *addr, int linkNum); +static void ng_bridge_rehash(priv_p priv); +static void ng_bridge_remove_hosts(priv_p priv, int linkNum); +static void ng_bridge_timeout(void *arg); +static const char *ng_bridge_nodename(node_p node); + +/* Ethernet broadcast */ +static const u_char ng_bridge_bcast_addr[ETHER_ADDR_LEN] = + { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + +/* Store each hook's link number in the private field */ +#define LINK_NUM(hook) (*(u_int16_t *)(&(hook)->private)) + +/* Compare Ethernet addresses using 32 and 16 bit words instead of bytewise */ +#define ETHER_EQUAL(a,b) (((const u_int32_t *)(a))[0] \ + == ((const u_int32_t *)(b))[0] \ + && ((const u_int16_t *)(a))[2] \ + == ((const u_int16_t *)(b))[2]) + +/* Minimum and maximum number of hash buckets. Must be a power of two. */ +#define MIN_BUCKETS (1 << 5) /* 32 */ +#define MAX_BUCKETS (1 << 14) /* 16384 */ + +/* Configuration default values */ +#define DEFAULT_LOOP_TIMEOUT 60 +#define DEFAULT_MAX_STALENESS (15 * 60) /* same as ARP timeout */ +#define DEFAULT_MIN_STABLE_AGE 1 + +/****************************************************************** + NETGRAPH PARSE TYPES +******************************************************************/ + +/* + * How to determine the length of the table returned by NGM_BRIDGE_GET_TABLE + */ +static int +ng_bridge_getTableLength(const struct ng_parse_type *type, + const u_char *start, const u_char *buf) +{ + const struct ng_bridge_host_ary *const hary + = (const struct ng_bridge_host_ary *)(buf - sizeof(u_int32_t)); + + return hary->numHosts; +} + +/* Parse type for struct ng_bridge_host_ary */ +static const struct ng_parse_struct_info ng_bridge_host_type_info + = NG_BRIDGE_HOST_TYPE_INFO(&ng_ether_enaddr_type); +static const struct ng_parse_type ng_bridge_host_type = { + &ng_parse_struct_type, + &ng_bridge_host_type_info +}; +static const struct ng_parse_array_info ng_bridge_hary_type_info = { + &ng_bridge_host_type, + ng_bridge_getTableLength +}; +static const struct ng_parse_type ng_bridge_hary_type = { + &ng_parse_array_type, + &ng_bridge_hary_type_info +}; +static const struct ng_parse_struct_info ng_bridge_host_ary_type_info + = NG_BRIDGE_HOST_ARY_TYPE_INFO(&ng_bridge_hary_type); +static const struct ng_parse_type ng_bridge_host_ary_type = { + &ng_parse_struct_type, + &ng_bridge_host_ary_type_info +}; + +/* Parse type for struct ng_bridge_config */ +static const struct ng_parse_fixedarray_info ng_bridge_ipfwary_type_info = { + &ng_parse_uint8_type, + NG_BRIDGE_MAX_LINKS +}; +static const struct ng_parse_type ng_bridge_ipfwary_type = { + &ng_parse_fixedarray_type, + &ng_bridge_ipfwary_type_info +}; +static const struct ng_parse_struct_info ng_bridge_config_type_info + = NG_BRIDGE_CONFIG_TYPE_INFO(&ng_bridge_ipfwary_type); +static const struct ng_parse_type ng_bridge_config_type = { + &ng_parse_struct_type, + &ng_bridge_config_type_info +}; + +/* Parse type for struct ng_bridge_link_stat */ +static const struct ng_parse_struct_info + ng_bridge_stats_type_info = NG_BRIDGE_STATS_TYPE_INFO; +static const struct ng_parse_type ng_bridge_stats_type = { + &ng_parse_struct_type, + &ng_bridge_stats_type_info +}; + +/* List of commands and how to convert arguments to/from ASCII */ +static const struct ng_cmdlist ng_bridge_cmdlist[] = { + { + NGM_BRIDGE_COOKIE, + NGM_BRIDGE_SET_CONFIG, + "setconfig", + &ng_bridge_config_type, + NULL + }, + { + NGM_BRIDGE_COOKIE, + NGM_BRIDGE_GET_CONFIG, + "getconfig", + NULL, + &ng_bridge_config_type + }, + { + NGM_BRIDGE_COOKIE, + NGM_BRIDGE_RESET, + "reset", + NULL, + NULL + }, + { + NGM_BRIDGE_COOKIE, + NGM_BRIDGE_GET_STATS, + "getstats", + &ng_parse_uint32_type, + &ng_bridge_stats_type + }, + { + NGM_BRIDGE_COOKIE, + NGM_BRIDGE_CLR_STATS, + "clrstats", + &ng_parse_uint32_type, + NULL + }, + { + NGM_BRIDGE_COOKIE, + NGM_BRIDGE_GETCLR_STATS, + "getclrstats", + &ng_parse_uint32_type, + &ng_bridge_stats_type + }, + { + NGM_BRIDGE_COOKIE, + NGM_BRIDGE_GET_TABLE, + "gettable", + NULL, + &ng_bridge_host_ary_type + }, + { 0 } +}; + +/* Node type descriptor */ +static struct ng_type ng_bridge_typestruct = { + NG_VERSION, + NG_BRIDGE_NODE_TYPE, + NULL, + ng_bridge_constructor, + ng_bridge_rcvmsg, + ng_bridge_rmnode, + ng_bridge_newhook, + NULL, + NULL, + ng_bridge_rcvdata, + ng_bridge_rcvdata, + ng_bridge_disconnect, + ng_bridge_cmdlist, +}; +NETGRAPH_INIT(ether, &ng_bridge_typestruct); + +/* Depend on ng_ether so we can use the Ethernet parse type */ +MODULE_DEPEND(ng_bridge, ng_ether, 1, 1, 1); + +/****************************************************************** + NETGRAPH NODE METHODS +******************************************************************/ + +/* + * Node constructor + */ +static int +ng_bridge_constructor(node_p *nodep) +{ + priv_p priv; + int error; + + /* Allocate and initialize private info */ + MALLOC(priv, priv_p, sizeof(*priv), M_NETGRAPH, M_NOWAIT); + if (priv == NULL) + return (ENOMEM); + bzero(priv, sizeof(*priv)); + callout_init(&priv->timer); + + /* Allocate and initialize hash table, etc. */ + MALLOC(priv->tab, struct ng_bridge_bucket *, + MIN_BUCKETS * sizeof(*priv->tab), M_NETGRAPH, M_NOWAIT); + if (priv->tab == NULL) { + FREE(priv, M_NETGRAPH); + return (ENOMEM); + } + bzero(priv->tab, MIN_BUCKETS * sizeof(*priv->tab)); /* init SLIST's */ + priv->numBuckets = MIN_BUCKETS; + priv->hashMask = MIN_BUCKETS - 1; + priv->conf.debugLevel = 1; + priv->conf.loopTimeout = DEFAULT_LOOP_TIMEOUT; + priv->conf.maxStaleness = DEFAULT_MAX_STALENESS; + priv->conf.minStableAge = DEFAULT_MIN_STABLE_AGE; + + /* Call superclass constructor */ + if ((error = ng_make_node_common(&ng_bridge_typestruct, nodep))) { + FREE(priv, M_NETGRAPH); + return (error); + } + (*nodep)->private = priv; + priv->node = *nodep; + + /* Start timer by faking a timeout event */ + (*nodep)->refs++; + ng_bridge_timeout(*nodep); + return (0); +} + +/* + * Method for attaching a new hook + */ +static int +ng_bridge_newhook(node_p node, hook_p hook, const char *name) +{ + const priv_p priv = node->private; + + /* Check for a link hook */ + if (strncmp(name, NG_BRIDGE_HOOK_LINK_PREFIX, + strlen(NG_BRIDGE_HOOK_LINK_PREFIX)) == 0) { + const char *cp; + char *eptr; + u_long linkNum; + + cp = name + strlen(NG_BRIDGE_HOOK_LINK_PREFIX); + if (!isdigit(*cp) || (cp[0] == '0' && cp[1] != '\0')) + return (EINVAL); + linkNum = strtoul(cp, &eptr, 10); + if (*eptr != '\0' || linkNum >= NG_BRIDGE_MAX_LINKS) + return (EINVAL); + if (priv->links[linkNum] != NULL) + return (EISCONN); + MALLOC(priv->links[linkNum], struct ng_bridge_link *, + sizeof(*priv->links[linkNum]), M_NETGRAPH, M_NOWAIT); + if (priv->links[linkNum] == NULL) + return (ENOMEM); + bzero(priv->links[linkNum], sizeof(*priv->links[linkNum])); + priv->links[linkNum]->hook = hook; + LINK_NUM(hook) = linkNum; + priv->numLinks++; + return (0); + } + + /* Unknown hook name */ + return (EINVAL); +} + +/* + * Receive a control message + */ +static int +ng_bridge_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, + struct ng_mesg **rptr, hook_p lasthook) +{ + const priv_p priv = node->private; + struct ng_mesg *resp = NULL; + int error = 0; + + switch (msg->header.typecookie) { + case NGM_BRIDGE_COOKIE: + switch (msg->header.cmd) { + case NGM_BRIDGE_GET_CONFIG: + { + struct ng_bridge_config *conf; + + NG_MKRESPONSE(resp, msg, + sizeof(struct ng_bridge_config), M_NOWAIT); + if (resp == NULL) { + error = ENOMEM; + break; + } + conf = (struct ng_bridge_config *)resp->data; + *conf = priv->conf; /* no sanity checking needed */ + break; + } + case NGM_BRIDGE_SET_CONFIG: + { + struct ng_bridge_config *conf; + int i; + + if (msg->header.arglen + != sizeof(struct ng_bridge_config)) { + error = EINVAL; + break; + } + conf = (struct ng_bridge_config *)msg->data; + priv->conf = *conf; + for (i = 0; i < NG_BRIDGE_MAX_LINKS; i++) + priv->conf.ipfw[i] = !!priv->conf.ipfw[i]; + break; + } + case NGM_BRIDGE_RESET: + { + int i; + + /* Flush all entries in the hash table */ + ng_bridge_remove_hosts(priv, -1); + + /* Reset all loop detection counters and stats */ + for (i = 0; i < NG_BRIDGE_MAX_LINKS; i++) { + if (priv->links[i] == NULL) + continue; + priv->links[i]->loopCount = 0; + bzero(&priv->links[i]->stats, + sizeof(priv->links[i]->stats)); + } + break; + } + case NGM_BRIDGE_GET_STATS: + case NGM_BRIDGE_CLR_STATS: + case NGM_BRIDGE_GETCLR_STATS: + { + struct ng_bridge_link *link; + int linkNum; + + /* Get link number */ + if (msg->header.arglen != sizeof(u_int32_t)) { + error = EINVAL; + break; + } + linkNum = *((u_int32_t *)msg->data); + if (linkNum < 0 || linkNum >= NG_BRIDGE_MAX_LINKS) { + error = EINVAL; + break; + } + if ((link = priv->links[linkNum]) == NULL) { + error = ENOTCONN; + break; + } + + /* Get/clear stats */ + if (msg->header.cmd != NGM_BRIDGE_CLR_STATS) { + NG_MKRESPONSE(resp, msg, + sizeof(link->stats), M_NOWAIT); + if (resp == NULL) { + error = ENOMEM; + break; + } + bcopy(&link->stats, + resp->data, sizeof(link->stats)); + } + if (msg->header.cmd != NGM_BRIDGE_GET_STATS) + bzero(&link->stats, sizeof(link->stats)); + break; + } + case NGM_BRIDGE_GET_TABLE: + { + struct ng_bridge_host_ary *ary; + struct ng_bridge_hent *hent; + int i = 0, bucket; + + NG_MKRESPONSE(resp, msg, sizeof(*ary) + + (priv->numHosts * sizeof(*ary->hosts)), M_NOWAIT); + if (resp == NULL) { + error = ENOMEM; + break; + } + ary = (struct ng_bridge_host_ary *)resp->data; + ary->numHosts = priv->numHosts; + for (bucket = 0; bucket < priv->numBuckets; bucket++) { + SLIST_FOREACH(hent, &priv->tab[bucket], next) + ary->hosts[i++] = hent->host; + } + break; + } + default: + error = EINVAL; + break; + } + break; + default: + error = EINVAL; + break; + } + + /* Done */ + if (rptr) + *rptr = resp; + else if (resp != NULL) + FREE(resp, M_NETGRAPH); + FREE(msg, M_NETGRAPH); + return (error); +} + +/* + * Receive data on a hook + */ +static int +ng_bridge_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) +{ + const node_p node = hook->node; + const priv_p priv = node->private; + struct ng_bridge_host *host; + struct ng_bridge_link *link; + struct ether_header *eh; + int error = 0, linkNum; + int i, manycast; + + /* Get link number */ + linkNum = LINK_NUM(hook); + KASSERT(linkNum >= 0 && linkNum < NG_BRIDGE_MAX_LINKS, + ("%s: linkNum=%u", __FUNCTION__, linkNum)); + link = priv->links[linkNum]; + KASSERT(link != NULL, ("%s: link%d null", __FUNCTION__, linkNum)); + + /* Sanity check packet and pull up header */ + if (m->m_pkthdr.len < ETHER_HDR_LEN) { + link->stats.recvRunts++; + NG_FREE_DATA(m, meta); + return (EINVAL); + } + if (m->m_len < ETHER_HDR_LEN && !(m = m_pullup(m, ETHER_HDR_LEN))) { + link->stats.memoryFailures++; + NG_FREE_META(meta); + return (ENOBUFS); + } + eh = mtod(m, struct ether_header *); + if ((eh->ether_shost[0] & 1) != 0) { + link->stats.recvInvalid++; + NG_FREE_DATA(m, meta); + return (EINVAL); + } + + /* Is link disabled due to a loopback condition? */ + if (link->loopCount != 0) { + link->stats.loopDrops++; + NG_FREE_DATA(m, meta); + return (ELOOP); /* XXX is this an appropriate error? */ + } + + /* Update stats */ + link->stats.recvPackets++; + link->stats.recvOctets += m->m_pkthdr.len; + if ((manycast = (eh->ether_dhost[0] & 1)) != 0) { + if (ETHER_EQUAL(eh->ether_dhost, ng_bridge_bcast_addr)) { + link->stats.recvBroadcasts++; + manycast = 2; + } else + link->stats.recvMulticasts++; + } + + /* Look up packet's source Ethernet address in hashtable */ + if ((host = ng_bridge_get(priv, eh->ether_shost)) != NULL) { + + /* Update time since last heard from this host */ + host->staleness = 0; + + /* Did host jump to a different link? */ + if (host->linkNum != linkNum) { + + /* + * If the host's old link was recently established + * on the old link and it's already jumped to a new + * link, declare a loopback condition. + */ + if (host->age < priv->conf.minStableAge) { + + /* Log the problem */ + if (priv->conf.debugLevel >= 2) { + struct ifnet *ifp = m->m_pkthdr.rcvif; + char suffix[32]; + + if (ifp != NULL) + snprintf(suffix, sizeof(suffix), + " (%s%d)", ifp->if_name, + ifp->if_unit); + else + *suffix = '\0'; + log(LOG_WARNING, "ng_bridge: %s:" + " loopback detected on %s%s\n", + ng_bridge_nodename(node), + hook->name, suffix); + } + + /* Mark link as linka non grata */ + link->loopCount = priv->conf.loopTimeout; + link->stats.loopDetects++; + + /* Forget all hosts on this link */ + ng_bridge_remove_hosts(priv, linkNum); + + /* Drop packet */ + link->stats.loopDrops++; + NG_FREE_DATA(m, meta); + return (ELOOP); /* XXX appropriate? */ + } + + /* Move host over to new link */ + host->linkNum = linkNum; + host->age = 0; + } + } else { + if (!ng_bridge_put(priv, eh->ether_shost, linkNum)) { + link->stats.memoryFailures++; + NG_FREE_DATA(m, meta); + return (ENOMEM); + } + } + + /* Run packet through ipfw processing, if enabled */ + if (priv->conf.ipfw[linkNum] && fw_enable && ip_fw_chk_ptr != NULL) { + /* XXX not implemented yet */ + } + + /* + * If unicast and destination host known, deliver to host's link, + * unless it is the same link as the packet came in on. + */ + if (!manycast) { + + /* Determine packet destination link */ + if ((host = ng_bridge_get(priv, eh->ether_dhost)) != NULL) { + struct ng_bridge_link *const destLink + = priv->links[host->linkNum]; + + /* If destination same as incoming link, do nothing */ + KASSERT(destLink != NULL, + ("%s: link%d null", __FUNCTION__, host->linkNum)); + if (destLink == link) { + NG_FREE_DATA(m, meta); + return (0); + } + + /* Deliver packet out the destination link */ + destLink->stats.xmitPackets++; + destLink->stats.xmitOctets += m->m_pkthdr.len; + NG_SEND_DATA(error, destLink->hook, m, meta); + return (error); + } + + /* Destination host is not known */ + link->stats.recvUnknown++; + } + + /* Distribute unknown, multicast, broadcast pkts to all other links */ + for (linkNum = i = 0; i < priv->numLinks - 1; linkNum++) { + struct ng_bridge_link *const destLink = priv->links[linkNum]; + meta_p meta2 = NULL; + struct mbuf *m2; + + /* Skip incoming link and disconnected links */ + if (destLink == NULL || destLink == link) + continue; + + /* Copy mbuf and meta info */ + if (++i == priv->numLinks - 1) { /* last link */ + m2 = m; + meta2 = meta; + } else { + m2 = m_copypacket(m, M_NOWAIT); /* XXX m_dup()? */ + if (m2 == NULL) { + link->stats.memoryFailures++; + NG_FREE_DATA(m, meta); + return (ENOBUFS); + } + if (meta != NULL + && (meta2 = ng_copy_meta(meta)) == NULL) { + link->stats.memoryFailures++; + m_freem(m2); + NG_FREE_DATA(m, meta); + return (ENOMEM); + } + } + + /* Update stats */ + destLink->stats.xmitPackets++; + destLink->stats.xmitOctets += m->m_pkthdr.len; + switch (manycast) { + case 0: /* unicast */ + break; + case 1: /* multicast */ + destLink->stats.xmitMulticasts++; + break; + case 2: /* broadcast */ + destLink->stats.xmitBroadcasts++; + break; + } + + /* Send packet */ + NG_SEND_DATA(error, destLink->hook, m2, meta2); + } + return (error); +} + +/* + * Shutdown node + */ +static int +ng_bridge_rmnode(node_p node) +{ + const priv_p priv = node->private; + + ng_unname(node); + ng_cutlinks(node); /* frees all link and host info */ + KASSERT(priv->numLinks == 0 && priv->numHosts == 0, + ("%s: numLinks=%d numHosts=%d", + __FUNCTION__, priv->numLinks, priv->numHosts)); + FREE(priv->tab, M_NETGRAPH); + FREE(priv, M_NETGRAPH); + node->private = NULL; + ng_unref(node); + return (0); +} + +/* + * Hook disconnection. + */ +static int +ng_bridge_disconnect(hook_p hook) +{ + const priv_p priv = hook->node->private; + int linkNum; + + /* Get link number */ + linkNum = LINK_NUM(hook); + KASSERT(linkNum >= 0 && linkNum < NG_BRIDGE_MAX_LINKS, + ("%s: linkNum=%u", __FUNCTION__, linkNum)); + + /* Remove all hosts associated with this link */ + ng_bridge_remove_hosts(priv, linkNum); + + /* Free associated link information */ + KASSERT(priv->links[linkNum] != NULL, ("%s: no link", __FUNCTION__)); + FREE(priv->links[linkNum], M_NETGRAPH); + priv->links[linkNum] = NULL; + priv->numLinks--; + + /* If no more hooks, go away */ + if (hook->node->numhooks == 0) + ng_rmnode(hook->node); + return (0); +} + +/****************************************************************** + HASH TABLE FUNCTIONS +******************************************************************/ + +/* + * Hash algorithm + * + * Only hashing bytes 3-6 of the Ethernet address is sufficient and fast. + */ +#define HASH(addr,mask) ( (((const u_int16_t *)(addr))[0] \ + ^ ((const u_int16_t *)(addr))[1] \ + ^ ((const u_int16_t *)(addr))[2]) & (mask) ) + +/* + * Find a host entry in the table. + */ +static struct ng_bridge_host * +ng_bridge_get(priv_p priv, const u_char *addr) +{ + const int bucket = HASH(addr, priv->hashMask); + struct ng_bridge_hent *hent; + + SLIST_FOREACH(hent, &priv->tab[bucket], next) { + if (ETHER_EQUAL(hent->host.addr, addr)) + return (&hent->host); + } + return (NULL); +} + +/* + * Add a new host entry to the table. This assumes the host doesn't + * already exist in the table. Returns 1 on success, 0 if there + * was a memory allocation failure. + */ +static int +ng_bridge_put(priv_p priv, const u_char *addr, int linkNum) +{ + const int bucket = HASH(addr, priv->hashMask); + struct ng_bridge_hent *hent; + +#ifdef INVARIANTS + /* Assert that entry does not already exist in hashtable */ + SLIST_FOREACH(hent, &priv->tab[bucket], next) { + KASSERT(!ETHER_EQUAL(hent->host.addr, addr), + ("%s: entry %6D exists in table", __FUNCTION__, addr, ":")); + } +#endif + + /* Allocate and initialize new hashtable entry */ + MALLOC(hent, struct ng_bridge_hent *, + sizeof(*hent), M_NETGRAPH, M_NOWAIT); + if (hent == NULL) + return (0); + bcopy(addr, hent->host.addr, ETHER_ADDR_LEN); + hent->host.linkNum = linkNum; + hent->host.staleness = 0; + hent->host.age = 0; + + /* Add new element to hash bucket */ + SLIST_INSERT_HEAD(&priv->tab[bucket], hent, next); + priv->numHosts++; + + /* Resize table if necessary */ + ng_bridge_rehash(priv); + return (1); +} + +/* + * Resize the hash table. We try to maintain the number of buckets + * such that the load factor is in the range 0.25 to 1.0. + * + * If we can't get the new memory then we silently fail. This is OK + * because things will still work and we'll try again soon anyway. + */ +static void +ng_bridge_rehash(priv_p priv) +{ + struct ng_bridge_bucket *newTab; + int oldBucket, newBucket; + int newNumBuckets; + u_int newMask; + + /* Is table too full or too empty? */ + if (priv->numHosts > priv->numBuckets + && (priv->numBuckets << 1) <= MAX_BUCKETS) + newNumBuckets = priv->numBuckets << 1; + else if (priv->numHosts < (priv->numBuckets >> 2) + && (priv->numBuckets >> 2) >= MIN_BUCKETS) + newNumBuckets = priv->numBuckets >> 2; + else + return; + newMask = newNumBuckets - 1; + + /* Allocate and initialize new table */ + MALLOC(newTab, struct ng_bridge_bucket *, + newNumBuckets * sizeof(*newTab), M_NETGRAPH, M_NOWAIT); + if (newTab == NULL) + return; + bzero(newTab, newNumBuckets * sizeof(*newTab)); + + /* Move all entries from old table to new table */ + for (oldBucket = 0; oldBucket < priv->numBuckets; oldBucket++) { + struct ng_bridge_bucket *const oldList = &priv->tab[oldBucket]; + + while (!SLIST_EMPTY(oldList)) { + struct ng_bridge_hent *const hent + = SLIST_FIRST(oldList); + + SLIST_REMOVE_HEAD(oldList, next); + newBucket = HASH(hent->host.addr, newMask); + SLIST_INSERT_HEAD(&newTab[newBucket], hent, next); + } + } + + /* Replace old table with new one */ + if (priv->conf.debugLevel >= 3) { + log(LOG_INFO, "ng_bridge: %s: table size %d -> %d\n", + ng_bridge_nodename(priv->node), + priv->numBuckets, newNumBuckets); + } + FREE(priv->tab, M_NETGRAPH); + priv->numBuckets = newNumBuckets; + priv->hashMask = newMask; + priv->tab = newTab; + return; +} + +/****************************************************************** + MISC FUNCTIONS +******************************************************************/ + +/* + * Remove all hosts associated with a specific link from the hashtable. + * If linkNum == -1, then remove all hosts in the table. + */ +static void +ng_bridge_remove_hosts(priv_p priv, int linkNum) +{ + int bucket; + + for (bucket = 0; bucket < priv->numBuckets; bucket++) { + struct ng_bridge_hent **hptr = &SLIST_FIRST(&priv->tab[bucket]); + + while (*hptr != NULL) { + struct ng_bridge_hent *const hent = *hptr; + + if (linkNum == -1 || hent->host.linkNum == linkNum) { + *hptr = SLIST_NEXT(hent, next); + FREE(hent, M_NETGRAPH); + priv->numHosts--; + } else + hptr = &SLIST_NEXT(hent, next); + } + } +} + +/* + * Handle our once-per-second timeout event. We do two things: + * we decrement link->loopCount for those links being muted due to + * a detected loopback condition, and we remove any hosts from + * the hashtable whom we haven't heard from in a long while. + */ +static void +ng_bridge_timeout(void *arg) +{ + const node_p node = arg; + const priv_p priv = node->private; + int s, bucket; + int counter = 0; + int linkNum; + + /* Avoid race condition with ng_bridge_shutdown() */ + s = splnet(); + if ((node->flags & NG_INVALID) != 0 || priv == NULL) { + ng_unref(node); + splx(s); + return; + } + + /* Register a new timeout, keeping the existing node reference */ + callout_reset(&priv->timer, hz, ng_bridge_timeout, node); + + /* Update host time counters and remove stale entries */ + for (bucket = 0; bucket < priv->numBuckets; bucket++) { + struct ng_bridge_hent **hptr = &SLIST_FIRST(&priv->tab[bucket]); + + while (*hptr != NULL) { + struct ng_bridge_hent *const hent = *hptr; + + /* Make sure host's link really exists */ + KASSERT(priv->links[hent->host.linkNum] != NULL, + ("%s: host %6D on nonexistent link %d\n", + __FUNCTION__, hent->host.addr, ":", + hent->host.linkNum)); + + /* Remove hosts we haven't heard from in a while */ + if (++hent->host.staleness >= priv->conf.maxStaleness) { + *hptr = SLIST_NEXT(hent, next); + FREE(hent, M_NETGRAPH); + priv->numHosts--; + } else { + if (hent->host.age < 0xffff) + hent->host.age++; + hptr = &SLIST_NEXT(hent, next); + counter++; + } + } + } + KASSERT(priv->numHosts == counter, + ("%s: hosts: %d != %d", __FUNCTION__, priv->numHosts, counter)); + + /* Decrease table size if necessary */ + ng_bridge_rehash(priv); + + /* Decrease loop counter on muted looped back links */ + for (counter = linkNum = 0; linkNum < NG_BRIDGE_MAX_LINKS; linkNum++) { + struct ng_bridge_link *const link = priv->links[linkNum]; + + if (link != NULL) { + if (link->loopCount != 0) { + link->loopCount--; + if (link->loopCount == 0 + && priv->conf.debugLevel >= 2) { + log(LOG_INFO, "ng_bridge: %s:" + " restoring looped back link%d\n", + ng_bridge_nodename(node), linkNum); + } + } + counter++; + } + } + KASSERT(priv->numLinks == counter, + ("%s: links: %d != %d", __FUNCTION__, priv->numLinks, counter)); + + /* Done */ + splx(s); +} + +/* + * Return node's "name", even if it doesn't have one. + */ +static const char * +ng_bridge_nodename(node_p node) +{ + static char name[NG_NODELEN+1]; + + if (node->name != NULL) + snprintf(name, sizeof(name), "%s", node->name); + else + snprintf(name, sizeof(name), "[%x]", ng_node2ID(node)); + return name; +} + diff --git a/sys/netgraph/ng_bridge.h b/sys/netgraph/ng_bridge.h new file mode 100644 index 000000000000..7c83d3fa5bc5 --- /dev/null +++ b/sys/netgraph/ng_bridge.h @@ -0,0 +1,162 @@ + +/* + * ng_bridge.h + * + * Copyright (c) 2000 Whistle Communications, Inc. + * All rights reserved. + * + * Subject to the following obligations and disclaimer of warranty, use and + * redistribution of this software, in source or object code forms, with or + * without modifications are expressly permitted by Whistle Communications; + * provided, however, that: + * 1. Any and all reproductions of the source or object code must include the + * copyright notice above and the following disclaimer of warranties; and + * 2. No rights are granted, in any manner or form, to use Whistle + * Communications, Inc. trademarks, including the mark "WHISTLE + * COMMUNICATIONS" on advertising, endorsements, or otherwise except as + * such appears in the above copyright notice or in the software. + * + * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND + * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO + * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, + * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY + * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS + * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. + * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES + * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING + * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Archie Cobbs <archie@freebsd.org> + * + * $FreeBSD$ + */ + +#ifndef _NETGRAPH_NG_BRIDGE_H_ +#define _NETGRAPH_NG_BRIDGE_H_ + +/* Node type name and magic cookie */ +#define NG_BRIDGE_NODE_TYPE "bridge" +#define NGM_BRIDGE_COOKIE 967239368 + +/* Hook names */ +#define NG_BRIDGE_HOOK_LINK_PREFIX "link" /* append decimal integer */ +#define NG_BRIDGE_HOOK_LINK_FMT "link%d" /* for use with printf(3) */ + +/* Maximum number of supported links */ +#define NG_BRIDGE_MAX_LINKS 32 + +/* Node configuration structure */ +struct ng_bridge_config { + u_char ipfw[NG_BRIDGE_MAX_LINKS]; /* enable ipfw */ + u_char debugLevel; /* debug level */ + u_int32_t loopTimeout; /* link loopback mute time */ + u_int32_t maxStaleness; /* max host age before nuking */ + u_int32_t minStableAge; /* min time for a stable host */ +}; + +/* Keep this in sync with the above structure definition */ +#define NG_BRIDGE_CONFIG_TYPE_INFO(ainfo) { \ + { \ + { "ipfw", (ainfo) }, \ + { "debugLevel", &ng_parse_uint8_type }, \ + { "loopTimeout", &ng_parse_uint32_type }, \ + { "maxStaleness", &ng_parse_uint32_type }, \ + { "minStableAge", &ng_parse_uint32_type }, \ + { NULL } \ + } \ +} + +/* Statistics structure (one for each link) */ +struct ng_bridge_link_stats { + u_int64_t recvOctets; /* total octets rec'd on link */ + u_int64_t recvPackets; /* total pkts rec'd on link */ + u_int64_t recvMulticasts; /* multicast pkts rec'd on link */ + u_int64_t recvBroadcasts; /* broadcast pkts rec'd on link */ + u_int64_t recvUnknown; /* pkts rec'd with unknown dest addr */ + u_int64_t recvRunts; /* pkts rec'd less than 14 bytes */ + u_int64_t recvInvalid; /* pkts rec'd with bogus source addr */ + u_int64_t xmitOctets; /* total octets xmit'd on link */ + u_int64_t xmitPackets; /* total pkts xmit'd on link */ + u_int64_t xmitMulticasts; /* multicast pkts xmit'd on link */ + u_int64_t xmitBroadcasts; /* broadcast pkts xmit'd on link */ + u_int64_t loopDrops; /* pkts dropped due to loopback */ + u_int64_t loopDetects; /* number of loop detections */ + u_int64_t memoryFailures; /* times couldn't get mem or mbuf */ +}; + +/* Keep this in sync with the above structure definition */ +#define NG_BRIDGE_STATS_TYPE_INFO { \ + { \ + { "recvOctets", &ng_parse_uint64_type }, \ + { "recvPackets", &ng_parse_uint64_type }, \ + { "recvMulticast", &ng_parse_uint64_type }, \ + { "recvBroadcast", &ng_parse_uint64_type }, \ + { "recvUnknown", &ng_parse_uint64_type }, \ + { "recvRunts", &ng_parse_uint64_type }, \ + { "recvInvalid", &ng_parse_uint64_type }, \ + { "xmitOctets", &ng_parse_uint64_type }, \ + { "xmitPackets", &ng_parse_uint64_type }, \ + { "xmitMulticasts", &ng_parse_uint64_type }, \ + { "xmitBroadcasts", &ng_parse_uint64_type }, \ + { "loopDrops", &ng_parse_uint64_type }, \ + { "loopDetects", &ng_parse_uint64_type }, \ + { "memoryFailures", &ng_parse_uint64_type }, \ + { NULL } \ + } \ +} + +/* Structure describing a single host */ +struct ng_bridge_host { + u_char addr[6]; /* ethernet address */ + u_int16_t linkNum; /* link where addr can be found */ + u_int16_t age; /* seconds ago entry was created */ + u_int16_t staleness; /* seconds ago host last heard from */ +}; + +/* Keep this in sync with the above structure definition */ +#define NG_BRIDGE_HOST_TYPE_INFO(entype) { \ + { \ + { "addr", (entype) }, \ + { "linkNum", &ng_parse_uint16_type }, \ + { "age", &ng_parse_uint16_type }, \ + { "staleness", &ng_parse_uint16_type }, \ + { NULL } \ + } \ +} + +/* Structure returned by NGM_BRIDGE_GET_TABLE */ +struct ng_bridge_host_ary { + u_int32_t numHosts; + struct ng_bridge_host hosts[0]; +}; + +/* Keep this in sync with the above structure definition */ +#define NG_BRIDGE_HOST_ARY_TYPE_INFO(harytype) { \ + { \ + { "numHosts", &ng_parse_uint32_type }, \ + { "hosts", (harytype) }, \ + { NULL } \ + } \ +} + +/* Netgraph control messages */ +enum { + NGM_BRIDGE_SET_CONFIG = 1, /* set node configuration */ + NGM_BRIDGE_GET_CONFIG, /* get node configuration */ + NGM_BRIDGE_RESET, /* reset (forget) all information */ + NGM_BRIDGE_GET_STATS, /* get link stats */ + NGM_BRIDGE_CLR_STATS, /* clear link stats */ + NGM_BRIDGE_GETCLR_STATS, /* atomically get & clear link stats */ + NGM_BRIDGE_GET_TABLE, /* get link table */ +}; + +#endif /* _NETGRAPH_NG_BRIDGE_H_ */ + |
