This commit was manufactured by cvs2svn to create branch 'RELENG_6'.
This commit is contained in:
parent
c538ede71c
commit
47d76a2b91
33
contrib/netcat/atomicio.h
Normal file
33
contrib/netcat/atomicio.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* $OpenBSD: atomicio.h,v 1.1 2005/05/24 20:13:28 avsm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Ensure all of data on socket comes through. f==read || f==vwrite
|
||||
*/
|
||||
size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
|
||||
|
||||
#define vwrite (ssize_t (*)(int, void *, size_t))write
|
353
crypto/openssh/ssh_namespace.h
Normal file
353
crypto/openssh/ssh_namespace.h
Normal file
@ -0,0 +1,353 @@
|
||||
/*
|
||||
* Namespace munging inspired by an equivalent hack in NetBSD's tree: add
|
||||
* the "ssh_" prefix to every symbol in libssh which doesn't already have
|
||||
* it. This prevents collisions between symbols in libssh and symbols in
|
||||
* other libraries or applications which link with libssh, either directly
|
||||
* or indirectly (e.g. through PAM loading pam_ssh).
|
||||
*
|
||||
* A list of symbols which need munging is obtained as follows:
|
||||
*
|
||||
* nm libssh.a | awk '$2 == "T" && $3 !~ /^ssh_/ { print $3 }'
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define a2port ssh_a2port
|
||||
#define a2tun ssh_a2tun
|
||||
#define acss ssh_acss
|
||||
#define acss_setkey ssh_acss_setkey
|
||||
#define acss_setsubkey ssh_acss_setsubkey
|
||||
#define add_host_to_hostfile ssh_add_host_to_hostfile
|
||||
#define addargs ssh_addargs
|
||||
#define ask_permission ssh_ask_permission
|
||||
#define atomicio ssh_atomicio
|
||||
#define auth_request_forwarding ssh_auth_request_forwarding
|
||||
#define buffer_append ssh_buffer_append
|
||||
#define buffer_append_space ssh_buffer_append_space
|
||||
#define buffer_clear ssh_buffer_clear
|
||||
#define buffer_compress ssh_buffer_compress
|
||||
#define buffer_compress_init_recv ssh_buffer_compress_init_recv
|
||||
#define buffer_compress_init_send ssh_buffer_compress_init_send
|
||||
#define buffer_compress_uninit ssh_buffer_compress_uninit
|
||||
#define buffer_consume ssh_buffer_consume
|
||||
#define buffer_consume_end ssh_buffer_consume_end
|
||||
#define buffer_consume_end_ret ssh_buffer_consume_end_ret
|
||||
#define buffer_consume_ret ssh_buffer_consume_ret
|
||||
#define buffer_dump ssh_buffer_dump
|
||||
#define buffer_free ssh_buffer_free
|
||||
#define buffer_get ssh_buffer_get
|
||||
#define buffer_get_bignum ssh_buffer_get_bignum
|
||||
#define buffer_get_bignum2 ssh_buffer_get_bignum2
|
||||
#define buffer_get_bignum2_ret ssh_buffer_get_bignum2_ret
|
||||
#define buffer_get_bignum_ret ssh_buffer_get_bignum_ret
|
||||
#define buffer_get_char ssh_buffer_get_char
|
||||
#define buffer_get_char_ret ssh_buffer_get_char_ret
|
||||
#define buffer_get_int ssh_buffer_get_int
|
||||
#define buffer_get_int64 ssh_buffer_get_int64
|
||||
#define buffer_get_int64_ret ssh_buffer_get_int64_ret
|
||||
#define buffer_get_int_ret ssh_buffer_get_int_ret
|
||||
#define buffer_get_ret ssh_buffer_get_ret
|
||||
#define buffer_get_short ssh_buffer_get_short
|
||||
#define buffer_get_short_ret ssh_buffer_get_short_ret
|
||||
#define buffer_get_string ssh_buffer_get_string
|
||||
#define buffer_get_string_ret ssh_buffer_get_string_ret
|
||||
#define buffer_init ssh_buffer_init
|
||||
#define buffer_len ssh_buffer_len
|
||||
#define buffer_ptr ssh_buffer_ptr
|
||||
#define buffer_put_bignum ssh_buffer_put_bignum
|
||||
#define buffer_put_bignum2 ssh_buffer_put_bignum2
|
||||
#define buffer_put_bignum2_ret ssh_buffer_put_bignum2_ret
|
||||
#define buffer_put_bignum_ret ssh_buffer_put_bignum_ret
|
||||
#define buffer_put_char ssh_buffer_put_char
|
||||
#define buffer_put_cstring ssh_buffer_put_cstring
|
||||
#define buffer_put_int ssh_buffer_put_int
|
||||
#define buffer_put_int64 ssh_buffer_put_int64
|
||||
#define buffer_put_short ssh_buffer_put_short
|
||||
#define buffer_put_string ssh_buffer_put_string
|
||||
#define buffer_uncompress ssh_buffer_uncompress
|
||||
#define chan_ibuf_empty ssh_chan_ibuf_empty
|
||||
#define chan_is_dead ssh_chan_is_dead
|
||||
#define chan_mark_dead ssh_chan_mark_dead
|
||||
#define chan_obuf_empty ssh_chan_obuf_empty
|
||||
#define chan_rcvd_ieof ssh_chan_rcvd_ieof
|
||||
#define chan_rcvd_oclose ssh_chan_rcvd_oclose
|
||||
#define chan_read_failed ssh_chan_read_failed
|
||||
#define chan_write_failed ssh_chan_write_failed
|
||||
#define channel_add_permitted_opens ssh_channel_add_permitted_opens
|
||||
#define channel_after_select ssh_channel_after_select
|
||||
#define channel_by_id ssh_channel_by_id
|
||||
#define channel_cancel_cleanup ssh_channel_cancel_cleanup
|
||||
#define channel_cancel_rport_listener ssh_channel_cancel_rport_listener
|
||||
#define channel_clear_permitted_opens ssh_channel_clear_permitted_opens
|
||||
#define channel_close_all ssh_channel_close_all
|
||||
#define channel_close_fd ssh_channel_close_fd
|
||||
#define channel_connect_by_listen_address ssh_channel_connect_by_listen_address
|
||||
#define channel_connect_to ssh_channel_connect_to
|
||||
#define channel_find_open ssh_channel_find_open
|
||||
#define channel_free ssh_channel_free
|
||||
#define channel_free_all ssh_channel_free_all
|
||||
#define channel_input_close ssh_channel_input_close
|
||||
#define channel_input_close_confirmation ssh_channel_input_close_confirmation
|
||||
#define channel_input_data ssh_channel_input_data
|
||||
#define channel_input_extended_data ssh_channel_input_extended_data
|
||||
#define channel_input_ieof ssh_channel_input_ieof
|
||||
#define channel_input_oclose ssh_channel_input_oclose
|
||||
#define channel_input_open_confirmation ssh_channel_input_open_confirmation
|
||||
#define channel_input_open_failure ssh_channel_input_open_failure
|
||||
#define channel_input_port_forward_request ssh_channel_input_port_forward_request
|
||||
#define channel_input_port_open ssh_channel_input_port_open
|
||||
#define channel_input_window_adjust ssh_channel_input_window_adjust
|
||||
#define channel_lookup ssh_channel_lookup
|
||||
#define channel_new ssh_channel_new
|
||||
#define channel_not_very_much_buffered_data ssh_channel_not_very_much_buffered_data
|
||||
#define channel_open_message ssh_channel_open_message
|
||||
#define channel_output_poll ssh_channel_output_poll
|
||||
#define channel_permit_all_opens ssh_channel_permit_all_opens
|
||||
#define channel_prepare_select ssh_channel_prepare_select
|
||||
#define channel_register_cleanup ssh_channel_register_cleanup
|
||||
#define channel_register_confirm ssh_channel_register_confirm
|
||||
#define channel_register_filter ssh_channel_register_filter
|
||||
#define channel_request_remote_forwarding ssh_channel_request_remote_forwarding
|
||||
#define channel_request_rforward_cancel ssh_channel_request_rforward_cancel
|
||||
#define channel_request_start ssh_channel_request_start
|
||||
#define channel_send_open ssh_channel_send_open
|
||||
#define channel_send_window_changes ssh_channel_send_window_changes
|
||||
#define channel_set_af ssh_channel_set_af
|
||||
#define channel_set_fds ssh_channel_set_fds
|
||||
#define channel_setup_local_fwd_listener ssh_channel_setup_local_fwd_listener
|
||||
#define channel_setup_remote_fwd_listener ssh_channel_setup_remote_fwd_listener
|
||||
#define channel_still_open ssh_channel_still_open
|
||||
#define channel_stop_listening ssh_channel_stop_listening
|
||||
#define check_host_in_hostfile ssh_check_host_in_hostfile
|
||||
#define choose_dh ssh_choose_dh
|
||||
#define chop ssh_chop
|
||||
#define cipher_blocksize ssh_cipher_blocksize
|
||||
#define cipher_by_name ssh_cipher_by_name
|
||||
#define cipher_by_number ssh_cipher_by_number
|
||||
#define cipher_cleanup ssh_cipher_cleanup
|
||||
#define cipher_crypt ssh_cipher_crypt
|
||||
#define cipher_get_keycontext ssh_cipher_get_keycontext
|
||||
#define cipher_get_keyiv ssh_cipher_get_keyiv
|
||||
#define cipher_get_keyiv_len ssh_cipher_get_keyiv_len
|
||||
#define cipher_get_number ssh_cipher_get_number
|
||||
#define cipher_init ssh_cipher_init
|
||||
#define cipher_keylen ssh_cipher_keylen
|
||||
#define cipher_mask_ssh1 ssh_cipher_mask_ssh1
|
||||
#define cipher_name ssh_cipher_name
|
||||
#define cipher_number ssh_cipher_number
|
||||
#define cipher_set_key_string ssh_cipher_set_key_string
|
||||
#define cipher_set_keycontext ssh_cipher_set_keycontext
|
||||
#define cipher_set_keyiv ssh_cipher_set_keyiv
|
||||
#define ciphers_valid ssh_ciphers_valid
|
||||
#define cleanhostname ssh_cleanhostname
|
||||
#define cleanup_exit ssh_cleanup_exit
|
||||
#define closefrom ssh_closefrom
|
||||
#define colon ssh_colon
|
||||
#define compat_cipher_proposal ssh_compat_cipher_proposal
|
||||
#define compat_datafellows ssh_compat_datafellows
|
||||
#define convtime ssh_convtime
|
||||
#define decode_reply ssh_decode_reply
|
||||
#define deny_input_open ssh_deny_input_open
|
||||
#define derive_ssh1_session_id ssh_derive_ssh1_session_id
|
||||
#define detect_attack ssh_detect_attack
|
||||
#define dh_estimate ssh_dh_estimate
|
||||
#define dh_gen_key ssh_dh_gen_key
|
||||
#define dh_new_group ssh_dh_new_group
|
||||
#define dh_new_group1 ssh_dh_new_group1
|
||||
#define dh_new_group14 ssh_dh_new_group14
|
||||
#define dh_new_group_asc ssh_dh_new_group_asc
|
||||
#define dh_pub_is_valid ssh_dh_pub_is_valid
|
||||
#define dispatch_init ssh_dispatch_init
|
||||
#define dispatch_protocol_error ssh_dispatch_protocol_error
|
||||
#define dispatch_protocol_ignore ssh_dispatch_protocol_ignore
|
||||
#define dispatch_range ssh_dispatch_range
|
||||
#define dispatch_run ssh_dispatch_run
|
||||
#define dispatch_set ssh_dispatch_set
|
||||
#define do_log ssh_do_log
|
||||
#define dump_base64 ssh_dump_base64
|
||||
#define enable_compat13 ssh_enable_compat13
|
||||
#define enable_compat20 ssh_enable_compat20
|
||||
#define evp_acss ssh_evp_acss
|
||||
#define evp_aes_128_ctr ssh_evp_aes_128_ctr
|
||||
#define evp_rijndael ssh_evp_rijndael
|
||||
#define evp_ssh1_3des ssh_evp_ssh1_3des
|
||||
#define evp_ssh1_bf ssh_evp_ssh1_bf
|
||||
#define export_dns_rr ssh_export_dns_rr
|
||||
#define freeargs ssh_freeargs
|
||||
#define freerrset ssh_freerrset
|
||||
#define gen_candidates ssh_gen_candidates
|
||||
#define get_canonical_hostname ssh_get_canonical_hostname
|
||||
#define get_local_ipaddr ssh_get_local_ipaddr
|
||||
#define get_local_name ssh_get_local_name
|
||||
#define get_local_port ssh_get_local_port
|
||||
#define get_peer_ipaddr ssh_get_peer_ipaddr
|
||||
#define get_peer_port ssh_get_peer_port
|
||||
#define get_remote_ipaddr ssh_get_remote_ipaddr
|
||||
#define get_remote_name_or_ip ssh_get_remote_name_or_ip
|
||||
#define get_remote_port ssh_get_remote_port
|
||||
#define getrrsetbyname ssh_getrrsetbyname
|
||||
#define host_hash ssh_host_hash
|
||||
#define hostfile_read_key ssh_hostfile_read_key
|
||||
#define hpdelim ssh_hpdelim
|
||||
#define init_rng ssh_init_rng
|
||||
#define ipv64_normalise_mapped ssh_ipv64_normalise_mapped
|
||||
#define kex_derive_keys ssh_kex_derive_keys
|
||||
#define kex_dh_hash ssh_kex_dh_hash
|
||||
#define kex_finish ssh_kex_finish
|
||||
#define kex_get_newkeys ssh_kex_get_newkeys
|
||||
#define kex_input_kexinit ssh_kex_input_kexinit
|
||||
#define kex_send_kexinit ssh_kex_send_kexinit
|
||||
#define kex_setup ssh_kex_setup
|
||||
#define kexdh_client ssh_kexdh_client
|
||||
#define kexgex_client ssh_kexgex_client
|
||||
#define kexgex_hash ssh_kexgex_hash
|
||||
#define key_demote ssh_key_demote
|
||||
#define key_equal ssh_key_equal
|
||||
#define key_fingerprint ssh_key_fingerprint
|
||||
#define key_fingerprint_raw ssh_key_fingerprint_raw
|
||||
#define key_free ssh_key_free
|
||||
#define key_from_blob ssh_key_from_blob
|
||||
#define key_from_private ssh_key_from_private
|
||||
#define key_generate ssh_key_generate
|
||||
#define key_load_private ssh_key_load_private
|
||||
#define key_load_private_pem ssh_key_load_private_pem
|
||||
#define key_load_private_type ssh_key_load_private_type
|
||||
#define key_load_public ssh_key_load_public
|
||||
#define key_load_public_type ssh_key_load_public_type
|
||||
#define key_names_valid2 ssh_key_names_valid2
|
||||
#define key_new ssh_key_new
|
||||
#define key_new_private ssh_key_new_private
|
||||
#define key_read ssh_key_read
|
||||
#define key_save_private ssh_key_save_private
|
||||
#define key_sign ssh_key_sign
|
||||
#define key_size ssh_key_size
|
||||
#define key_ssh_name ssh_key_ssh_name
|
||||
#define key_to_blob ssh_key_to_blob
|
||||
#define key_type ssh_key_type
|
||||
#define key_type_from_name ssh_key_type_from_name
|
||||
#define key_verify ssh_key_verify
|
||||
#define key_write ssh_key_write
|
||||
#define log_facility_number ssh_log_facility_number
|
||||
#define log_init ssh_log_init
|
||||
#define log_level_number ssh_log_level_number
|
||||
#define lookup_key_in_hostfile_by_type ssh_lookup_key_in_hostfile_by_type
|
||||
#define mac_compute ssh_mac_compute
|
||||
#define mac_init ssh_mac_init
|
||||
#define mac_valid ssh_mac_valid
|
||||
#define match_host_and_ip ssh_match_host_and_ip
|
||||
#define match_hostname ssh_match_hostname
|
||||
#define match_list ssh_match_list
|
||||
#define match_pattern ssh_match_pattern
|
||||
#define match_pattern_list ssh_match_pattern_list
|
||||
#define match_user ssh_match_user
|
||||
#define mm_receive_fd ssh_mm_receive_fd
|
||||
#define mm_send_fd ssh_mm_send_fd
|
||||
#define mysignal ssh_mysignal
|
||||
#define packet_add_padding ssh_packet_add_padding
|
||||
#define packet_close ssh_packet_close
|
||||
#define packet_connection_is_ipv4 ssh_packet_connection_is_ipv4
|
||||
#define packet_connection_is_on_socket ssh_packet_connection_is_on_socket
|
||||
#define packet_disconnect ssh_packet_disconnect
|
||||
#define packet_get_bignum ssh_packet_get_bignum
|
||||
#define packet_get_bignum2 ssh_packet_get_bignum2
|
||||
#define packet_get_char ssh_packet_get_char
|
||||
#define packet_get_connection_in ssh_packet_get_connection_in
|
||||
#define packet_get_connection_out ssh_packet_get_connection_out
|
||||
#define packet_get_encryption_key ssh_packet_get_encryption_key
|
||||
#define packet_get_int ssh_packet_get_int
|
||||
#define packet_get_keycontext ssh_packet_get_keycontext
|
||||
#define packet_get_keyiv ssh_packet_get_keyiv
|
||||
#define packet_get_keyiv_len ssh_packet_get_keyiv_len
|
||||
#define packet_get_protocol_flags ssh_packet_get_protocol_flags
|
||||
#define packet_get_raw ssh_packet_get_raw
|
||||
#define packet_get_ssh1_cipher ssh_packet_get_ssh1_cipher
|
||||
#define packet_get_state ssh_packet_get_state
|
||||
#define packet_get_string ssh_packet_get_string
|
||||
#define packet_have_data_to_write ssh_packet_have_data_to_write
|
||||
#define packet_is_interactive ssh_packet_is_interactive
|
||||
#define packet_need_rekeying ssh_packet_need_rekeying
|
||||
#define packet_not_very_much_data_to_write ssh_packet_not_very_much_data_to_write
|
||||
#define packet_process_incoming ssh_packet_process_incoming
|
||||
#define packet_put_bignum ssh_packet_put_bignum
|
||||
#define packet_put_bignum2 ssh_packet_put_bignum2
|
||||
#define packet_put_char ssh_packet_put_char
|
||||
#define packet_put_cstring ssh_packet_put_cstring
|
||||
#define packet_put_int ssh_packet_put_int
|
||||
#define packet_put_raw ssh_packet_put_raw
|
||||
#define packet_put_string ssh_packet_put_string
|
||||
#define packet_read ssh_packet_read
|
||||
#define packet_read_expect ssh_packet_read_expect
|
||||
#define packet_read_poll ssh_packet_read_poll
|
||||
#define packet_read_poll_seqnr ssh_packet_read_poll_seqnr
|
||||
#define packet_read_seqnr ssh_packet_read_seqnr
|
||||
#define packet_remaining ssh_packet_remaining
|
||||
#define packet_send ssh_packet_send
|
||||
#define packet_send_debug ssh_packet_send_debug
|
||||
#define packet_send_ignore ssh_packet_send_ignore
|
||||
#define packet_set_authenticated ssh_packet_set_authenticated
|
||||
#define packet_set_connection ssh_packet_set_connection
|
||||
#define packet_set_encryption_key ssh_packet_set_encryption_key
|
||||
#define packet_set_interactive ssh_packet_set_interactive
|
||||
#define packet_set_iv ssh_packet_set_iv
|
||||
#define packet_set_keycontext ssh_packet_set_keycontext
|
||||
#define packet_set_maxsize ssh_packet_set_maxsize
|
||||
#define packet_set_nonblocking ssh_packet_set_nonblocking
|
||||
#define packet_set_protocol_flags ssh_packet_set_protocol_flags
|
||||
#define packet_set_rekey_limit ssh_packet_set_rekey_limit
|
||||
#define packet_set_server ssh_packet_set_server
|
||||
#define packet_set_state ssh_packet_set_state
|
||||
#define packet_start ssh_packet_start
|
||||
#define packet_start_compression ssh_packet_start_compression
|
||||
#define packet_write_poll ssh_packet_write_poll
|
||||
#define packet_write_wait ssh_packet_write_wait
|
||||
#define percent_expand ssh_percent_expand
|
||||
#define permanently_set_uid ssh_permanently_set_uid
|
||||
#define prime_test ssh_prime_test
|
||||
#define proto_spec ssh_proto_spec
|
||||
#define pwcopy ssh_pwcopy
|
||||
#define read_keyfile_line ssh_read_keyfile_line
|
||||
#define read_passphrase ssh_read_passphrase
|
||||
#define refresh_progress_meter ssh_refresh_progress_meter
|
||||
#define replacearg ssh_replacearg
|
||||
#define restore_uid ssh_restore_uid
|
||||
#define rijndael_decrypt ssh_rijndael_decrypt
|
||||
#define rijndael_encrypt ssh_rijndael_encrypt
|
||||
#define rijndael_set_key ssh_rijndael_set_key
|
||||
#define rsa_generate_additional_parameters ssh_rsa_generate_additional_parameters
|
||||
#define rsa_private_decrypt ssh_rsa_private_decrypt
|
||||
#define rsa_public_encrypt ssh_rsa_public_encrypt
|
||||
#define sanitise_stdfd ssh_sanitise_stdfd
|
||||
#define seed_rng ssh_seed_rng
|
||||
#define set_newkeys ssh_set_newkeys
|
||||
#define set_nodelay ssh_set_nodelay
|
||||
#define set_nonblock ssh_set_nonblock
|
||||
#define shadow_pw ssh_shadow_pw
|
||||
#define ssh1_3des_iv ssh_ssh1_3des_iv
|
||||
#define start_progress_meter ssh_start_progress_meter
|
||||
#define stop_progress_meter ssh_stop_progress_meter
|
||||
#define strdelim ssh_strdelim
|
||||
#define strnvis ssh_strnvis
|
||||
#define strvis ssh_strvis
|
||||
#define strvisx ssh_strvisx
|
||||
#define sys_tun_open ssh_sys_tun_open
|
||||
#define temporarily_use_uid ssh_temporarily_use_uid
|
||||
#define tilde_expand_filename ssh_tilde_expand_filename
|
||||
#define tohex ssh_tohex
|
||||
#define tty_make_modes ssh_tty_make_modes
|
||||
#define tty_parse_modes ssh_tty_parse_modes
|
||||
#define tun_open ssh_tun_open
|
||||
#define unset_nonblock ssh_unset_nonblock
|
||||
#define uudecode ssh_uudecode
|
||||
#define uuencode ssh_uuencode
|
||||
#define verify_host_key_dns ssh_verify_host_key_dns
|
||||
#define vis ssh_vis
|
||||
#define x11_connect_display ssh_x11_connect_display
|
||||
#define x11_create_display_inet ssh_x11_create_display_inet
|
||||
#define x11_input_open ssh_x11_input_open
|
||||
#define x11_request_forwarding_with_spoofing ssh_x11_request_forwarding_with_spoofing
|
||||
#define xcrypt ssh_xcrypt
|
||||
#define xfree ssh_xfree
|
||||
#define xmalloc ssh_xmalloc
|
||||
#define xmmap ssh_xmmap
|
||||
#define xrealloc ssh_xrealloc
|
||||
#define xstrdup ssh_xstrdup
|
71
include/res_update.h
Normal file
71
include/res_update.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1999 by Internet Software Consortium, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: res_update.h,v 1.1.206.1 2004/03/09 08:33:29 marka Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef __RES_UPDATE_H
|
||||
#define __RES_UPDATE_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
/*
|
||||
* This RR-like structure is particular to UPDATE.
|
||||
*/
|
||||
struct ns_updrec {
|
||||
struct {
|
||||
struct ns_updrec *prev;
|
||||
struct ns_updrec *next;
|
||||
} r_link, r_glink;
|
||||
ns_sect r_section; /* ZONE/PREREQUISITE/UPDATE */
|
||||
char * r_dname; /* owner of the RR */
|
||||
ns_class r_class; /* class number */
|
||||
ns_type r_type; /* type number */
|
||||
u_int32_t r_ttl; /* time to live */
|
||||
u_char * r_data; /* rdata fields as text string */
|
||||
u_int r_size; /* size of r_data field */
|
||||
int r_opcode; /* type of operation */
|
||||
/* following fields for private use by the resolver/server routines */
|
||||
struct databuf *r_dp; /* databuf to process */
|
||||
struct databuf *r_deldp; /* databuf's deleted/overwritten */
|
||||
u_int r_zone; /* zone number on server */
|
||||
};
|
||||
typedef struct ns_updrec ns_updrec;
|
||||
typedef struct {
|
||||
ns_updrec *head;
|
||||
ns_updrec *tail;
|
||||
} ns_updque;
|
||||
|
||||
#define res_mkupdate __res_mkupdate
|
||||
#define res_update __res_update
|
||||
#define res_mkupdrec __res_mkupdrec
|
||||
#define res_freeupdrec __res_freeupdrec
|
||||
#define res_nmkupdate __res_nmkupdate
|
||||
#define res_nupdate __res_nupdate
|
||||
|
||||
int res_mkupdate(ns_updrec *, u_char *, int);
|
||||
int res_update(ns_updrec *);
|
||||
ns_updrec * res_mkupdrec(int, const char *, u_int, u_int, u_long);
|
||||
void res_freeupdrec(ns_updrec *);
|
||||
int res_nmkupdate(res_state, ns_updrec *, u_char *, int);
|
||||
int res_nupdate(res_state, ns_updrec *, ns_tsig_key *);
|
||||
|
||||
#endif /*__RES_UPDATE_H*/
|
210
lib/libc/nameser/ns_samedomain.c
Normal file
210
lib/libc/nameser/ns_samedomain.c
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1995,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] = "$Id: ns_samedomain.c,v 1.1.2.2.4.2 2004/03/16 12:34:17 marka Exp $";
|
||||
#endif
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/*
|
||||
* int
|
||||
* ns_samedomain(a, b)
|
||||
* Check whether a name belongs to a domain.
|
||||
* Inputs:
|
||||
* a - the domain whose ancestory is being verified
|
||||
* b - the potential ancestor we're checking against
|
||||
* Return:
|
||||
* boolean - is a at or below b?
|
||||
* Notes:
|
||||
* Trailing dots are first removed from name and domain.
|
||||
* Always compare complete subdomains, not only whether the
|
||||
* domain name is the trailing string of the given name.
|
||||
*
|
||||
* "host.foobar.top" lies in "foobar.top" and in "top" and in ""
|
||||
* but NOT in "bar.top"
|
||||
*/
|
||||
|
||||
int
|
||||
ns_samedomain(const char *a, const char *b) {
|
||||
size_t la, lb;
|
||||
int diff, i, escaped;
|
||||
const char *cp;
|
||||
|
||||
la = strlen(a);
|
||||
lb = strlen(b);
|
||||
|
||||
/* Ignore a trailing label separator (i.e. an unescaped dot) in 'a'. */
|
||||
if (la != 0U && a[la - 1] == '.') {
|
||||
escaped = 0;
|
||||
/* Note this loop doesn't get executed if la==1. */
|
||||
for (i = la - 2; i >= 0; i--)
|
||||
if (a[i] == '\\') {
|
||||
if (escaped)
|
||||
escaped = 0;
|
||||
else
|
||||
escaped = 1;
|
||||
} else
|
||||
break;
|
||||
if (!escaped)
|
||||
la--;
|
||||
}
|
||||
|
||||
/* Ignore a trailing label separator (i.e. an unescaped dot) in 'b'. */
|
||||
if (lb != 0U && b[lb - 1] == '.') {
|
||||
escaped = 0;
|
||||
/* note this loop doesn't get executed if lb==1 */
|
||||
for (i = lb - 2; i >= 0; i--)
|
||||
if (b[i] == '\\') {
|
||||
if (escaped)
|
||||
escaped = 0;
|
||||
else
|
||||
escaped = 1;
|
||||
} else
|
||||
break;
|
||||
if (!escaped)
|
||||
lb--;
|
||||
}
|
||||
|
||||
/* lb == 0 means 'b' is the root domain, so 'a' must be in 'b'. */
|
||||
if (lb == 0U)
|
||||
return (1);
|
||||
|
||||
/* 'b' longer than 'a' means 'a' can't be in 'b'. */
|
||||
if (lb > la)
|
||||
return (0);
|
||||
|
||||
/* 'a' and 'b' being equal at this point indicates sameness. */
|
||||
if (lb == la)
|
||||
return (strncasecmp(a, b, lb) == 0);
|
||||
|
||||
/* Ok, we know la > lb. */
|
||||
|
||||
diff = la - lb;
|
||||
|
||||
/*
|
||||
* If 'a' is only 1 character longer than 'b', then it can't be
|
||||
* a subdomain of 'b' (because of the need for the '.' label
|
||||
* separator).
|
||||
*/
|
||||
if (diff < 2)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* If the character before the last 'lb' characters of 'b'
|
||||
* isn't '.', then it can't be a match (this lets us avoid
|
||||
* having "foobar.com" match "bar.com").
|
||||
*/
|
||||
if (a[diff - 1] != '.')
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* We're not sure about that '.', however. It could be escaped
|
||||
* and thus not a really a label separator.
|
||||
*/
|
||||
escaped = 0;
|
||||
for (i = diff - 2; i >= 0; i--)
|
||||
if (a[i] == '\\') {
|
||||
if (escaped)
|
||||
escaped = 0;
|
||||
else
|
||||
escaped = 1;
|
||||
} else
|
||||
break;
|
||||
if (escaped)
|
||||
return (0);
|
||||
|
||||
/* Now compare aligned trailing substring. */
|
||||
cp = a + diff;
|
||||
return (strncasecmp(cp, b, lb) == 0);
|
||||
}
|
||||
|
||||
#ifndef _LIBC
|
||||
/*
|
||||
* int
|
||||
* ns_subdomain(a, b)
|
||||
* is "a" a subdomain of "b"?
|
||||
*/
|
||||
int
|
||||
ns_subdomain(const char *a, const char *b) {
|
||||
return (ns_samename(a, b) != 1 && ns_samedomain(a, b));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* int
|
||||
* ns_makecanon(src, dst, dstsize)
|
||||
* make a canonical copy of domain name "src"
|
||||
* notes:
|
||||
* foo -> foo.
|
||||
* foo. -> foo.
|
||||
* foo.. -> foo.
|
||||
* foo\. -> foo\..
|
||||
* foo\\. -> foo\\.
|
||||
*/
|
||||
|
||||
int
|
||||
ns_makecanon(const char *src, char *dst, size_t dstsize) {
|
||||
size_t n = strlen(src);
|
||||
|
||||
if (n + sizeof "." > dstsize) { /* Note: sizeof == 2 */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
strcpy(dst, src);
|
||||
while (n >= 1U && dst[n - 1] == '.') /* Ends in "." */
|
||||
if (n >= 2U && dst[n - 2] == '\\' && /* Ends in "\." */
|
||||
(n < 3U || dst[n - 3] != '\\')) /* But not "\\." */
|
||||
break;
|
||||
else
|
||||
dst[--n] = '\0';
|
||||
dst[n++] = '.';
|
||||
dst[n] = '\0';
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* int
|
||||
* ns_samename(a, b)
|
||||
* determine whether domain name "a" is the same as domain name "b"
|
||||
* return:
|
||||
* -1 on error
|
||||
* 0 if names differ
|
||||
* 1 if names are the same
|
||||
*/
|
||||
|
||||
int
|
||||
ns_samename(const char *a, const char *b) {
|
||||
char ta[NS_MAXDNAME], tb[NS_MAXDNAME];
|
||||
|
||||
if (ns_makecanon(a, ta, sizeof ta) < 0 ||
|
||||
ns_makecanon(b, tb, sizeof tb) < 0)
|
||||
return (-1);
|
||||
if (strcasecmp(ta, tb) == 0)
|
||||
return (1);
|
||||
else
|
||||
return (0);
|
||||
}
|
10
lib/libc/resolv/Makefile.inc
Normal file
10
lib/libc/resolv/Makefile.inc
Normal file
@ -0,0 +1,10 @@
|
||||
# $FreeBSD$
|
||||
|
||||
# resolv sources
|
||||
.PATH: ${.CURDIR}/resolv
|
||||
|
||||
SRCS+= herror.c h_errno.c mtctxres.c res_comp.c res_data.c res_debug.c \
|
||||
res_findzonecut.c res_init.c res_mkquery.c res_mkupdate.c \
|
||||
res_query.c res_send.c res_state.c res_update.c
|
||||
|
||||
SYM_MAPS+= ${.CURDIR}/resolv/Symbol.map
|
46
lib/libc/resolv/h_errno.c
Normal file
46
lib/libc/resolv/h_errno.c
Normal file
@ -0,0 +1,46 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 The FreeBSD Project. 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 <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#undef h_errno
|
||||
extern int h_errno;
|
||||
|
||||
int *
|
||||
__h_errno(void)
|
||||
{
|
||||
return (&__res_state()->res_h_errno);
|
||||
}
|
||||
|
||||
void
|
||||
__h_errno_set(res_state res, int err)
|
||||
{
|
||||
h_errno = res->res_h_errno = err;
|
||||
}
|
87
lib/libc/resolv/res_state.c
Normal file
87
lib/libc/resolv/res_state.c
Normal file
@ -0,0 +1,87 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 The FreeBSD Project. 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 <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "namespace.h"
|
||||
#include "reentrant.h"
|
||||
#include "un-namespace.h"
|
||||
|
||||
#undef _res
|
||||
|
||||
struct __res_state _res;
|
||||
|
||||
static thread_key_t res_key;
|
||||
static once_t res_init_once = ONCE_INITIALIZER;
|
||||
static int res_thr_keycreated = 0;
|
||||
|
||||
static void
|
||||
free_res(void *ptr)
|
||||
{
|
||||
res_state statp = ptr;
|
||||
|
||||
if (statp->_u._ext.ext != NULL)
|
||||
res_ndestroy(statp);
|
||||
free(statp);
|
||||
}
|
||||
|
||||
static void
|
||||
res_keycreate(void)
|
||||
{
|
||||
res_thr_keycreated = thr_keycreate(&res_key, free_res) == 0;
|
||||
}
|
||||
|
||||
res_state
|
||||
__res_state(void)
|
||||
{
|
||||
res_state statp;
|
||||
|
||||
if (thr_main() != 0)
|
||||
return (&_res);
|
||||
|
||||
if (thr_once(&res_init_once, res_keycreate) != 0 ||
|
||||
!res_thr_keycreated)
|
||||
return (&_res);
|
||||
|
||||
statp = thr_getspecific(res_key);
|
||||
if (statp != NULL)
|
||||
return (statp);
|
||||
statp = calloc(1, sizeof(*statp));
|
||||
if (statp == NULL)
|
||||
return (&_res);
|
||||
#ifdef __BIND_RES_TEXT
|
||||
statp->options = RES_TIMEOUT; /* Motorola, et al. */
|
||||
#endif
|
||||
if (thr_setspecific(res_key, statp) == 0)
|
||||
return (statp);
|
||||
free(statp);
|
||||
return (&_res);
|
||||
}
|
76
lib/libutil/kld.c
Normal file
76
lib/libutil/kld.c
Normal file
@ -0,0 +1,76 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 Dag-Erling Coïdan Smørgrav
|
||||
* 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
|
||||
* in this position and unchanged.
|
||||
* 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 <sys/param.h>
|
||||
#include <sys/linker.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <libutil.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
kld_isloaded(const char *name)
|
||||
{
|
||||
struct kld_file_stat fstat;
|
||||
struct module_stat mstat;
|
||||
const char *ko;
|
||||
int fid, mid;
|
||||
|
||||
for (fid = kldnext(0); fid > 0; fid = kldnext(fid)) {
|
||||
fstat.version = sizeof(fstat);
|
||||
if (kldstat(fid, &fstat) != 0)
|
||||
continue;
|
||||
/* check if the file name matches the supplied name */
|
||||
if (strcmp(fstat.name, name) == 0)
|
||||
return (1);
|
||||
/* strip .ko and try again */
|
||||
if ((ko = strstr(fstat.name, ".ko")) != NULL &&
|
||||
strlen(name) == (size_t)(ko - fstat.name) &&
|
||||
strncmp(fstat.name, name, ko - fstat.name) == 0)
|
||||
return (1);
|
||||
/* look for a matching module within the file */
|
||||
for (mid = kldfirstmod(fid); mid > 0; mid = modfnext(mid)) {
|
||||
mstat.version = sizeof(mstat);
|
||||
if (modstat(mid, &mstat) != 0)
|
||||
continue;
|
||||
if (strcmp(mstat.name, name) == 0)
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
kld_load(const char *name)
|
||||
{
|
||||
if (kldload(name) == -1 && errno != EEXIST)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
85
share/man/man5/linsysfs.5
Normal file
85
share/man/man5/linsysfs.5
Normal file
@ -0,0 +1,85 @@
|
||||
.\" Written by Garrett Wollman
|
||||
.\" This file is in the public domain.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 6, 2006
|
||||
.Dt LINSYSFS 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm linsysfs
|
||||
.Nd Linux system file system
|
||||
.Sh SYNOPSIS
|
||||
.Bd -literal
|
||||
linsys /compat/linux/sys linsysfs rw 0 0
|
||||
.Ed
|
||||
.Sh DESCRIPTION
|
||||
The Linux system file system, or
|
||||
.Nm ,
|
||||
emulates a subset of the Linux sys file system and is required for
|
||||
the complete operation of some Linux binaries.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
provides a two-level view of devices.
|
||||
At the highest level, PCI devices themselves are named, according to
|
||||
their bus, slot and function in the system hierachy.
|
||||
PCI storage devices are listed in the scsi_host class with a device sym-link
|
||||
to the PCI directories of the devices.
|
||||
.Pp
|
||||
Each device node is a directory containing some files and directories:
|
||||
.Bl -tag -width status
|
||||
.It Pa host
|
||||
A place holder for storage
|
||||
.Pa host
|
||||
information.
|
||||
.It Pa pci_id
|
||||
A directory for the
|
||||
.Pa pci_id
|
||||
that contains either the device information or another directory structure
|
||||
for a PCI bridge.
|
||||
.El
|
||||
.Pp
|
||||
Each host node of scsi_host is a directory containing some files and directories:
|
||||
.Bl -tag -width proc_name
|
||||
.It Pa proc_name
|
||||
The Linux registered driver name for these devices.
|
||||
.It Pa device
|
||||
A sym-link to the PCI
|
||||
.Pa device
|
||||
directory.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /compat/linux/sys/devices/pci0000:00 -compact
|
||||
.It Pa /compat/linux/sys
|
||||
The normal mount point for the
|
||||
.Nm .
|
||||
.It Pa /compat/linux/sys/class/scsi_host
|
||||
The storage host node.
|
||||
.It Pa /compat/linux/sys/devices/pci0000:00
|
||||
The PCI device hierarchy node.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mount 2 ,
|
||||
.Xr unmount 2 ,
|
||||
.Xr linprocfs 5 ,
|
||||
.Xr pseudofs 9
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
first appeared in
|
||||
.Fx 7.0 .
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm
|
||||
was derived from
|
||||
.Nm linprocfs
|
||||
by
|
||||
.An Doug Ambrisko .
|
||||
This manual page was edited by
|
||||
.An Doug Ambrisko ,
|
||||
based on the
|
||||
.Xr linprocfs 5
|
||||
manual page by
|
||||
.An Garrett Wollman .
|
674
sys/arm/at91/at91.c
Normal file
674
sys/arm/at91/at91.c
Normal file
@ -0,0 +1,674 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Olivier Houchard. 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_kern.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_page.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
||||
#define _ARM32_BUS_DMA_PRIVATE
|
||||
#include <machine/bus.h>
|
||||
#include <machine/intr.h>
|
||||
|
||||
#include <arm/at91/at91rm92reg.h>
|
||||
#include <arm/at91/at91var.h>
|
||||
|
||||
static struct at91_softc *at91_softc;
|
||||
|
||||
static int
|
||||
at91_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
|
||||
bus_space_handle_t *bshp)
|
||||
{
|
||||
vm_paddr_t pa, endpa;
|
||||
|
||||
pa = trunc_page(bpa);
|
||||
if (pa >= 0xfff00000)
|
||||
return (0);
|
||||
endpa = round_page(bpa + size);
|
||||
|
||||
*bshp = (vm_offset_t)pmap_mapdev(pa, endpa - pa);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
at91_bs_unmap(void *t, bus_size_t size)
|
||||
{
|
||||
vm_offset_t va, endva;
|
||||
|
||||
va = trunc_page((vm_offset_t)t);
|
||||
endva = va + round_page(size);
|
||||
|
||||
/* Free the kernel virtual mapping. */
|
||||
kmem_free(kernel_map, va, endva - va);
|
||||
}
|
||||
|
||||
static int
|
||||
at91_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset,
|
||||
bus_size_t size, bus_space_handle_t *nbshp)
|
||||
{
|
||||
|
||||
*nbshp = bsh + offset;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
at91_barrier(void *t, bus_space_handle_t bsh, bus_size_t size, bus_size_t b,
|
||||
int a)
|
||||
{
|
||||
}
|
||||
|
||||
bs_protos(generic);
|
||||
bs_protos(generic_armv4);
|
||||
|
||||
struct bus_space at91_bs_tag = {
|
||||
/* cookie */
|
||||
(void *) 0,
|
||||
|
||||
/* mapping/unmapping */
|
||||
at91_bs_map,
|
||||
at91_bs_unmap,
|
||||
at91_bs_subregion,
|
||||
|
||||
/* allocation/deallocation */
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
/* barrier */
|
||||
at91_barrier,
|
||||
|
||||
/* read (single) */
|
||||
generic_bs_r_1,
|
||||
generic_armv4_bs_r_2,
|
||||
generic_bs_r_4,
|
||||
NULL,
|
||||
|
||||
/* read multiple */
|
||||
generic_bs_rm_1,
|
||||
generic_armv4_bs_rm_2,
|
||||
generic_bs_rm_4,
|
||||
NULL,
|
||||
|
||||
/* read region */
|
||||
generic_bs_rr_1,
|
||||
generic_armv4_bs_rr_2,
|
||||
generic_bs_rr_4,
|
||||
NULL,
|
||||
|
||||
/* write (single) */
|
||||
generic_bs_w_1,
|
||||
generic_armv4_bs_w_2,
|
||||
generic_bs_w_4,
|
||||
NULL,
|
||||
|
||||
/* write multiple */
|
||||
generic_bs_wm_1,
|
||||
generic_armv4_bs_wm_2,
|
||||
generic_bs_wm_4,
|
||||
NULL,
|
||||
|
||||
/* write region */
|
||||
NULL,
|
||||
generic_armv4_bs_wr_2,
|
||||
generic_bs_wr_4,
|
||||
NULL,
|
||||
|
||||
/* set multiple */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
/* set region */
|
||||
NULL,
|
||||
generic_armv4_bs_sr_2,
|
||||
generic_bs_sr_4,
|
||||
NULL,
|
||||
|
||||
/* copy */
|
||||
NULL,
|
||||
generic_armv4_bs_c_2,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int
|
||||
at91_probe(device_t dev)
|
||||
{
|
||||
device_set_desc(dev, "AT91RM9200 device bus");
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
at91_identify(driver_t *drv, device_t parent)
|
||||
{
|
||||
|
||||
BUS_ADD_CHILD(parent, 0, "atmelarm", 0);
|
||||
}
|
||||
|
||||
struct arm32_dma_range *
|
||||
bus_dma_get_range(void)
|
||||
{
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
bus_dma_get_range_nb(void)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
extern void irq_entry(void);
|
||||
|
||||
static void
|
||||
at91_add_child(device_t dev, int prio, const char *name, int unit,
|
||||
bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2)
|
||||
{
|
||||
device_t kid;
|
||||
struct at91_ivar *ivar;
|
||||
|
||||
kid = device_add_child_ordered(dev, prio, name, unit);
|
||||
if (kid == NULL) {
|
||||
printf("Can't add child %s%d ordered\n", name, unit);
|
||||
return;
|
||||
}
|
||||
ivar = malloc(sizeof(*ivar), M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
if (ivar == NULL) {
|
||||
device_delete_child(dev, kid);
|
||||
printf("Can't add alloc ivar\n");
|
||||
return;
|
||||
}
|
||||
device_set_ivars(kid, ivar);
|
||||
resource_list_init(&ivar->resources);
|
||||
if (irq0 != -1)
|
||||
bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
|
||||
if (irq1 != 0)
|
||||
bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
|
||||
if (irq2 != 0)
|
||||
bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
|
||||
if (addr != 0)
|
||||
bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
|
||||
}
|
||||
|
||||
struct cpu_devs
|
||||
{
|
||||
const char *name;
|
||||
int unit;
|
||||
bus_addr_t mem_base;
|
||||
bus_size_t mem_len;
|
||||
int irq0;
|
||||
int irq1;
|
||||
int irq2;
|
||||
};
|
||||
|
||||
struct cpu_devs at91rm9200_devs[] =
|
||||
{
|
||||
// All the "system" devices
|
||||
{
|
||||
"at91_st", 0,
|
||||
AT91RM92_BASE + AT91RM92_ST_BASE, AT91RM92_ST_SIZE,
|
||||
AT91RM92_IRQ_SYSTEM
|
||||
},
|
||||
{
|
||||
"at91_pio", 0,
|
||||
AT91RM92_BASE + AT91RM92_PIOA_BASE, AT91RM92_PIO_SIZE,
|
||||
AT91RM92_IRQ_SYSTEM
|
||||
},
|
||||
{
|
||||
"at91_pio", 1,
|
||||
AT91RM92_BASE + AT91RM92_PIOB_BASE, AT91RM92_PIO_SIZE,
|
||||
AT91RM92_IRQ_SYSTEM
|
||||
},
|
||||
{
|
||||
"at91_pio", 2,
|
||||
AT91RM92_BASE + AT91RM92_PIOC_BASE, AT91RM92_PIO_SIZE,
|
||||
AT91RM92_IRQ_SYSTEM
|
||||
},
|
||||
{
|
||||
"at91_pio", 3,
|
||||
AT91RM92_BASE + AT91RM92_PIOD_BASE, AT91RM92_PIO_SIZE,
|
||||
AT91RM92_IRQ_SYSTEM
|
||||
},
|
||||
{
|
||||
"at91_pmc", 0,
|
||||
AT91RM92_BASE + AT91RM92_PMC_BASE, AT91RM92_PMC_SIZE,
|
||||
AT91RM92_IRQ_SYSTEM
|
||||
},
|
||||
{
|
||||
"at91_aic", 0,
|
||||
AT91RM92_BASE + AT91RM92_AIC_BASE, AT91RM92_AIC_SIZE,
|
||||
0 // Interrupt controller has no interrupts!
|
||||
},
|
||||
{
|
||||
"at91_rtc", 0,
|
||||
AT91RM92_BASE + AT91RM92_RTC_BASE, AT91RM92_RTC_SIZE,
|
||||
AT91RM92_IRQ_SYSTEM
|
||||
},
|
||||
{
|
||||
"at91_mc", 0,
|
||||
AT91RM92_BASE + AT91RM92_MC_BASE, AT91RM92_MC_SIZE,
|
||||
AT91RM92_IRQ_SYSTEM
|
||||
},
|
||||
|
||||
// All other devices
|
||||
{
|
||||
"at91_tc", 0,
|
||||
AT91RM92_BASE + AT91RM92_TC0_BASE, AT91RM92_TC_SIZE,
|
||||
AT91RM92_IRQ_TC0, AT91RM92_IRQ_TC1, AT91RM92_IRQ_TC2
|
||||
},
|
||||
{
|
||||
"at91_tc", 1,
|
||||
AT91RM92_BASE + AT91RM92_TC1_BASE, AT91RM92_TC_SIZE,
|
||||
AT91RM92_IRQ_TC3, AT91RM92_IRQ_TC4, AT91RM92_IRQ_TC5
|
||||
},
|
||||
{
|
||||
"at91_udp", 0,
|
||||
AT91RM92_BASE + AT91RM92_UDP_BASE, AT91RM92_UDP_SIZE,
|
||||
AT91RM92_IRQ_UDP
|
||||
},
|
||||
{
|
||||
"at91_mci", 0,
|
||||
AT91RM92_BASE + AT91RM92_MCI_BASE, AT91RM92_MCI_SIZE,
|
||||
AT91RM92_IRQ_MCI
|
||||
},
|
||||
{
|
||||
"at91_twi", 0,
|
||||
AT91RM92_BASE + AT91RM92_TWI_BASE, AT91RM92_TWI_SIZE,
|
||||
AT91RM92_IRQ_TWI
|
||||
},
|
||||
{
|
||||
"ate", 0,
|
||||
AT91RM92_BASE + AT91RM92_EMAC_BASE, AT91RM92_EMAC_SIZE,
|
||||
AT91RM92_IRQ_EMAC
|
||||
},
|
||||
#ifndef SKYEYE_WORKAROUNDS
|
||||
{
|
||||
"uart", 0,
|
||||
AT91RM92_BASE + AT91RM92_DBGU_BASE, AT91RM92_DBGU_SIZE,
|
||||
AT91RM92_IRQ_SYSTEM
|
||||
},
|
||||
{
|
||||
"uart", 1,
|
||||
AT91RM92_BASE + AT91RM92_USART0_BASE, AT91RM92_USART_SIZE,
|
||||
AT91RM92_IRQ_USART0
|
||||
},
|
||||
{
|
||||
"uart", 2,
|
||||
AT91RM92_BASE + AT91RM92_USART1_BASE, AT91RM92_USART_SIZE,
|
||||
AT91RM92_IRQ_USART1
|
||||
},
|
||||
{
|
||||
"uart", 3,
|
||||
AT91RM92_BASE + AT91RM92_USART2_BASE, AT91RM92_USART_SIZE,
|
||||
AT91RM92_IRQ_USART2
|
||||
},
|
||||
{
|
||||
"uart", 4,
|
||||
AT91RM92_BASE + AT91RM92_USART3_BASE, AT91RM92_USART_SIZE,
|
||||
AT91RM92_IRQ_USART3
|
||||
},
|
||||
#else
|
||||
{
|
||||
"uart", 0,
|
||||
AT91RM92_BASE + AT91RM92_USART0_BASE, AT91RM92_USART_SIZE,
|
||||
AT91RM92_IRQ_USART0
|
||||
},
|
||||
#endif
|
||||
{
|
||||
"at91_ssc", 0,
|
||||
AT91RM92_BASE + AT91RM92_SSC0_BASE, AT91RM92_SSC_SIZE,
|
||||
AT91RM92_IRQ_SSC0
|
||||
},
|
||||
{
|
||||
"at91_ssc", 1,
|
||||
AT91RM92_BASE + AT91RM92_SSC1_BASE, AT91RM92_SSC_SIZE,
|
||||
AT91RM92_IRQ_SSC1
|
||||
},
|
||||
{
|
||||
"at91_ssc", 2,
|
||||
AT91RM92_BASE + AT91RM92_SSC2_BASE, AT91RM92_SSC_SIZE,
|
||||
AT91RM92_IRQ_SSC2
|
||||
},
|
||||
{
|
||||
"at91_spi", 0,
|
||||
AT91RM92_BASE + AT91RM92_SPI_BASE, AT91RM92_SPI_SIZE,
|
||||
AT91RM92_IRQ_SPI
|
||||
},
|
||||
{
|
||||
"ohci", 0,
|
||||
AT91RM92_OHCI_BASE, AT91RM92_OHCI_SIZE,
|
||||
AT91RM92_IRQ_UHP
|
||||
},
|
||||
{ 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static void
|
||||
at91_cpu_add_builtin_children(device_t dev, struct at91_softc *sc)
|
||||
{
|
||||
int i;
|
||||
struct cpu_devs *walker;
|
||||
|
||||
// XXX should look at the device id in the DBGU register and
|
||||
// XXX based on the CPU load in these devices
|
||||
for (i = 0, walker = at91rm9200_devs; walker->name; i++, walker++) {
|
||||
at91_add_child(dev, i, walker->name, walker->unit,
|
||||
walker->mem_base, walker->mem_len, walker->irq0,
|
||||
walker->irq1, walker->irq2);
|
||||
}
|
||||
}
|
||||
|
||||
#define NORMDEV 50
|
||||
|
||||
static int
|
||||
at91_attach(device_t dev)
|
||||
{
|
||||
struct at91_softc *sc = device_get_softc(dev);
|
||||
int i;
|
||||
|
||||
at91_softc = sc;
|
||||
sc->sc_st = &at91_bs_tag;
|
||||
sc->sc_sh = AT91RM92_BASE;
|
||||
sc->dev = dev;
|
||||
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_SYS_BASE,
|
||||
AT91RM92_SYS_SIZE, &sc->sc_sys_sh) != 0)
|
||||
panic("Enable to map IRQ registers");
|
||||
sc->sc_irq_rman.rm_type = RMAN_ARRAY;
|
||||
sc->sc_irq_rman.rm_descr = "AT91RM92 IRQs";
|
||||
sc->sc_mem_rman.rm_type = RMAN_ARRAY;
|
||||
sc->sc_mem_rman.rm_descr = "AT91RM92 Memory";
|
||||
#if 0
|
||||
sc->sc_usbmem_rman.rm_type = RMAN_ARRAY;
|
||||
sc->sc_usbmem_rman.rm_descr = "AT91RM92 USB Memory-mapped regs";
|
||||
#endif
|
||||
if (rman_init(&sc->sc_irq_rman) != 0 ||
|
||||
rman_manage_region(&sc->sc_irq_rman, 1, 31) != 0)
|
||||
panic("at91_attach: failed to set up IRQ rman");
|
||||
if (rman_init(&sc->sc_mem_rman) != 0 ||
|
||||
rman_manage_region(&sc->sc_mem_rman, 0xfff00000ul,
|
||||
0xfffffffful) != 0)
|
||||
panic("at91_attach: failed to set up memory rman");
|
||||
if (rman_manage_region(&sc->sc_mem_rman, AT91RM92_OHCI_BASE,
|
||||
AT91RM92_OHCI_BASE + AT91RM92_OHCI_SIZE - 1) != 0)
|
||||
panic("at91_attach: failed to set up ohci memory");
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_SVR +
|
||||
i * 4, i);
|
||||
/* Priority. */
|
||||
/* XXX: Give better priorities to IRQs */
|
||||
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_SMR + i * 4,
|
||||
0);
|
||||
if (i < 8)
|
||||
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_EOICR,
|
||||
1);
|
||||
|
||||
}
|
||||
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_SPU, 32);
|
||||
/* No debug. */
|
||||
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_DCR, 0);
|
||||
/* Disable and clear all interrupts. */
|
||||
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_IDCR, 0xffffffff);
|
||||
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_ICCR, 0xffffffff);
|
||||
|
||||
/* XXX */
|
||||
/* Disable all interrupts for RTC (0xe24 == RTC_IDR) */
|
||||
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xe24, 0xffffffff);
|
||||
/* DIsable all interrupts for DBGU */
|
||||
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x20c, 0xffffffff);
|
||||
/* Disable all interrupts for the SDRAM controller */
|
||||
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xfa8, 0xffffffff);
|
||||
|
||||
at91_cpu_add_builtin_children(dev, sc);
|
||||
|
||||
bus_generic_probe(dev);
|
||||
bus_generic_attach(dev);
|
||||
enable_interrupts(I32_bit | F32_bit);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static struct resource *
|
||||
at91_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
u_long start, u_long end, u_long count, u_int flags)
|
||||
{
|
||||
struct at91_softc *sc = device_get_softc(dev);
|
||||
struct resource_list_entry *rle;
|
||||
struct at91_ivar *ivar = device_get_ivars(child);
|
||||
struct resource_list *rl = &ivar->resources;
|
||||
|
||||
if (device_get_parent(child) != dev)
|
||||
return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
|
||||
type, rid, start, end, count, flags));
|
||||
|
||||
rle = resource_list_find(rl, type, *rid);
|
||||
if (rle == NULL)
|
||||
return (NULL);
|
||||
if (rle->res)
|
||||
panic("Resource rid %d type %d already in use", *rid, type);
|
||||
if (start == 0UL && end == ~0UL) {
|
||||
start = rle->start;
|
||||
count = ulmax(count, rle->count);
|
||||
end = ulmax(rle->end, start + count - 1);
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case SYS_RES_IRQ:
|
||||
rle->res = rman_reserve_resource(&sc->sc_irq_rman,
|
||||
start, end, count, flags, child);
|
||||
break;
|
||||
case SYS_RES_MEMORY:
|
||||
#if 0
|
||||
if (start >= 0x00300000 && start <= 0x003fffff)
|
||||
rle->res = rman_reserve_resource(&sc->sc_usbmem_rman,
|
||||
start, end, count, flags, child);
|
||||
else
|
||||
#endif
|
||||
rle->res = rman_reserve_resource(&sc->sc_mem_rman,
|
||||
start, end, count, flags, child);
|
||||
rman_set_bustag(rle->res, &at91_bs_tag);
|
||||
rman_set_bushandle(rle->res, start);
|
||||
break;
|
||||
}
|
||||
if (rle->res) {
|
||||
rle->start = rman_get_start(rle->res);
|
||||
rle->end = rman_get_end(rle->res);
|
||||
rle->count = count;
|
||||
rman_set_rid(rle->res, *rid);
|
||||
}
|
||||
return (rle->res);
|
||||
}
|
||||
|
||||
static struct resource_list *
|
||||
at91_get_resource_list(device_t dev, device_t child)
|
||||
{
|
||||
struct at91_ivar *ivar;
|
||||
|
||||
ivar = device_get_ivars(child);
|
||||
return (&(ivar->resources));
|
||||
}
|
||||
|
||||
static int
|
||||
at91_release_resource(device_t dev, device_t child, int type,
|
||||
int rid, struct resource *r)
|
||||
{
|
||||
struct resource_list *rl;
|
||||
struct resource_list_entry *rle;
|
||||
|
||||
rl = at91_get_resource_list(dev, child);
|
||||
if (rl == NULL)
|
||||
return (EINVAL);
|
||||
rle = resource_list_find(rl, type, rid);
|
||||
if (rle == NULL)
|
||||
return (EINVAL);
|
||||
rman_release_resource(r);
|
||||
rle->res = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
at91_setup_intr(device_t dev, device_t child,
|
||||
struct resource *ires, int flags, driver_intr_t *intr, void *arg,
|
||||
void **cookiep)
|
||||
{
|
||||
struct at91_softc *sc = device_get_softc(dev);
|
||||
|
||||
if (rman_get_start(ires) == AT91RM92_IRQ_SYSTEM && !(flags & INTR_FAST))
|
||||
panic("All system interrupt ISRs must be type INTR_FAST");
|
||||
BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, intr, arg,
|
||||
cookiep);
|
||||
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_IECR,
|
||||
1 << rman_get_start(ires));
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
at91_teardown_intr(device_t dev, device_t child, struct resource *res,
|
||||
void *cookie)
|
||||
{
|
||||
struct at91_softc *sc = device_get_softc(dev);
|
||||
|
||||
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_IDCR,
|
||||
1 << rman_get_start(res));
|
||||
return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
|
||||
}
|
||||
|
||||
static int
|
||||
at91_activate_resource(device_t bus, device_t child, int type, int rid,
|
||||
struct resource *r)
|
||||
{
|
||||
#if 0
|
||||
u_long p;
|
||||
int error;
|
||||
|
||||
if (type == SYS_RES_MEMORY) {
|
||||
error = bus_space_map(rman_get_bustag(r),
|
||||
rman_get_bushandle(r), rman_get_size(r), 0, &p);
|
||||
if (error)
|
||||
return (error);
|
||||
rman_set_bushandle(r, p);
|
||||
}
|
||||
#endif
|
||||
return (rman_activate_resource(r));
|
||||
}
|
||||
|
||||
static int
|
||||
at91_print_child(device_t dev, device_t child)
|
||||
{
|
||||
struct at91_ivar *ivars;
|
||||
struct resource_list *rl;
|
||||
int retval = 0;
|
||||
|
||||
ivars = device_get_ivars(child);
|
||||
rl = &ivars->resources;
|
||||
|
||||
retval += bus_print_child_header(dev, child);
|
||||
|
||||
retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx");
|
||||
retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx");
|
||||
retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
|
||||
if (device_get_flags(dev))
|
||||
retval += printf(" flags %#x", device_get_flags(dev));
|
||||
|
||||
retval += bus_print_child_footer(dev, child);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
void
|
||||
arm_mask_irq(uintptr_t nb)
|
||||
{
|
||||
|
||||
bus_space_write_4(at91_softc->sc_st,
|
||||
at91_softc->sc_sys_sh, IC_IDCR, 1 << nb);
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
arm_get_next_irq()
|
||||
{
|
||||
|
||||
int status;
|
||||
int irq;
|
||||
|
||||
irq = bus_space_read_4(at91_softc->sc_st,
|
||||
at91_softc->sc_sys_sh, IC_IVR);
|
||||
status = bus_space_read_4(at91_softc->sc_st,
|
||||
at91_softc->sc_sys_sh, IC_ISR);
|
||||
if (status == 0) {
|
||||
bus_space_write_4(at91_softc->sc_st,
|
||||
at91_softc->sc_sys_sh, IC_EOICR, 1);
|
||||
return (-1);
|
||||
}
|
||||
return (irq);
|
||||
}
|
||||
|
||||
void
|
||||
arm_unmask_irq(uintptr_t nb)
|
||||
{
|
||||
|
||||
bus_space_write_4(at91_softc->sc_st,
|
||||
at91_softc->sc_sys_sh, IC_IECR, 1 << nb);
|
||||
bus_space_write_4(at91_softc->sc_st, at91_softc->sc_sys_sh,
|
||||
IC_EOICR, 0);
|
||||
|
||||
}
|
||||
|
||||
static device_method_t at91_methods[] = {
|
||||
DEVMETHOD(device_probe, at91_probe),
|
||||
DEVMETHOD(device_attach, at91_attach),
|
||||
DEVMETHOD(device_identify, at91_identify),
|
||||
|
||||
DEVMETHOD(bus_alloc_resource, at91_alloc_resource),
|
||||
DEVMETHOD(bus_setup_intr, at91_setup_intr),
|
||||
DEVMETHOD(bus_teardown_intr, at91_teardown_intr),
|
||||
DEVMETHOD(bus_activate_resource, at91_activate_resource),
|
||||
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
|
||||
DEVMETHOD(bus_get_resource_list,at91_get_resource_list),
|
||||
DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
|
||||
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
|
||||
DEVMETHOD(bus_release_resource, at91_release_resource),
|
||||
DEVMETHOD(bus_print_child, at91_print_child),
|
||||
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static driver_t at91_driver = {
|
||||
"atmelarm",
|
||||
at91_methods,
|
||||
sizeof(struct at91_softc),
|
||||
};
|
||||
static devclass_t at91_devclass;
|
||||
|
||||
DRIVER_MODULE(atmelarm, nexus, at91_driver, at91_devclass, 0, 0);
|
47
sys/arm/at91/at91_pdcreg.h
Normal file
47
sys/arm/at91/at91_pdcreg.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 M. Warner Losh. 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.
|
||||
*/
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#ifndef ARM_AT91_AT91_PDCREG_H
|
||||
#define ARM_AT91_AT91_PDCREG_H
|
||||
|
||||
#define PDC_RPR 0x100 /* PDC Receive Pointer Register */
|
||||
#define PDC_RCR 0x104 /* PDC Receive Counter Register */
|
||||
#define PDC_TPR 0x108 /* PDC Transmit Pointer Register */
|
||||
#define PDC_TCR 0x10c /* PDC Transmit Counter Register */
|
||||
#define PDC_RNPR 0x110 /* PDC Receive Next Pointer Register */
|
||||
#define PDC_RNCR 0x114 /* PDC Receive Next Counter Register */
|
||||
#define PDC_TNPR 0x118 /* PDC Transmit Next Pointer Reg */
|
||||
#define PDC_TNCR 0x11c /* PDC Transmit Next Counter Reg */
|
||||
#define PDC_PTCR 0x120 /* PDC Transfer Control Register */
|
||||
#define PDC_PTSR 0x124 /* PDC Transfer Status Register */
|
||||
|
||||
/* PTCR/PTSR */
|
||||
#define PDC_PTCR_RXTEN (1UL << 0) /* RXTEN: Receiver Transfer Enable */
|
||||
#define PDC_PTCR_RXTDIS (1UL << 1) /* RXTDIS: Receiver Transfer Disable */
|
||||
#define PDC_PTCR_TXTEN (1UL << 8) /* TXTEN: Transmitter Transfer En */
|
||||
#define PDC_PTCR_TXTDIS (1UL << 9) /* TXTDIS: Transmitter Transmit Dis */
|
||||
|
||||
#endif /* ARM_AT91_AT91_PDCREG_H */
|
232
sys/arm/at91/at91_st.c
Normal file
232
sys/arm/at91/at91_st.c
Normal file
@ -0,0 +1,232 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Olivier Houchard. 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/timetc.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/resource.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/intr.h>
|
||||
#include <arm/at91/at91rm92reg.h>
|
||||
#include <arm/at91/at91var.h>
|
||||
#include <arm/at91/at91_streg.h>
|
||||
|
||||
static struct at91st_softc {
|
||||
bus_space_tag_t sc_st;
|
||||
bus_space_handle_t sc_sh;
|
||||
device_t dev;
|
||||
} *timer_softc;
|
||||
|
||||
#define RD4(off) \
|
||||
bus_space_read_4(timer_softc->sc_st, timer_softc->sc_sh, (off))
|
||||
#define WR4(off, val) \
|
||||
bus_space_write_4(timer_softc->sc_st, timer_softc->sc_sh, (off), (val))
|
||||
|
||||
static inline int
|
||||
st_crtr(void)
|
||||
{
|
||||
int cur1, cur2;
|
||||
do {
|
||||
cur1 = RD4(ST_CRTR);
|
||||
cur2 = RD4(ST_CRTR);
|
||||
} while (cur1 != cur2);
|
||||
return (cur1);
|
||||
}
|
||||
|
||||
static unsigned at91st_get_timecount(struct timecounter *tc);
|
||||
|
||||
static struct timecounter at91st_timecounter = {
|
||||
at91st_get_timecount, /* get_timecount */
|
||||
NULL, /* no poll_pps */
|
||||
#ifdef SKYEYE_WORKAROUNDS
|
||||
0xffffffffu, /* counter_mask */
|
||||
#else
|
||||
0xfffffu, /* counter_mask */
|
||||
#endif
|
||||
32768, /* frequency */
|
||||
"AT91RM9200 timer", /* name */
|
||||
0 /* quality */
|
||||
};
|
||||
|
||||
static int
|
||||
at91st_probe(device_t dev)
|
||||
{
|
||||
|
||||
device_set_desc(dev, "ST");
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
at91st_attach(device_t dev)
|
||||
{
|
||||
struct at91_softc *sc = device_get_softc(device_get_parent(dev));
|
||||
|
||||
timer_softc = device_get_softc(dev);
|
||||
timer_softc->sc_st = sc->sc_st;
|
||||
timer_softc->dev = dev;
|
||||
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_ST_BASE,
|
||||
AT91RM92_ST_SIZE, &timer_softc->sc_sh) != 0)
|
||||
panic("couldn't subregion timer registers");
|
||||
/*
|
||||
* Real time counter increments every clock cycle, need to set before
|
||||
* initializing clocks so that DELAY works.
|
||||
*/
|
||||
WR4(ST_RTMR, 1);
|
||||
/* Disable all interrupts */
|
||||
WR4(ST_IDR, 0xffffffff);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static device_method_t at91st_methods[] = {
|
||||
DEVMETHOD(device_probe, at91st_probe),
|
||||
DEVMETHOD(device_attach, at91st_attach),
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static driver_t at91st_driver = {
|
||||
"at91_st",
|
||||
at91st_methods,
|
||||
sizeof(struct at91st_softc),
|
||||
};
|
||||
static devclass_t at91st_devclass;
|
||||
|
||||
DRIVER_MODULE(at91_st, atmelarm, at91st_driver, at91st_devclass, 0, 0);
|
||||
|
||||
#ifdef SKYEYE_WORKAROUNDS
|
||||
static unsigned long tot_count = 0;
|
||||
#endif
|
||||
|
||||
static unsigned
|
||||
at91st_get_timecount(struct timecounter *tc)
|
||||
{
|
||||
#ifdef SKYEYE_WORKAROUNDS
|
||||
return (tot_count);
|
||||
#else
|
||||
return (st_crtr());
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
clock_intr(void *arg)
|
||||
{
|
||||
struct trapframe *fp = arg;
|
||||
|
||||
/* The interrupt is shared, so we have to make sure it's for us. */
|
||||
if (RD4(ST_SR) & ST_SR_PITS) {
|
||||
#ifdef SKYEYE_WORKAROUNDS
|
||||
tot_count += 32768 / hz;
|
||||
#endif
|
||||
hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cpu_initclocks(void)
|
||||
{
|
||||
int rel_value;
|
||||
struct resource *irq;
|
||||
int rid = 0;
|
||||
void *ih;
|
||||
device_t dev = timer_softc->dev;
|
||||
|
||||
if (32768 % hz) {
|
||||
printf("Cannot get %d Hz clock; using 128Hz\n", hz);
|
||||
hz = 128;
|
||||
}
|
||||
rel_value = 32768 / hz;
|
||||
/* Disable all interrupts. */
|
||||
WR4(ST_IDR, 0xffffffff);
|
||||
/* The system timer shares the system irq (1) */
|
||||
irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 1, 1, 1,
|
||||
RF_ACTIVE | RF_SHAREABLE);
|
||||
if (!irq)
|
||||
panic("Unable to allocate irq for the system timer");
|
||||
else
|
||||
bus_setup_intr(dev, irq, INTR_TYPE_CLK | INTR_FAST,
|
||||
clock_intr, NULL, &ih);
|
||||
|
||||
WR4(ST_PIMR, rel_value);
|
||||
|
||||
/* Enable PITS interrupts. */
|
||||
WR4(ST_IER, ST_SR_PITS);
|
||||
tc_init(&at91st_timecounter);
|
||||
}
|
||||
|
||||
void
|
||||
DELAY(int n)
|
||||
{
|
||||
uint32_t start, end, cur;
|
||||
|
||||
start = st_crtr();
|
||||
n = (n * 1000) / 32768;
|
||||
if (n <= 0)
|
||||
n = 1;
|
||||
end = (start + n) & ST_CRTR_MASK;
|
||||
cur = start;
|
||||
if (start > end) {
|
||||
while (cur >= start || cur < end)
|
||||
cur = st_crtr();
|
||||
} else {
|
||||
while (cur < end)
|
||||
cur = st_crtr();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cpu_reset(void)
|
||||
{
|
||||
/*
|
||||
* Reset the CPU by programmig the watchdog timer to reset the
|
||||
* CPU after 128 'slow' clocks, or about ~4ms. Loop until
|
||||
* the reset happens for safety.
|
||||
*/
|
||||
WR4(ST_WDMR, ST_WDMR_RSTEN | 2);
|
||||
WR4(ST_CR, ST_CR_WDRST);
|
||||
while (1)
|
||||
continue;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_startprofclock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
cpu_stopprofclock(void)
|
||||
{
|
||||
}
|
||||
|
109
sys/arm/at91/uart_bus_at91usart.c
Normal file
109
sys/arm/at91/uart_bus_at91usart.c
Normal file
@ -0,0 +1,109 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Olivier Houchard. 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 "opt_uart.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <machine/bus.h>
|
||||
#include <sys/rman.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
#include <dev/uart/uart.h>
|
||||
#include <dev/uart/uart_bus.h>
|
||||
#include <dev/uart/uart_cpu.h>
|
||||
|
||||
#include <arm/at91/at91rm92reg.h>
|
||||
|
||||
#include "uart_if.h"
|
||||
|
||||
static int usart_at91rm92_probe(device_t dev);
|
||||
|
||||
extern struct uart_class at91_usart_class;
|
||||
|
||||
static device_method_t usart_at91rm92_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, usart_at91rm92_probe),
|
||||
DEVMETHOD(device_attach, uart_bus_attach),
|
||||
DEVMETHOD(device_detach, uart_bus_detach),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t usart_at91rm92_driver = {
|
||||
uart_driver_name,
|
||||
usart_at91rm92_methods,
|
||||
sizeof(struct uart_softc),
|
||||
};
|
||||
|
||||
extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
|
||||
|
||||
static int
|
||||
usart_at91rm92_probe(device_t dev)
|
||||
{
|
||||
struct uart_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
switch (device_get_unit(dev))
|
||||
{
|
||||
case 0:
|
||||
#ifdef SKYEYE_WORKAROUNDS
|
||||
device_set_desc(dev, "USART0");
|
||||
#else
|
||||
device_set_desc(dev, "DBGU");
|
||||
#endif
|
||||
/*
|
||||
* Setting sc_sysdev makes this device a 'system device' and
|
||||
* indirectly makes it the system console.
|
||||
*/
|
||||
sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
|
||||
bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
|
||||
break;
|
||||
case 1:
|
||||
device_set_desc(dev, "USART0");
|
||||
break;
|
||||
case 2:
|
||||
device_set_desc(dev, "USART1");
|
||||
break;
|
||||
case 3:
|
||||
device_set_desc(dev, "USART2");
|
||||
break;
|
||||
case 4:
|
||||
device_set_desc(dev, "USART3");
|
||||
break;
|
||||
}
|
||||
sc->sc_class = &at91_usart_class;
|
||||
return (uart_bus_probe(dev, 0, 0, 0, device_get_unit(dev)));
|
||||
}
|
||||
|
||||
|
||||
DRIVER_MODULE(uart, atmelarm, usart_at91rm92_driver, uart_devclass, 0, 0);
|
83
sys/arm/at91/uart_cpu_at91rm9200usart.c
Normal file
83
sys/arm/at91/uart_cpu_at91rm9200usart.c
Normal file
@ -0,0 +1,83 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Marcel Moolenaar
|
||||
* 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 "opt_uart.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/cons.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/uart/uart.h>
|
||||
#include <dev/uart/uart_cpu.h>
|
||||
|
||||
#include <arm/at91/at91rm92reg.h>
|
||||
|
||||
bus_space_tag_t uart_bus_space_io;
|
||||
bus_space_tag_t uart_bus_space_mem;
|
||||
|
||||
extern struct uart_ops at91_usart_ops;
|
||||
extern struct bus_space at91_bs_tag;
|
||||
|
||||
int
|
||||
uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
|
||||
{
|
||||
return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
|
||||
}
|
||||
|
||||
int
|
||||
uart_cpu_getdev(int devtype, struct uart_devinfo *di)
|
||||
{
|
||||
di->ops = at91_usart_ops;
|
||||
di->bas.chan = 0;
|
||||
di->bas.bst = &at91_bs_tag;
|
||||
/*
|
||||
* XXX: Not pretty, but will work because we map VA == PA early
|
||||
* for the last 1MB of memory.
|
||||
*/
|
||||
#ifdef SKYEYE_WORKAROUNDS
|
||||
di->bas.bsh = AT91RM92_BASE + AT91RM92_USART0_BASE;
|
||||
di->baudrate = 38400;
|
||||
#else
|
||||
di->bas.bsh = AT91RM92_BASE + AT91RM92_SYS_BASE + DBGU;
|
||||
di->baudrate = 115200;
|
||||
#endif
|
||||
di->bas.regshft = 0;
|
||||
di->bas.rclk = 0;
|
||||
di->databits = 8;
|
||||
di->stopbits = 1;
|
||||
di->parity = UART_PARITY_NONE;
|
||||
uart_bus_space_io = &at91_bs_tag;
|
||||
uart_bus_space_mem = NULL;
|
||||
/* Check the environment for overrides */
|
||||
if (uart_getenv(devtype, di) == 0)
|
||||
return (0);
|
||||
return (0);
|
||||
}
|
490
sys/arm/at91/uart_dev_at91usart.c
Normal file
490
sys/arm/at91/uart_dev_at91usart.c
Normal file
@ -0,0 +1,490 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 M. Warner Losh
|
||||
* Copyright (c) 2005 Olivier Houchard
|
||||
* 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/cons.h>
|
||||
#include <sys/tty.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/uart/uart.h>
|
||||
#include <dev/uart/uart_cpu.h>
|
||||
#include <dev/uart/uart_bus.h>
|
||||
#include <arm/at91/at91rm92reg.h>
|
||||
#include <arm/at91/at91_usartreg.h>
|
||||
#include <arm/at91/at91_pdcreg.h>
|
||||
|
||||
#include "uart_if.h"
|
||||
|
||||
/*
|
||||
* High-level UART interface.
|
||||
*/
|
||||
struct at91_usart_softc {
|
||||
struct uart_softc base;
|
||||
bus_dma_tag_t dmatag; /* bus dma tag for mbufs */
|
||||
bus_dmamap_t tx_map;
|
||||
bus_dmamap_t rx_map;
|
||||
};
|
||||
|
||||
#define DEFAULT_RCLK AT91C_MASTER_CLOCK
|
||||
#define USART_BUFFER_SIZE 128
|
||||
|
||||
#define RD4(bas, reg) \
|
||||
bus_space_read_4((bas)->bst, (bas)->bsh, uart_regofs(bas, reg))
|
||||
#define WR4(bas, reg, value) \
|
||||
bus_space_write_4((bas)->bst, (bas)->bsh, uart_regofs(bas, reg), value)
|
||||
|
||||
#define SIGCHG(c, i, s, d) \
|
||||
do { \
|
||||
if (c) { \
|
||||
i |= (i & s) ? s : s | d; \
|
||||
} else { \
|
||||
i = (i & s) ? (i & ~s) | d : i; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
/*
|
||||
* Low-level UART interface.
|
||||
*/
|
||||
static int at91_usart_probe(struct uart_bas *bas);
|
||||
static void at91_usart_init(struct uart_bas *bas, int, int, int, int);
|
||||
static void at91_usart_term(struct uart_bas *bas);
|
||||
static void at91_usart_putc(struct uart_bas *bas, int);
|
||||
static int at91_usart_poll(struct uart_bas *bas);
|
||||
static int at91_usart_getc(struct uart_bas *bas, struct mtx *mtx);
|
||||
|
||||
extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
|
||||
|
||||
static int
|
||||
at91_usart_param(struct uart_bas *bas, int baudrate, int databits,
|
||||
int stopbits, int parity)
|
||||
{
|
||||
uint32_t mr;
|
||||
|
||||
/*
|
||||
* Assume 3-write RS-232 configuration.
|
||||
* XXX Not sure how uart will present the other modes to us, so
|
||||
* XXX they are unimplemented. maybe ioctl?
|
||||
*/
|
||||
mr = USART_MR_MODE_NORMAL;
|
||||
mr |= USART_MR_USCLKS_MCK; /* Assume MCK */
|
||||
|
||||
/*
|
||||
* Or in the databits requested
|
||||
*/
|
||||
if (databits < 9)
|
||||
mr &= ~USART_MR_MODE9;
|
||||
switch (databits) {
|
||||
case 5:
|
||||
mr |= USART_MR_CHRL_5BITS;
|
||||
break;
|
||||
case 6:
|
||||
mr |= USART_MR_CHRL_6BITS;
|
||||
break;
|
||||
case 7:
|
||||
mr |= USART_MR_CHRL_7BITS;
|
||||
break;
|
||||
case 8:
|
||||
mr |= USART_MR_CHRL_8BITS;
|
||||
break;
|
||||
case 9:
|
||||
mr |= USART_MR_CHRL_8BITS | USART_MR_MODE9;
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Or in the parity
|
||||
*/
|
||||
switch (parity) {
|
||||
case UART_PARITY_NONE:
|
||||
mr |= USART_MR_PAR_NONE;
|
||||
break;
|
||||
case UART_PARITY_ODD:
|
||||
mr |= USART_MR_PAR_ODD;
|
||||
break;
|
||||
case UART_PARITY_EVEN:
|
||||
mr |= USART_MR_PAR_EVEN;
|
||||
break;
|
||||
case UART_PARITY_MARK:
|
||||
mr |= USART_MR_PAR_MARK;
|
||||
break;
|
||||
case UART_PARITY_SPACE:
|
||||
mr |= USART_MR_PAR_SPACE;
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Or in the stop bits. Note: The hardware supports
|
||||
* 1.5 stop bits in async mode, but there's no way to
|
||||
* specify that AFAICT.
|
||||
*/
|
||||
if (stopbits > 1)
|
||||
mr |= USART_MR_NBSTOP_2;
|
||||
else
|
||||
mr |= USART_MR_NBSTOP_2;
|
||||
/* else if (stopbits == 1.5)
|
||||
mr |= USART_MR_NBSTOP_1_5; */
|
||||
|
||||
/*
|
||||
* We want normal plumbing mode too, none of this fancy
|
||||
* loopback or echo mode.
|
||||
*/
|
||||
mr |= USART_MR_CHMODE_NORMAL;
|
||||
|
||||
mr &= ~USART_MR_MSBF; /* lsb first */
|
||||
mr &= ~USART_MR_CKLO_SCK; /* Don't drive SCK */
|
||||
|
||||
/* XXX Need to take possible synchronous mode into account */
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct uart_ops at91_usart_ops = {
|
||||
.probe = at91_usart_probe,
|
||||
.init = at91_usart_init,
|
||||
.term = at91_usart_term,
|
||||
.putc = at91_usart_putc,
|
||||
.poll = at91_usart_poll,
|
||||
.getc = at91_usart_getc,
|
||||
};
|
||||
|
||||
static int
|
||||
at91_usart_probe(struct uart_bas *bas)
|
||||
{
|
||||
/* We know that this is always here */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize this device (I think as the console)
|
||||
*/
|
||||
static void
|
||||
at91_usart_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
|
||||
int parity)
|
||||
{
|
||||
int cr;
|
||||
|
||||
at91_usart_param(bas, baudrate, databits, stopbits, parity);
|
||||
|
||||
/* Turn on rx and tx */
|
||||
cr = USART_CR_RSTSTA | USART_CR_RSTRX | USART_CR_RSTTX;
|
||||
WR4(bas, USART_CR, cr);
|
||||
WR4(bas, USART_CR, USART_CR_RXEN | USART_CR_TXEN);
|
||||
WR4(bas, USART_IER, USART_CSR_TIMEOUT |
|
||||
USART_CSR_TXRDY | USART_CSR_RXRDY |
|
||||
USART_CSR_RXBRK | USART_CSR_ENDRX | USART_CSR_ENDTX);
|
||||
/* Set the receive timeout to be 1.5 character times. */
|
||||
WR4(bas, USART_RTOR, 12);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free resources now that we're no longer the console. This appears to
|
||||
* be never called, and I'm unsure quite what to do if I am called.
|
||||
*/
|
||||
static void
|
||||
at91_usart_term(struct uart_bas *bas)
|
||||
{
|
||||
/* XXX */
|
||||
}
|
||||
|
||||
/*
|
||||
* Put a character of console output (so we do it here polling rather than
|
||||
* interrutp driven).
|
||||
*/
|
||||
static void
|
||||
at91_usart_putc(struct uart_bas *bas, int c)
|
||||
{
|
||||
|
||||
while (!(RD4(bas, USART_CSR) &
|
||||
USART_CSR_TXRDY));
|
||||
WR4(bas, USART_THR, c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Poll for a character available
|
||||
*/
|
||||
static int
|
||||
at91_usart_poll(struct uart_bas *bas)
|
||||
{
|
||||
|
||||
if (!(RD4(bas, USART_CSR) & USART_CSR_RXRDY))
|
||||
return (-1);
|
||||
return (RD4(bas, USART_RHR) & 0xff);
|
||||
}
|
||||
|
||||
/*
|
||||
* Block waiting for a character.
|
||||
*/
|
||||
static int
|
||||
at91_usart_getc(struct uart_bas *bas, struct mtx *mtx)
|
||||
{
|
||||
int c;
|
||||
|
||||
while (!(RD4(bas, USART_CSR) & USART_CSR_RXRDY))
|
||||
;
|
||||
c = RD4(bas, USART_RHR);
|
||||
c &= 0xff;
|
||||
return (c);
|
||||
}
|
||||
|
||||
static int at91_usart_bus_probe(struct uart_softc *sc);
|
||||
static int at91_usart_bus_attach(struct uart_softc *sc);
|
||||
static int at91_usart_bus_flush(struct uart_softc *, int);
|
||||
static int at91_usart_bus_getsig(struct uart_softc *);
|
||||
static int at91_usart_bus_ioctl(struct uart_softc *, int, intptr_t);
|
||||
static int at91_usart_bus_ipend(struct uart_softc *);
|
||||
static int at91_usart_bus_param(struct uart_softc *, int, int, int, int);
|
||||
static int at91_usart_bus_receive(struct uart_softc *);
|
||||
static int at91_usart_bus_setsig(struct uart_softc *, int);
|
||||
static int at91_usart_bus_transmit(struct uart_softc *);
|
||||
|
||||
static kobj_method_t at91_usart_methods[] = {
|
||||
KOBJMETHOD(uart_probe, at91_usart_bus_probe),
|
||||
KOBJMETHOD(uart_attach, at91_usart_bus_attach),
|
||||
KOBJMETHOD(uart_flush, at91_usart_bus_flush),
|
||||
KOBJMETHOD(uart_getsig, at91_usart_bus_getsig),
|
||||
KOBJMETHOD(uart_ioctl, at91_usart_bus_ioctl),
|
||||
KOBJMETHOD(uart_ipend, at91_usart_bus_ipend),
|
||||
KOBJMETHOD(uart_param, at91_usart_bus_param),
|
||||
KOBJMETHOD(uart_receive, at91_usart_bus_receive),
|
||||
KOBJMETHOD(uart_setsig, at91_usart_bus_setsig),
|
||||
KOBJMETHOD(uart_transmit, at91_usart_bus_transmit),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
int
|
||||
at91_usart_bus_probe(struct uart_softc *sc)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
at91_usart_bus_attach(struct uart_softc *sc)
|
||||
{
|
||||
int err;
|
||||
struct at91_usart_softc *atsc;
|
||||
|
||||
atsc = (struct at91_usart_softc *)sc;
|
||||
|
||||
sc->sc_txfifosz = USART_BUFFER_SIZE;
|
||||
sc->sc_rxfifosz = USART_BUFFER_SIZE;
|
||||
sc->sc_hwiflow = 0;
|
||||
|
||||
/*
|
||||
* Allocate DMA tags and maps
|
||||
*/
|
||||
err = bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT,
|
||||
BUS_SPACE_MAXADDR, NULL, NULL, USART_BUFFER_SIZE, 1,
|
||||
USART_BUFFER_SIZE, BUS_DMA_ALLOCNOW, NULL, NULL, &atsc->dmatag);
|
||||
if (err != 0)
|
||||
goto errout;
|
||||
err = bus_dmamap_create(atsc->dmatag, 0, &atsc->tx_map);
|
||||
if (err != 0)
|
||||
goto errout;
|
||||
err = bus_dmamap_create(atsc->dmatag, 0, &atsc->rx_map);
|
||||
if (err != 0)
|
||||
goto errout;
|
||||
errout:;
|
||||
// XXX bad
|
||||
return (err);
|
||||
}
|
||||
|
||||
#ifndef SKYEYE_WORKAROUNDS
|
||||
static void
|
||||
at91_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
|
||||
{
|
||||
if (error != 0)
|
||||
return;
|
||||
*(bus_addr_t *)arg = segs[0].ds_addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int
|
||||
at91_usart_bus_transmit(struct uart_softc *sc)
|
||||
{
|
||||
#ifndef SKYEYE_WORKAROUNDS
|
||||
bus_addr_t addr;
|
||||
#endif
|
||||
struct at91_usart_softc *atsc;
|
||||
|
||||
atsc = (struct at91_usart_softc *)sc;
|
||||
#ifndef SKYEYE_WORKAROUNDS
|
||||
if (bus_dmamap_load(atsc->dmatag, atsc->tx_map, sc->sc_txbuf,
|
||||
sc->sc_txdatasz, at91_getaddr, &addr, 0) != 0)
|
||||
return (EAGAIN);
|
||||
bus_dmamap_sync(atsc->dmatag, atsc->tx_map, BUS_DMASYNC_PREWRITE);
|
||||
#endif
|
||||
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
sc->sc_txbusy = 1;
|
||||
#ifndef SKYEYE_WORKAROUNDS
|
||||
/*
|
||||
* Setup the PDC to transfer the data and interrupt us when it
|
||||
* is done. We've already requested the interrupt.
|
||||
*/
|
||||
WR4(&sc->sc_bas, PDC_TPR, addr);
|
||||
WR4(&sc->sc_bas, PDC_TCR, sc->sc_txdatasz);
|
||||
WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_TXTEN);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
#else
|
||||
for (int i = 0; i < sc->sc_txdatasz; i++)
|
||||
at91_usart_putc(&sc->sc_bas, sc->sc_txbuf[i]);
|
||||
/*
|
||||
* XXX: Gross hack : Skyeye doesn't raise an interrupt once the
|
||||
* transfer is done, so simulate it.
|
||||
*/
|
||||
WR4(&sc->sc_bas, USART_IER, USART_CSR_TXRDY);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
static int
|
||||
at91_usart_bus_setsig(struct uart_softc *sc, int sig)
|
||||
{
|
||||
uint32_t new, old, cr;
|
||||
struct uart_bas *bas;
|
||||
|
||||
do {
|
||||
old = sc->sc_hwsig;
|
||||
new = old;
|
||||
if (sig & SER_DDTR)
|
||||
SIGCHG(sig & SER_DTR, new, SER_DTR, SER_DDTR);
|
||||
if (sig & SER_DRTS)
|
||||
SIGCHG(sig & SER_RTS, new, SER_RTS, SER_DRTS);
|
||||
} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
|
||||
bas = &sc->sc_bas;
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
cr = RD4(bas, USART_CR);
|
||||
cr &= ~(USART_CR_DTREN | USART_CR_DTRDIS | USART_CR_RTSEN |
|
||||
USART_CR_RTSDIS);
|
||||
if (new & SER_DTR)
|
||||
cr |= USART_CR_DTREN;
|
||||
else
|
||||
cr |= USART_CR_DTRDIS;
|
||||
if (new & SER_RTS)
|
||||
cr |= USART_CR_RTSEN;
|
||||
else
|
||||
cr |= USART_CR_RTSDIS;
|
||||
WR4(bas, USART_CR, cr);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
static int
|
||||
at91_usart_bus_receive(struct uart_softc *sc)
|
||||
{
|
||||
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
uart_rx_put(sc, at91_usart_getc(&sc->sc_bas, NULL));
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
static int
|
||||
at91_usart_bus_param(struct uart_softc *sc, int baudrate, int databits,
|
||||
int stopbits, int parity)
|
||||
{
|
||||
return (at91_usart_param(&sc->sc_bas, baudrate, databits, stopbits,
|
||||
parity));
|
||||
}
|
||||
static int
|
||||
at91_usart_bus_ipend(struct uart_softc *sc)
|
||||
{
|
||||
int csr = RD4(&sc->sc_bas, USART_CSR);
|
||||
int ipend = 0;
|
||||
struct at91_usart_softc *atsc;
|
||||
|
||||
atsc = (struct at91_usart_softc *)sc;
|
||||
if (csr & USART_CSR_ENDTX) {
|
||||
bus_dmamap_sync(atsc->dmatag, atsc->tx_map,
|
||||
BUS_DMASYNC_POSTWRITE);
|
||||
bus_dmamap_unload(atsc->dmatag, atsc->tx_map);
|
||||
}
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
if (csr & USART_CSR_TXRDY && sc->sc_txbusy)
|
||||
ipend |= SER_INT_TXIDLE;
|
||||
if (csr & USART_CSR_ENDTX && sc->sc_txbusy)
|
||||
ipend |= SER_INT_TXIDLE;
|
||||
if (csr & (USART_CSR_RXRDY /* | USART_CSR_ENDRX | USART_CSR_TIMEOUT */))
|
||||
ipend |= SER_INT_RXREADY;
|
||||
if (csr & USART_CSR_RXBRK) {
|
||||
unsigned int cr = USART_CR_RSTSTA;
|
||||
|
||||
ipend |= SER_INT_BREAK;
|
||||
WR4(&sc->sc_bas, USART_CR, cr);
|
||||
}
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (ipend);
|
||||
}
|
||||
static int
|
||||
at91_usart_bus_flush(struct uart_softc *sc, int what)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
at91_usart_bus_getsig(struct uart_softc *sc)
|
||||
{
|
||||
uint32_t new, sig;
|
||||
uint8_t csr;
|
||||
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
csr = RD4(&sc->sc_bas, USART_CSR);
|
||||
sig = 0;
|
||||
if (csr & USART_CSR_CTS)
|
||||
sig |= SER_CTS;
|
||||
if (csr & USART_CSR_DCD)
|
||||
sig |= SER_DCD;
|
||||
if (csr & USART_CSR_DSR)
|
||||
sig |= SER_DSR;
|
||||
if (csr & USART_CSR_RI)
|
||||
sig |= SER_RI;
|
||||
new = sig & ~SER_MASK_DELTA;
|
||||
sc->sc_hwsig = new;
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (sig);
|
||||
}
|
||||
|
||||
static int
|
||||
at91_usart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
|
||||
{
|
||||
return (EINVAL);
|
||||
}
|
||||
struct uart_class at91_usart_class = {
|
||||
"at91_usart class",
|
||||
at91_usart_methods,
|
||||
sizeof(struct at91_usart_softc),
|
||||
.uc_range = 8,
|
||||
.uc_rclk = DEFAULT_RCLK
|
||||
};
|
13
sys/boot/pc98/cdboot/Makefile
Normal file
13
sys/boot/pc98/cdboot/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= cdboot
|
||||
STRIP=
|
||||
BINMODE=${NOBINMODE}
|
||||
NO_MAN=
|
||||
SRCS= ${PROG}.s
|
||||
|
||||
ORG= 0x0000
|
||||
|
||||
LDFLAGS=-N -e start -Ttext ${ORG} -Wl,-S,--oformat,binary
|
||||
|
||||
.include <bsd.prog.mk>
|
811
sys/boot/pc98/cdboot/cdboot.s
Normal file
811
sys/boot/pc98/cdboot/cdboot.s
Normal file
@ -0,0 +1,811 @@
|
||||
#
|
||||
# Copyright (c) 2006 TAKAHASHI Yoshihiro <nyan@FreeBSD.org>
|
||||
# Copyright (c) 2001 John Baldwin <jhb@FreeBSD.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.
|
||||
# 3. Neither the name of the author nor the names of any co-contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# 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$
|
||||
|
||||
#
|
||||
# Basically, we first create a set of boot arguments to pass to the loaded
|
||||
# binary. Then we attempt to load /boot/loader from the CD we were booted
|
||||
# off of.
|
||||
#
|
||||
|
||||
#
|
||||
# Memory locations.
|
||||
#
|
||||
.set STACK_OFF,0x6000 # Stack offset
|
||||
.set LOAD_SEG,0x0700 # Load segment
|
||||
.set LOAD_SIZE,2048 # Load size
|
||||
.set DAUA,0x0584 # DA/UA
|
||||
|
||||
.set MEM_PAGE_SIZE,0x1000 # memory page size, 4k
|
||||
.set MEM_ARG,0x900 # Arguments at start
|
||||
.set MEM_ARG_BTX,0xa100 # Where we move them to so the
|
||||
# BTX client can see them
|
||||
.set MEM_ARG_SIZE,0x18 # Size of the arguments
|
||||
.set MEM_BTX_ADDRESS,0x9000 # where BTX lives
|
||||
.set MEM_BTX_ENTRY,0x9010 # where BTX starts to execute
|
||||
.set MEM_BTX_OFFSET,MEM_PAGE_SIZE # offset of BTX in the loader
|
||||
.set MEM_BTX_CLIENT,0xa000 # where BTX clients live
|
||||
#
|
||||
# PC98 machine type from sys/pc98/pc98/pc98_machdep.h
|
||||
#
|
||||
.set MEM_SYS, 0xa100 # System common area segment
|
||||
.set PC98_MACHINE_TYPE, 0x0620 # PC98 machine type
|
||||
.set EPSON_ID, 0x0624 # EPSON machine id
|
||||
|
||||
.set M_NEC_PC98, 0x0001
|
||||
.set M_EPSON_PC98, 0x0002
|
||||
.set M_NOT_H98, 0x0010
|
||||
.set M_H98, 0x0020
|
||||
.set M_NOTE, 0x0040
|
||||
.set M_NORMAL, 0x1000
|
||||
.set M_8M, 0x8000
|
||||
#
|
||||
# Signature Constants
|
||||
#
|
||||
.set SIG1_OFF,0x1fe # Signature offset
|
||||
.set SIG2_OFF,0x7fe # Signature offset
|
||||
#
|
||||
# a.out header fields
|
||||
#
|
||||
.set AOUT_TEXT,0x04 # text segment size
|
||||
.set AOUT_DATA,0x08 # data segment size
|
||||
.set AOUT_BSS,0x0c # zero'd BSS size
|
||||
.set AOUT_SYMBOLS,0x10 # symbol table
|
||||
.set AOUT_ENTRY,0x14 # entry point
|
||||
.set AOUT_HEADER,MEM_PAGE_SIZE # size of the a.out header
|
||||
#
|
||||
# Flags for kargs->bootflags
|
||||
#
|
||||
.set KARGS_FLAGS_CD,0x1 # flag to indicate booting from
|
||||
# CD loader
|
||||
#
|
||||
# Segment selectors.
|
||||
#
|
||||
.set SEL_SDATA,0x8 # Supervisor data
|
||||
.set SEL_RDATA,0x10 # Real mode data
|
||||
.set SEL_SCODE,0x18 # PM-32 code
|
||||
.set SEL_SCODE16,0x20 # PM-16 code
|
||||
#
|
||||
# BTX constants
|
||||
#
|
||||
.set INT_SYS,0x30 # BTX syscall interrupt
|
||||
#
|
||||
# Constants for reading from the CD.
|
||||
#
|
||||
.set ERROR_TIMEOUT,0x90 # BIOS timeout on read
|
||||
.set NUM_RETRIES,3 # Num times to retry
|
||||
.set SECTOR_SIZE,0x800 # size of a sector
|
||||
.set SECTOR_SHIFT,11 # number of place to shift
|
||||
.set BUFFER_LEN,0x100 # number of sectors in buffer
|
||||
.set MAX_READ,0xf800 # max we can read at a time
|
||||
.set MAX_READ_SEC,MAX_READ >> SECTOR_SHIFT
|
||||
.set MEM_READ_BUFFER,0x9000 # buffer to read from CD
|
||||
.set MEM_VOLDESC,MEM_READ_BUFFER # volume descriptor
|
||||
.set MEM_DIR,MEM_VOLDESC+SECTOR_SIZE # Lookup buffer
|
||||
.set VOLDESC_LBA,0x10 # LBA of vol descriptor
|
||||
.set VD_PRIMARY,1 # Primary VD
|
||||
.set VD_END,255 # VD Terminator
|
||||
.set VD_ROOTDIR,156 # Offset of Root Dir Record
|
||||
.set DIR_LEN,0 # Offset of Dir Record length
|
||||
.set DIR_EA_LEN,1 # Offset of EA length
|
||||
.set DIR_EXTENT,2 # Offset of 64-bit LBA
|
||||
.set DIR_SIZE,10 # Offset of 64-bit length
|
||||
.set DIR_NAMELEN,32 # Offset of 8-bit name len
|
||||
.set DIR_NAME,33 # Offset of dir name
|
||||
|
||||
#
|
||||
# Program start.
|
||||
#
|
||||
.code16
|
||||
.globl start
|
||||
|
||||
start: jmp main
|
||||
|
||||
.org 4
|
||||
.ascii "IPL1 "
|
||||
|
||||
main: cld
|
||||
|
||||
/* Setup the stack */
|
||||
xor %ax,%ax
|
||||
mov %ax,%ss
|
||||
mov $STACK_OFF,%sp
|
||||
|
||||
push %ecx
|
||||
|
||||
/* Setup graphic screen */
|
||||
mov $0x42,%ah # 640x400
|
||||
mov $0xc0,%ch
|
||||
int $0x18
|
||||
mov $0x40,%ah # graph on
|
||||
int $0x18
|
||||
|
||||
/* Setup text screen */
|
||||
mov $0x0a00,%ax # 80x25
|
||||
int $0x18
|
||||
mov $0x0c,%ah # text on
|
||||
int $0x18
|
||||
mov $0x13,%ah # cursor home
|
||||
xor %dx,%dx
|
||||
int $0x18
|
||||
mov $0x11,%ah # cursor on
|
||||
int $0x18
|
||||
|
||||
/* Setup keyboard */
|
||||
mov $0x03,%ah
|
||||
int $0x18
|
||||
|
||||
/* Transfer PC-9801 system common area */
|
||||
xor %ax,%ax
|
||||
mov %ax,%si
|
||||
mov %ax,%ds
|
||||
mov %ax,%di
|
||||
mov $MEM_SYS,%ax
|
||||
mov %ax,%es
|
||||
mov $0x0600,%cx
|
||||
rep
|
||||
movsb
|
||||
|
||||
/* Transfer EPSON machine type */
|
||||
mov $0xfd00,%ax
|
||||
mov %ax,%ds
|
||||
mov (0x804),%eax
|
||||
and $0x00ffffff,%eax
|
||||
mov %eax,%es:(EPSON_ID)
|
||||
|
||||
/* Set machine type to PC98_SYSTEM_PARAMETER */
|
||||
call machine_check
|
||||
|
||||
/* Load cdboot */
|
||||
xor %ax,%ax
|
||||
mov %ax,%ds
|
||||
mov $0x06,%ah /* Read data */
|
||||
mov (DAUA),%al /* Read drive */
|
||||
pop %ecx /* cylinder */
|
||||
xor %dx,%dx /* head / sector */
|
||||
mov $LOAD_SEG,%bx /* Load address */
|
||||
mov %bx,%es
|
||||
xor %bp,%bp
|
||||
mov $LOAD_SIZE,%bx /* Load size */
|
||||
int $0x1b
|
||||
mov $msg_readerr,%si
|
||||
jc error
|
||||
|
||||
/* Jump to cdboot */
|
||||
ljmp $LOAD_SEG,$cdboot
|
||||
|
||||
#
|
||||
# Set machine type to PC98_SYSTEM_PARAMETER.
|
||||
#
|
||||
machine_check: xor %edx,%edx
|
||||
mov %dx,%ds
|
||||
mov $MEM_SYS,%ax
|
||||
mov %ax,%es
|
||||
|
||||
/* Wait V-SYNC */
|
||||
vsync.1: inb $0x60,%al
|
||||
test $0x20,%al
|
||||
jnz vsync.1
|
||||
vsync.2: inb $0x60,%al
|
||||
test $0x20,%al
|
||||
jz vsync.2
|
||||
|
||||
/* ANK 'A' font */
|
||||
xor %al,%al
|
||||
outb %al,$0xa1
|
||||
mov $0x41,%al
|
||||
outb %al,$0xa3
|
||||
|
||||
/* Get 'A' font from CG window */
|
||||
push %ds
|
||||
mov $0xa400,%ax
|
||||
mov %ax,%ds
|
||||
xor %eax,%eax
|
||||
xor %bx,%bx
|
||||
mov $4,%cx
|
||||
font.1: add (%bx),%eax
|
||||
add $4,%bx
|
||||
loop font.1
|
||||
pop %ds
|
||||
cmp $0x6efc58fc,%eax
|
||||
jnz m_epson
|
||||
|
||||
m_pc98: or $M_NEC_PC98,%edx
|
||||
mov $0x0458,%bx
|
||||
mov (%bx),%al
|
||||
test $0x80,%al
|
||||
jz m_not_h98
|
||||
or $M_H98,%edx
|
||||
jmp 1f
|
||||
m_epson: or $M_EPSON_PC98,%edx
|
||||
m_not_h98: or $M_NOT_H98,%edx
|
||||
|
||||
1: inb $0x42,%al
|
||||
test $0x20,%al
|
||||
jz 1f
|
||||
or $M_8M,%edx
|
||||
|
||||
1: mov $0x0400,%bx
|
||||
mov (%bx),%al
|
||||
test $0x80,%al
|
||||
jz 1f
|
||||
or $M_NOTE,%edx
|
||||
|
||||
1: mov $PC98_MACHINE_TYPE,%bx
|
||||
mov %edx,%es:(%bx)
|
||||
ret
|
||||
|
||||
#
|
||||
# Print out the error message at [SI], wait for a keypress, and then
|
||||
# reboot the machine.
|
||||
#
|
||||
error: call putstr
|
||||
mov $msg_keypress,%si
|
||||
call putstr
|
||||
xor %ax,%ax # Get keypress
|
||||
int $0x18
|
||||
xor %ax,%ax # CPU reset
|
||||
outb %al,$0xf0
|
||||
halt: hlt
|
||||
jmp halt # Spin
|
||||
|
||||
#
|
||||
# Display a null-terminated string at [SI].
|
||||
#
|
||||
# Trashes: AX, BX, CX, DX, SI, DI
|
||||
#
|
||||
putstr: push %ds
|
||||
push %es
|
||||
mov %cs,%ax
|
||||
mov %ax,%ds
|
||||
mov $0xa000,%ax
|
||||
mov %ax,%es
|
||||
mov cursor,%di
|
||||
mov $0x00e1,%bx # Attribute
|
||||
mov $160,%cx
|
||||
putstr.0: lodsb
|
||||
testb %al,%al
|
||||
jz putstr.done
|
||||
cmp $0x0d,%al
|
||||
jz putstr.cr
|
||||
cmp $0x0a,%al
|
||||
jz putstr.lf
|
||||
mov %bl,%es:0x2000(%di)
|
||||
stosb
|
||||
inc %di
|
||||
jmp putstr.move
|
||||
putstr.cr: xor %dx,%dx
|
||||
mov %di,%ax
|
||||
div %cx
|
||||
sub %dx,%di
|
||||
jmp putstr.move
|
||||
putstr.lf: add %cx,%di
|
||||
putstr.move: mov %di,%dx
|
||||
mov $0x13,%ah # Move cursor
|
||||
int $0x18
|
||||
jmp putstr.0
|
||||
putstr.done: mov %di,cursor
|
||||
pop %es
|
||||
pop %ds
|
||||
ret
|
||||
|
||||
#
|
||||
# Display a single char at [AL], but don't move a cursor.
|
||||
#
|
||||
putc: push %es
|
||||
push %di
|
||||
push %bx
|
||||
mov $0xa000,%bx
|
||||
mov %bx,%es
|
||||
mov cursor,%di
|
||||
mov $0xe1,%bl # Attribute
|
||||
mov %bl,%es:0x2000(%di)
|
||||
stosb
|
||||
pop %bx
|
||||
pop %di
|
||||
pop %es
|
||||
ret
|
||||
|
||||
msg_readerr: .asciz "Read Error\r\n"
|
||||
msg_keypress: .asciz "\r\nPress any key to reboot\r\n"
|
||||
|
||||
/* Boot signature */
|
||||
|
||||
.org SIG1_OFF,0x90
|
||||
|
||||
.word 0xaa55 # Magic number
|
||||
|
||||
#
|
||||
# cdboot
|
||||
#
|
||||
cdboot: mov %cs,%ax
|
||||
mov %ax,%ds
|
||||
xor %ax,%ax
|
||||
mov %ax,%es
|
||||
mov %es:(DAUA),%al # Save BIOS boot device
|
||||
mov %al,drive
|
||||
mov %cx,cylinder # Save BIOS boot cylinder
|
||||
|
||||
mov $msg_welcome,%si # %ds:(%si) -> welcome message
|
||||
call putstr # display the welcome message
|
||||
#
|
||||
# Setup the arguments that the loader is expecting from boot[12]
|
||||
#
|
||||
mov $msg_bootinfo,%si # %ds:(%si) -> boot args message
|
||||
call putstr # display the message
|
||||
mov $MEM_ARG,%bx # %ds:(%bx) -> boot args
|
||||
mov %bx,%di # %es:(%di) -> boot args
|
||||
xor %eax,%eax # zero %eax
|
||||
mov $(MEM_ARG_SIZE/4),%cx # Size of arguments in 32-bit
|
||||
# dwords
|
||||
rep # Clear the arguments
|
||||
stosl # to zero
|
||||
mov drive,%dl # Store BIOS boot device
|
||||
mov %dl,%es:0x4(%bx) # in kargs->bootdev
|
||||
or $KARGS_FLAGS_CD,%es:0x8(%bx) # kargs->bootflags |=
|
||||
# KARGS_FLAGS_CD
|
||||
#
|
||||
# Load Volume Descriptor
|
||||
#
|
||||
mov $VOLDESC_LBA,%eax # Set LBA of first VD
|
||||
load_vd: push %eax # Save %eax
|
||||
mov $1,%dh # One sector
|
||||
mov $MEM_VOLDESC,%ebx # Destination
|
||||
call read # Read it in
|
||||
cmpb $VD_PRIMARY,%es:(%bx) # Primary VD?
|
||||
je have_vd # Yes
|
||||
pop %eax # Prepare to
|
||||
inc %eax # try next
|
||||
cmpb $VD_END,%es:(%bx) # Last VD?
|
||||
jne load_vd # No, read next
|
||||
mov $msg_novd,%si # No VD
|
||||
jmp error # Halt
|
||||
have_vd: # Have Primary VD
|
||||
#
|
||||
# Try to look up the loader binary using the paths in the loader_paths
|
||||
# array.
|
||||
#
|
||||
mov $loader_paths,%si # Point to start of array
|
||||
lookup_path: push %si # Save file name pointer
|
||||
call lookup # Try to find file
|
||||
pop %di # Restore file name pointer
|
||||
jnc lookup_found # Found this file
|
||||
push %es
|
||||
mov %cs,%ax
|
||||
mov %ax,%es
|
||||
xor %al,%al # Look for next
|
||||
mov $0xffff,%cx # path name by
|
||||
repnz # scanning for
|
||||
scasb # nul char
|
||||
pop %es
|
||||
mov %di,%si # Point %si at next path
|
||||
mov (%si),%al # Get first char of next path
|
||||
or %al,%al # Is it double nul?
|
||||
jnz lookup_path # No, try it.
|
||||
mov $msg_failed,%si # Failed message
|
||||
jmp error # Halt
|
||||
lookup_found: # Found a loader file
|
||||
#
|
||||
# Load the binary into the buffer. Due to real mode addressing limitations
|
||||
# we have to read it in in 64k chunks.
|
||||
#
|
||||
mov %es:DIR_SIZE(%bx),%eax # Read file length
|
||||
add $SECTOR_SIZE-1,%eax # Convert length to sectors
|
||||
shr $SECTOR_SHIFT,%eax
|
||||
cmp $BUFFER_LEN,%eax
|
||||
jbe load_sizeok
|
||||
mov $msg_load2big,%si # Error message
|
||||
jmp error
|
||||
load_sizeok: movzbw %al,%cx # Num sectors to read
|
||||
mov %es:DIR_EXTENT(%bx),%eax # Load extent
|
||||
xor %edx,%edx
|
||||
mov %es:DIR_EA_LEN(%bx),%dl
|
||||
add %edx,%eax # Skip extended
|
||||
mov $MEM_READ_BUFFER,%ebx # Read into the buffer
|
||||
load_loop: mov %cl,%dh
|
||||
cmp $MAX_READ_SEC,%cl # Truncate to max read size
|
||||
jbe load_notrunc
|
||||
mov $MAX_READ_SEC,%dh
|
||||
load_notrunc: sub %dh,%cl # Update count
|
||||
push %eax # Save
|
||||
call read # Read it in
|
||||
pop %eax # Restore
|
||||
add $MAX_READ_SEC,%eax # Update LBA
|
||||
add $MAX_READ,%ebx # Update dest addr
|
||||
jcxz load_done # Done?
|
||||
jmp load_loop # Keep going
|
||||
load_done:
|
||||
#
|
||||
# Turn on the A20 address line
|
||||
#
|
||||
xor %ax,%ax # Turn A20 on
|
||||
outb %al,$0xf2
|
||||
mov $0x02,%al
|
||||
outb %al,$0xf6
|
||||
#
|
||||
# Relocate the loader and BTX using a very lazy protected mode
|
||||
#
|
||||
mov $msg_relocate,%si # Display the
|
||||
call putstr # relocation message
|
||||
mov %es:(MEM_READ_BUFFER+AOUT_ENTRY),%edi # %edi is the destination
|
||||
mov $(MEM_READ_BUFFER+AOUT_HEADER),%esi # %esi is
|
||||
# the start of the text
|
||||
# segment
|
||||
mov %es:(MEM_READ_BUFFER+AOUT_TEXT),%ecx # %ecx = length of the text
|
||||
# segment
|
||||
push %edi # Save entry point for later
|
||||
lgdt gdtdesc # setup our own gdt
|
||||
cli # turn off interrupts
|
||||
mov %cr0,%eax # Turn on
|
||||
or $0x1,%al # protected
|
||||
mov %eax,%cr0 # mode
|
||||
ljmp $SEL_SCODE,$pm_start # long jump to clear the
|
||||
# instruction pre-fetch queue
|
||||
.code32
|
||||
pm_start: mov $SEL_SDATA,%ax # Initialize
|
||||
mov %ax,%ds # %ds and
|
||||
mov %ax,%es # %es to a flat selector
|
||||
rep # Relocate the
|
||||
movsb # text segment
|
||||
add $(MEM_PAGE_SIZE - 1),%edi # pad %edi out to a new page
|
||||
and $~(MEM_PAGE_SIZE - 1),%edi # for the data segment
|
||||
mov MEM_READ_BUFFER+AOUT_DATA,%ecx # size of the data segment
|
||||
rep # Relocate the
|
||||
movsb # data segment
|
||||
mov MEM_READ_BUFFER+AOUT_BSS,%ecx # size of the bss
|
||||
xor %eax,%eax # zero %eax
|
||||
add $3,%cl # round %ecx up to
|
||||
shr $2,%ecx # a multiple of 4
|
||||
rep # zero the
|
||||
stosl # bss
|
||||
mov MEM_READ_BUFFER+AOUT_ENTRY,%esi # %esi -> relocated loader
|
||||
add $MEM_BTX_OFFSET,%esi # %esi -> BTX in the loader
|
||||
mov $MEM_BTX_ADDRESS,%edi # %edi -> where BTX needs to go
|
||||
movzwl 0xa(%esi),%ecx # %ecx -> length of BTX
|
||||
rep # Relocate
|
||||
movsb # BTX
|
||||
ljmp $SEL_SCODE16,$pm_16 # Jump to 16-bit PM
|
||||
.code16
|
||||
pm_16: mov $SEL_RDATA,%ax # Initialize
|
||||
mov %ax,%ds # %ds and
|
||||
mov %ax,%es # %es to a real mode selector
|
||||
mov %cr0,%eax # Turn off
|
||||
and $~0x1,%al # protected
|
||||
mov %eax,%cr0 # mode
|
||||
ljmp $LOAD_SEG,$pm_end # Long jump to clear the
|
||||
# instruction pre-fetch queue
|
||||
pm_end: sti # Turn interrupts back on now
|
||||
#
|
||||
# Copy the BTX client to MEM_BTX_CLIENT
|
||||
#
|
||||
mov %cs,%ax
|
||||
mov %ax,%ds
|
||||
xor %ax,%ax
|
||||
mov %ax,%es
|
||||
mov $MEM_BTX_CLIENT,%di # Prepare to relocate
|
||||
mov $btx_client,%si # the simple btx client
|
||||
mov $(btx_client_end-btx_client),%cx # length of btx client
|
||||
rep # Relocate the
|
||||
movsb # simple BTX client
|
||||
#
|
||||
# Copy the boot[12] args to where the BTX client can see them
|
||||
#
|
||||
xor %ax,%ax
|
||||
mov %ax,%ds
|
||||
mov $MEM_ARG,%si # where the args are at now
|
||||
mov $MEM_ARG_BTX,%di # where the args are moving to
|
||||
mov $(MEM_ARG_SIZE/4),%cx # size of the arguments in longs
|
||||
rep # Relocate
|
||||
movsl # the words
|
||||
#
|
||||
# Save the entry point so the client can get to it later on
|
||||
#
|
||||
pop %eax # Restore saved entry point
|
||||
stosl # and add it to the end of
|
||||
# the arguments
|
||||
#
|
||||
# Now we just start up BTX and let it do the rest
|
||||
#
|
||||
mov $msg_jump,%si # Display the
|
||||
call putstr # jump message
|
||||
ljmp $0,$MEM_BTX_ENTRY # Jump to the BTX entry point
|
||||
|
||||
#
|
||||
# Lookup the file in the path at [SI] from the root directory.
|
||||
#
|
||||
# Trashes: All but BX
|
||||
# Returns: CF = 0 (success), BX = pointer to record
|
||||
# CF = 1 (not found)
|
||||
#
|
||||
lookup: mov $VD_ROOTDIR+MEM_VOLDESC,%bx # Root directory record
|
||||
push %bx
|
||||
push %si
|
||||
mov $msg_lookup,%si # Display lookup message
|
||||
call putstr
|
||||
pop %si
|
||||
push %si
|
||||
call putstr
|
||||
mov $msg_lookup2,%si
|
||||
call putstr
|
||||
pop %si
|
||||
pop %bx
|
||||
lookup_dir: lodsb # Get first char of path
|
||||
cmp $0,%al # Are we done?
|
||||
je lookup_done # Yes
|
||||
cmp $'/',%al # Skip path separator.
|
||||
je lookup_dir
|
||||
dec %si # Undo lodsb side effect
|
||||
call find_file # Lookup first path item
|
||||
jnc lookup_dir # Try next component
|
||||
mov $msg_lookupfail,%si # Not found message
|
||||
push %bx
|
||||
call putstr
|
||||
pop %bx
|
||||
stc # Set carry
|
||||
ret
|
||||
lookup_done: mov $msg_lookupok,%si # Success message
|
||||
push %bx
|
||||
call putstr
|
||||
pop %bx
|
||||
clc # Clear carry
|
||||
ret
|
||||
|
||||
#
|
||||
# Lookup file at [SI] in directory whose record is at [BX].
|
||||
#
|
||||
# Trashes: All but returns
|
||||
# Returns: CF = 0 (success), BX = pointer to record, SI = next path item
|
||||
# CF = 1 (not found), SI = preserved
|
||||
#
|
||||
find_file: mov %es:DIR_EXTENT(%bx),%eax # Load extent
|
||||
xor %edx,%edx
|
||||
mov %es:DIR_EA_LEN(%bx),%dl
|
||||
add %edx,%eax # Skip extended attributes
|
||||
mov %eax,rec_lba # Save LBA
|
||||
mov %es:DIR_SIZE(%bx),%eax # Save size
|
||||
mov %eax,rec_size
|
||||
xor %cl,%cl # Zero length
|
||||
push %si # Save
|
||||
ff.namelen: inc %cl # Update length
|
||||
lodsb # Read char
|
||||
cmp $0,%al # Nul?
|
||||
je ff.namedone # Yes
|
||||
cmp $'/',%al # Path separator?
|
||||
jnz ff.namelen # No, keep going
|
||||
ff.namedone: dec %cl # Adjust length and save
|
||||
mov %cl,name_len
|
||||
pop %si # Restore
|
||||
ff.load: mov rec_lba,%eax # Load LBA
|
||||
mov $MEM_DIR,%ebx # Address buffer
|
||||
mov $1,%dh # One sector
|
||||
call read # Read directory block
|
||||
incl rec_lba # Update LBA to next block
|
||||
ff.scan: mov %ebx,%edx # Check for EOF
|
||||
sub $MEM_DIR,%edx
|
||||
cmp %edx,rec_size
|
||||
ja ff.scan.1
|
||||
stc # EOF reached
|
||||
ret
|
||||
ff.scan.1: cmpb $0,%es:DIR_LEN(%bx) # Last record in block?
|
||||
je ff.nextblock
|
||||
push %si # Save
|
||||
movzbw %es:DIR_NAMELEN(%bx),%si # Find end of string
|
||||
ff.checkver: cmpb $'0',%es:DIR_NAME-1(%bx,%si) # Less than '0'?
|
||||
jb ff.checkver.1
|
||||
cmpb $'9',%es:DIR_NAME-1(%bx,%si) # Greater than '9'?
|
||||
ja ff.checkver.1
|
||||
dec %si # Next char
|
||||
jnz ff.checkver
|
||||
jmp ff.checklen # All numbers in name, so
|
||||
# no version
|
||||
ff.checkver.1: movzbw %es:DIR_NAMELEN(%bx),%cx
|
||||
cmp %cx,%si # Did we find any digits?
|
||||
je ff.checkdot # No
|
||||
cmpb $';',%es:DIR_NAME-1(%bx,%si) # Check for semicolon
|
||||
jne ff.checkver.2
|
||||
dec %si # Skip semicolon
|
||||
mov %si,%cx
|
||||
mov %cl,%es:DIR_NAMELEN(%bx) # Adjust length
|
||||
jmp ff.checkdot
|
||||
ff.checkver.2: mov %cx,%si # Restore %si to end of string
|
||||
ff.checkdot: cmpb $'.',%es:DIR_NAME-1(%bx,%si) # Trailing dot?
|
||||
jne ff.checklen # No
|
||||
decb %es:DIR_NAMELEN(%bx) # Adjust length
|
||||
ff.checklen: pop %si # Restore
|
||||
movzbw name_len,%cx # Load length of name
|
||||
cmp %cl,%es:DIR_NAMELEN(%bx) # Does length match?
|
||||
je ff.checkname # Yes, check name
|
||||
ff.nextrec: add %es:DIR_LEN(%bx),%bl # Next record
|
||||
adc $0,%bh
|
||||
jmp ff.scan
|
||||
ff.nextblock: subl $SECTOR_SIZE,rec_size # Adjust size
|
||||
jnc ff.load # If subtract ok, keep going
|
||||
ret # End of file, so not found
|
||||
ff.checkname: lea DIR_NAME(%bx),%di # Address name in record
|
||||
push %si # Save
|
||||
repe cmpsb # Compare name
|
||||
je ff.match # We have a winner!
|
||||
pop %si # Restore
|
||||
jmp ff.nextrec # Keep looking.
|
||||
ff.match: add $2,%sp # Discard saved %si
|
||||
clc # Clear carry
|
||||
ret
|
||||
|
||||
#
|
||||
# Load DH sectors starting at LBA EAX into [EBX].
|
||||
#
|
||||
# Trashes: EAX
|
||||
#
|
||||
read: push %es # Save
|
||||
push %bp
|
||||
push %dx
|
||||
push %cx
|
||||
push %ebx
|
||||
mov %bx,%bp # Set destination address
|
||||
and $0x000f,%bp
|
||||
shr $4,%ebx
|
||||
mov %bx,%es
|
||||
xor %bx,%bx # Set read bytes
|
||||
mov %dh,%bl
|
||||
shl $SECTOR_SHIFT,%bx # 2048 bytes/sec
|
||||
mov %ax,%cx # Set LBA
|
||||
shr $16,%eax
|
||||
mov %ax,%dx
|
||||
read.retry: mov $0x06,%ah # BIOS device read
|
||||
mov drive,%al
|
||||
and $0x7f,%al
|
||||
call twiddle # Entertain the user
|
||||
int $0x1b # Call BIOS
|
||||
jc read.fail # Worked?
|
||||
pop %ebx # Restore
|
||||
pop %cx
|
||||
pop %dx
|
||||
pop %bp
|
||||
pop %es
|
||||
ret # Return
|
||||
read.fail: cmp $ERROR_TIMEOUT,%ah # Timeout?
|
||||
je read.retry # Yes, Retry.
|
||||
read.error: mov %ah,%al # Save error
|
||||
mov $hex_error,%di # Format it
|
||||
call hex8 # as hex
|
||||
mov $msg_badread,%si # Display Read error message
|
||||
jmp error
|
||||
|
||||
#
|
||||
# Output the "twiddle"
|
||||
#
|
||||
twiddle: push %ax # Save
|
||||
push %bx # Save
|
||||
mov twiddle_index,%al # Load index
|
||||
mov twiddle_chars,%bx # Address table
|
||||
inc %al # Next
|
||||
and $3,%al # char
|
||||
mov %al,twiddle_index # Save index for next call
|
||||
xlat # Get char
|
||||
call putc # Output it
|
||||
pop %bx # Restore
|
||||
pop %ax # Restore
|
||||
ret
|
||||
|
||||
#
|
||||
# Convert AL to hex, saving the result to [EDI].
|
||||
#
|
||||
hex8: pushl %eax # Save
|
||||
shrb $0x4,%al # Do upper
|
||||
call hex8.1 # 4
|
||||
popl %eax # Restore
|
||||
hex8.1: andb $0xf,%al # Get lower 4
|
||||
cmpb $0xa,%al # Convert
|
||||
sbbb $0x69,%al # to hex
|
||||
das # digit
|
||||
orb $0x20,%al # To lower case
|
||||
mov %al,(%di) # Save char
|
||||
inc %di
|
||||
ret # (Recursive)
|
||||
|
||||
#
|
||||
# BTX client to start btxldr
|
||||
#
|
||||
.code32
|
||||
btx_client: mov $(MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE-4), %esi
|
||||
# %ds:(%esi) -> end
|
||||
# of boot[12] args
|
||||
mov $(MEM_ARG_SIZE/4),%ecx # Number of words to push
|
||||
std # Go backwards
|
||||
push_arg: lodsl # Read argument
|
||||
push %eax # Push it onto the stack
|
||||
loop push_arg # Push all of the arguments
|
||||
cld # In case anyone depends on this
|
||||
pushl MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE # Entry point of
|
||||
# the loader
|
||||
push %eax # Emulate a near call
|
||||
mov $0x1,%eax # 'exec' system call
|
||||
int $INT_SYS # BTX system call
|
||||
btx_client_end:
|
||||
.code16
|
||||
|
||||
.p2align 4
|
||||
#
|
||||
# Global descriptor table.
|
||||
#
|
||||
gdt: .word 0x0,0x0,0x0,0x0 # Null entry
|
||||
.word 0xffff,0x0000,0x9200,0x00cf # SEL_SDATA
|
||||
.word 0xffff,0x0000,0x9200,0x0000 # SEL_RDATA
|
||||
.word 0xffff,LOAD_SEG<<4,0x9a00,0x00cf # SEL_SCODE (32-bit)
|
||||
.word 0xffff,LOAD_SEG<<4,0x9a00,0x008f # SEL_SCODE16 (16-bit)
|
||||
gdt.1:
|
||||
#
|
||||
# Pseudo-descriptors.
|
||||
#
|
||||
gdtdesc: .word gdt.1-gdt-1 # Limit
|
||||
.long LOAD_SEG<<4 + gdt # Base
|
||||
|
||||
#
|
||||
# BOOT device
|
||||
#
|
||||
drive: .byte 0
|
||||
cylinder: .word 0
|
||||
|
||||
#
|
||||
# State for searching dir
|
||||
#
|
||||
rec_lba: .long 0x0 # LBA (adjusted for EA)
|
||||
rec_size: .long 0x0 # File size
|
||||
name_len: .byte 0x0 # Length of current name
|
||||
|
||||
cursor: .word 0
|
||||
twiddle_index: .byte 0x0
|
||||
|
||||
msg_welcome: .asciz "CD Loader 1.2\r\n\n"
|
||||
msg_bootinfo: .asciz "Building the boot loader arguments\r\n"
|
||||
msg_relocate: .asciz "Relocating the loader and the BTX\r\n"
|
||||
msg_jump: .asciz "Starting the BTX loader\r\n"
|
||||
msg_badread: .ascii "Read Error: 0x"
|
||||
hex_error: .ascii "00\r\n"
|
||||
msg_novd: .asciz "Could not find Primary Volume Descriptor\r\n"
|
||||
msg_lookup: .asciz "Looking up "
|
||||
msg_lookup2: .asciz "... "
|
||||
msg_lookupok: .asciz "Found\r\n"
|
||||
msg_lookupfail: .asciz "File not found\r\n"
|
||||
msg_load2big: .asciz "File too big\r\n"
|
||||
msg_failed: .asciz "Boot failed\r\n"
|
||||
twiddle_chars: .ascii "|/-\\"
|
||||
loader_paths: .asciz "/BOOT.PC98/LOADER"
|
||||
.asciz "/boot.pc98/loader"
|
||||
.asciz "/BOOT/LOADER"
|
||||
.asciz "/boot/loader"
|
||||
.byte 0
|
||||
|
||||
/* Boot signature */
|
||||
|
||||
.org SIG2_OFF,0x90
|
||||
|
||||
.word 0xaa55 # Magic number
|
344
sys/boot/pc98/libpc98/bioscd.c
Normal file
344
sys/boot/pc98/libpc98/bioscd.c
Normal file
@ -0,0 +1,344 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
|
||||
* Copyright (c) 2001 John H. Baldwin <jhb@FreeBSD.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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* BIOS CD device handling for CD's that have been booted off of via no
|
||||
* emulation booting as defined in the El Torito standard.
|
||||
*
|
||||
* Ideas and algorithms from:
|
||||
*
|
||||
* - FreeBSD libi386/biosdisk.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stand.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <machine/bootinfo.h>
|
||||
#include <machine/psl.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <bootstrap.h>
|
||||
#include <btxv86.h>
|
||||
#include "libi386.h"
|
||||
|
||||
#define BIOSCD_SECSIZE 2048
|
||||
#define BUFSIZE (1 * BIOSCD_SECSIZE)
|
||||
#define MAXBCDEV 1
|
||||
|
||||
/* Major numbers for devices we frontend for. */
|
||||
#define ACDMAJOR 117
|
||||
#define CDMAJOR 15
|
||||
|
||||
#ifdef DISK_DEBUG
|
||||
# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __func__ , ## args)
|
||||
#else
|
||||
# define DEBUG(fmt, args...)
|
||||
#endif
|
||||
|
||||
struct specification_packet {
|
||||
u_char sp_size;
|
||||
u_char sp_bootmedia;
|
||||
u_char sp_drive;
|
||||
u_char sp_controller;
|
||||
u_int sp_lba;
|
||||
u_short sp_devicespec;
|
||||
u_short sp_buffersegment;
|
||||
u_short sp_loadsegment;
|
||||
u_short sp_sectorcount;
|
||||
u_short sp_cylsec;
|
||||
u_char sp_head;
|
||||
};
|
||||
|
||||
/*
|
||||
* List of BIOS devices, translation from disk unit number to
|
||||
* BIOS unit number.
|
||||
*/
|
||||
static struct bcinfo {
|
||||
int bc_unit; /* BIOS unit number */
|
||||
struct specification_packet bc_sp;
|
||||
} bcinfo [MAXBCDEV];
|
||||
static int nbcinfo = 0;
|
||||
|
||||
static int bc_read(int unit, daddr_t dblk, int blks, caddr_t dest);
|
||||
static int bc_init(void);
|
||||
static int bc_strategy(void *devdata, int flag, daddr_t dblk,
|
||||
size_t size, char *buf, size_t *rsize);
|
||||
static int bc_open(struct open_file *f, ...);
|
||||
static int bc_close(struct open_file *f);
|
||||
static void bc_print(int verbose);
|
||||
|
||||
struct devsw bioscd = {
|
||||
"cd",
|
||||
DEVT_CD,
|
||||
bc_init,
|
||||
bc_strategy,
|
||||
bc_open,
|
||||
bc_close,
|
||||
noioctl,
|
||||
bc_print,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Translate between BIOS device numbers and our private unit numbers.
|
||||
*/
|
||||
int
|
||||
bc_bios2unit(int biosdev)
|
||||
{
|
||||
int i;
|
||||
|
||||
DEBUG("looking for bios device 0x%x", biosdev);
|
||||
for (i = 0; i < nbcinfo; i++) {
|
||||
DEBUG("bc unit %d is BIOS device 0x%x", i, bcinfo[i].bc_unit);
|
||||
if (bcinfo[i].bc_unit == biosdev)
|
||||
return(i);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
int
|
||||
bc_unit2bios(int unit)
|
||||
{
|
||||
if ((unit >= 0) && (unit < nbcinfo))
|
||||
return(bcinfo[unit].bc_unit);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't quiz, we have to be told what device to use, so this functoin
|
||||
* doesn't do anything. Instead, the loader calls bc_add() with the BIOS
|
||||
* device number to add.
|
||||
*/
|
||||
static int
|
||||
bc_init(void)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
bc_add(int biosdev)
|
||||
{
|
||||
|
||||
if (nbcinfo >= MAXBCDEV)
|
||||
return (-1);
|
||||
bcinfo[nbcinfo].bc_unit = biosdev;
|
||||
|
||||
/* SCSI CD-ROM only */
|
||||
if ((biosdev & 0xf0) != 0xa0)
|
||||
return (-1);
|
||||
if ((((uint32_t *)PTOV(0xA1460))[biosdev & 0x0f] & 0x1f) != 5)
|
||||
return (-1);
|
||||
|
||||
printf("BIOS CD is cd%d\n", nbcinfo);
|
||||
nbcinfo++;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print information about disks
|
||||
*/
|
||||
static void
|
||||
bc_print(int verbose)
|
||||
{
|
||||
int i;
|
||||
char line[80];
|
||||
|
||||
for (i = 0; i < nbcinfo; i++) {
|
||||
sprintf(line, " cd%d: Device 0x%x\n", i,
|
||||
bcinfo[i].bc_sp.sp_devicespec);
|
||||
pager_output(line);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to open the disk described by (dev) for use by (f).
|
||||
*/
|
||||
static int
|
||||
bc_open(struct open_file *f, ...)
|
||||
{
|
||||
va_list ap;
|
||||
struct i386_devdesc *dev;
|
||||
|
||||
va_start(ap, f);
|
||||
dev = va_arg(ap, struct i386_devdesc *);
|
||||
va_end(ap);
|
||||
if (dev->d_kind.bioscd.unit >= nbcinfo) {
|
||||
DEBUG("attempt to open nonexistent disk");
|
||||
return(ENXIO);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
bc_close(struct open_file *f)
|
||||
{
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
bc_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf,
|
||||
size_t *rsize)
|
||||
{
|
||||
struct i386_devdesc *dev;
|
||||
int unit;
|
||||
int blks;
|
||||
#ifdef BD_SUPPORT_FRAGS
|
||||
char fragbuf[BIOSCD_SECSIZE];
|
||||
size_t fragsize;
|
||||
|
||||
fragsize = size % BIOSCD_SECSIZE;
|
||||
#else
|
||||
if (size % BIOSCD_SECSIZE)
|
||||
return (EINVAL);
|
||||
#endif
|
||||
|
||||
if (rw != F_READ)
|
||||
return(EROFS);
|
||||
dev = (struct i386_devdesc *)devdata;
|
||||
unit = dev->d_kind.bioscd.unit;
|
||||
blks = size / BIOSCD_SECSIZE;
|
||||
if (dblk % (BIOSCD_SECSIZE / DEV_BSIZE) != 0)
|
||||
return (EINVAL);
|
||||
dblk /= (BIOSCD_SECSIZE / DEV_BSIZE);
|
||||
DEBUG("read %d from %d to %p", blks, dblk, buf);
|
||||
|
||||
if (rsize)
|
||||
*rsize = 0;
|
||||
if (blks && bc_read(unit, dblk, blks, buf)) {
|
||||
DEBUG("read error");
|
||||
return (EIO);
|
||||
}
|
||||
#ifdef BD_SUPPORT_FRAGS
|
||||
DEBUG("bc_strategy: frag read %d from %d+%d to %p",
|
||||
fragsize, dblk, blks, buf + (blks * BIOSCD_SECSIZE));
|
||||
if (fragsize && bc_read(unit, dblk + blks, 1, fragsize)) {
|
||||
DEBUG("frag read error");
|
||||
return(EIO);
|
||||
}
|
||||
bcopy(fragbuf, buf + (blks * BIOSCD_SECSIZE), fragsize);
|
||||
#endif
|
||||
if (rsize)
|
||||
*rsize = size;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
bc_read(int unit, daddr_t dblk, int blks, caddr_t dest)
|
||||
{
|
||||
u_int result, retry;
|
||||
static unsigned short packet[8];
|
||||
int biosdev;
|
||||
#ifdef DISK_DEBUG
|
||||
int error;
|
||||
#endif
|
||||
|
||||
/* Just in case some idiot actually tries to read -1 blocks... */
|
||||
if (blks < 0)
|
||||
return (-1);
|
||||
|
||||
/* If nothing to do, just return succcess. */
|
||||
if (blks == 0)
|
||||
return (0);
|
||||
|
||||
biosdev = bc_unit2bios(unit);
|
||||
/*
|
||||
* Loop retrying the operation a couple of times. The BIOS
|
||||
* may also retry.
|
||||
*/
|
||||
for (retry = 0; retry < 3; retry++) {
|
||||
/* If retrying, reset the drive */
|
||||
if (retry > 0) {
|
||||
v86.ctl = V86_FLAGS;
|
||||
v86.addr = 0x1b;
|
||||
v86.eax = 0x0300 | biosdev;
|
||||
v86int();
|
||||
}
|
||||
|
||||
v86.ctl = V86_FLAGS;
|
||||
v86.addr = 0x1b;
|
||||
v86.eax = 0x0600 | (biosdev & 0x7f);
|
||||
v86.ebx = blks * BIOSCD_SECSIZE;
|
||||
v86.ecx = dblk & 0xffff;
|
||||
v86.edx = (dblk >> 16) & 0xffff;
|
||||
v86.ebp = VTOPOFF(dest);
|
||||
v86.es = VTOPSEG(dest);
|
||||
v86int();
|
||||
result = (v86.efl & PSL_C);
|
||||
if (result == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DISK_DEBUG
|
||||
error = (v86.eax >> 8) & 0xff;
|
||||
#endif
|
||||
DEBUG("%d sectors from %ld to %p (0x%x) %s", blks, dblk, dest,
|
||||
VTOP(dest), result ? "failed" : "ok");
|
||||
DEBUG("unit %d status 0x%x", unit, error);
|
||||
|
||||
/* hexdump(dest, (blks * BIOSCD_SECSIZE)); */
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a suitable dev_t value for (dev).
|
||||
*/
|
||||
int
|
||||
bc_getdev(struct i386_devdesc *dev)
|
||||
{
|
||||
int biosdev, unit, device;
|
||||
int major;
|
||||
int rootdev;
|
||||
|
||||
unit = dev->d_kind.bioscd.unit;
|
||||
biosdev = bc_unit2bios(unit);
|
||||
DEBUG("unit %d BIOS device %d", unit, biosdev);
|
||||
if (biosdev == -1) /* not a BIOS device */
|
||||
return(-1);
|
||||
|
||||
device = biosdev & 0xf0;
|
||||
if (device == 0x80)
|
||||
major = ACDMAJOR;
|
||||
else if (device == 0xa0)
|
||||
major = CDMAJOR;
|
||||
else
|
||||
return (-1);
|
||||
|
||||
unit = 0; /* XXX */
|
||||
|
||||
/* XXX: Assume partition 'a'. */
|
||||
rootdev = MAKEBOOTDEV(major, 0, 0, unit, 0);
|
||||
DEBUG("dev is 0x%x\n", rootdev);
|
||||
return(rootdev);
|
||||
}
|
283
sys/compat/linsysfs/linsysfs.c
Normal file
283
sys/compat/linsysfs/linsysfs.c
Normal file
@ -0,0 +1,283 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 IronPort Systems
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/blist.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/exec.h>
|
||||
#include <sys/filedesc.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/linker.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/sbuf.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/pciio.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_map.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <vm/vm_object.h>
|
||||
#include <vm/swap_pager.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include "opt_compat.h"
|
||||
#ifdef COMPAT_LINUX32 /* XXX */
|
||||
#include <machine/../linux32/linux.h>
|
||||
#else
|
||||
#include <machine/../linux/linux.h>
|
||||
#endif
|
||||
#include <compat/linux/linux_ioctl.h>
|
||||
#include <compat/linux/linux_mib.h>
|
||||
#include <compat/linux/linux_util.h>
|
||||
#include <fs/pseudofs/pseudofs.h>
|
||||
|
||||
struct scsi_host_queue {
|
||||
TAILQ_ENTRY(scsi_host_queue) scsi_host_next;
|
||||
char *path;
|
||||
char *name;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(,scsi_host_queue) scsi_host_q;
|
||||
|
||||
static int host_number = 0;
|
||||
|
||||
static int
|
||||
atoi(const char *str)
|
||||
{
|
||||
return (int)strtol(str, (char **)NULL, 10);
|
||||
}
|
||||
|
||||
/*
|
||||
* Filler function for proc_name
|
||||
*/
|
||||
static int
|
||||
linsysfs_scsiname(PFS_FILL_ARGS)
|
||||
{
|
||||
struct scsi_host_queue *scsi_host;
|
||||
int index;
|
||||
|
||||
if (strncmp(pn->pn_parent->pn_name, "host", 4) == 0) {
|
||||
index = atoi(&pn->pn_parent->pn_name[4]);
|
||||
} else {
|
||||
sbuf_printf(sb, "unknown\n");
|
||||
return (0);
|
||||
}
|
||||
TAILQ_FOREACH(scsi_host, &scsi_host_q, scsi_host_next) {
|
||||
if (index-- == 0) {
|
||||
sbuf_printf(sb, "%s\n", scsi_host->name);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
sbuf_printf(sb, "unknown\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Filler function for device sym-link
|
||||
*/
|
||||
static int
|
||||
linsysfs_link_scsi_host(PFS_FILL_ARGS)
|
||||
{
|
||||
struct scsi_host_queue *scsi_host;
|
||||
int index;
|
||||
|
||||
if (strncmp(pn->pn_parent->pn_name, "host", 4) == 0) {
|
||||
index = atoi(&pn->pn_parent->pn_name[4]);
|
||||
} else {
|
||||
sbuf_printf(sb, "unknown\n");
|
||||
return (0);
|
||||
}
|
||||
TAILQ_FOREACH(scsi_host, &scsi_host_q, scsi_host_next) {
|
||||
if (index-- == 0) {
|
||||
sbuf_printf(sb, "../../../devices%s", scsi_host->path);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
sbuf_printf(sb, "unknown\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
#define PCI_DEV "pci"
|
||||
static int
|
||||
linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi, char *path,
|
||||
char *prefix)
|
||||
{
|
||||
struct scsi_host_queue *scsi_host;
|
||||
struct pfs_node *sub_dir;
|
||||
int i, nchildren;
|
||||
device_t *children, parent;
|
||||
devclass_t devclass;
|
||||
const char *name = NULL;
|
||||
struct pci_devinfo *dinfo;
|
||||
char *device, *host, *new_path = path;
|
||||
|
||||
parent = device_get_parent(dev);
|
||||
if (parent) {
|
||||
devclass = device_get_devclass(parent);
|
||||
if (devclass != NULL)
|
||||
name = devclass_get_name(devclass);
|
||||
if (name && strcmp(name, PCI_DEV) == 0) {
|
||||
dinfo = device_get_ivars(dev);
|
||||
if (dinfo) {
|
||||
device = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
|
||||
new_path = malloc(MAXPATHLEN, M_TEMP,
|
||||
M_WAITOK);
|
||||
new_path[0] = '\000';
|
||||
strcpy(new_path, path);
|
||||
host = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
|
||||
device[0] = '\000';
|
||||
sprintf(device, "%s:%02x:%02x.%x",
|
||||
prefix,
|
||||
dinfo->cfg.bus,
|
||||
dinfo->cfg.slot,
|
||||
dinfo->cfg.func);
|
||||
strcat(new_path, "/");
|
||||
strcat(new_path, device);
|
||||
dir = pfs_create_dir(dir, device,
|
||||
NULL, NULL, 0);
|
||||
|
||||
if (dinfo->cfg.baseclass == PCIC_STORAGE) {
|
||||
/* DJA only make this if needed */
|
||||
sprintf(host, "host%d", host_number++);
|
||||
strcat(new_path, "/");
|
||||
strcat(new_path, host);
|
||||
sub_dir = pfs_create_dir(dir,
|
||||
host, NULL, NULL, 0);
|
||||
scsi_host = malloc(sizeof(
|
||||
struct scsi_host_queue),
|
||||
M_DEVBUF, M_NOWAIT);
|
||||
scsi_host->path = malloc(
|
||||
strlen(new_path) + 1,
|
||||
M_DEVBUF, M_NOWAIT);
|
||||
scsi_host->path[0] = '\000';
|
||||
bcopy(new_path, scsi_host->path,
|
||||
strlen(new_path) + 1);
|
||||
scsi_host->name = "unknown";
|
||||
|
||||
sub_dir = pfs_create_dir(scsi, host,
|
||||
NULL, NULL, 0);
|
||||
pfs_create_link(sub_dir, "device",
|
||||
&linsysfs_link_scsi_host,
|
||||
NULL, NULL, 0);
|
||||
pfs_create_file(sub_dir, "proc_name",
|
||||
&linsysfs_scsiname,
|
||||
NULL, NULL, PFS_RD);
|
||||
scsi_host->name
|
||||
= linux_driver_get_name_dev(dev);
|
||||
TAILQ_INSERT_TAIL(&scsi_host_q,
|
||||
scsi_host, scsi_host_next);
|
||||
}
|
||||
free(device, M_TEMP);
|
||||
free(host, M_TEMP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
device_get_children(dev, &children, &nchildren);
|
||||
for (i = 0; i < nchildren; i++) {
|
||||
if (children[i])
|
||||
linsysfs_run_bus(children[i], dir, scsi, new_path, prefix);
|
||||
}
|
||||
if (new_path != path)
|
||||
free(new_path, M_TEMP);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
static int
|
||||
linsysfs_init(PFS_INIT_ARGS)
|
||||
{
|
||||
struct pfs_node *root;
|
||||
struct pfs_node *dir;
|
||||
struct pfs_node *pci;
|
||||
struct pfs_node *scsi;
|
||||
devclass_t devclass;
|
||||
device_t dev;
|
||||
|
||||
TAILQ_INIT(&scsi_host_q);
|
||||
|
||||
root = pi->pi_root;
|
||||
|
||||
/* /sys/class/... */
|
||||
scsi = pfs_create_dir(root, "class", NULL, NULL, 0);
|
||||
scsi = pfs_create_dir(scsi, "scsi_host", NULL, NULL, 0);
|
||||
|
||||
/* /sys/device */
|
||||
dir = pfs_create_dir(root, "devices", NULL, NULL, 0);
|
||||
|
||||
/* /sys/device/pci0000:00 */
|
||||
pci = pfs_create_dir(dir, "pci0000:00", NULL, NULL, 0);
|
||||
|
||||
devclass = devclass_find("root");
|
||||
if (devclass == NULL) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
dev = devclass_get_device(devclass, 0);
|
||||
linsysfs_run_bus(dev, pci, scsi, "/pci0000:00", "0000");
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Destructor
|
||||
*/
|
||||
static int
|
||||
linsysfs_uninit(PFS_INIT_ARGS)
|
||||
{
|
||||
struct scsi_host_queue *scsi_host;
|
||||
|
||||
TAILQ_FOREACH(scsi_host, &scsi_host_q, scsi_host_next) {
|
||||
TAILQ_REMOVE(&scsi_host_q, scsi_host, scsi_host_next);
|
||||
free(scsi_host->path, M_TEMP);
|
||||
free(scsi_host, M_TEMP);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
PSEUDOFS(linsysfs, 1);
|
||||
MODULE_DEPEND(linsysfs, linux, 1, 1, 1);
|
1095
sys/dev/ipmi/ipmi.c
Normal file
1095
sys/dev/ipmi/ipmi.c
Normal file
File diff suppressed because it is too large
Load Diff
90
sys/dev/mfi/mfi_linux.c
Normal file
90
sys/dev/mfi/mfi_linux.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 IronPort Systems
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/proc.h>
|
||||
|
||||
#if defined(__amd64__) /* Assume amd64 wants 32 bit Linux */
|
||||
#include <machine/../linux32/linux.h>
|
||||
#include <machine/../linux32/linux32_proto.h>
|
||||
#else
|
||||
#include <machine/../linux/linux.h>
|
||||
#include <machine/../linux/linux_proto.h>
|
||||
#endif
|
||||
#include <compat/linux/linux_ioctl.h>
|
||||
#include <compat/linux/linux_util.h>
|
||||
|
||||
/* There are multiple ioctl number ranges that need to be handled */
|
||||
#define MFI_LINUX_IOCTL_MIN 0x4d00
|
||||
#define MFI_LINUX_IOCTL_MAX 0x4d04
|
||||
|
||||
static linux_ioctl_function_t mfi_linux_ioctl;
|
||||
static struct linux_ioctl_handler mfi_linux_handler = {mfi_linux_ioctl,
|
||||
MFI_LINUX_IOCTL_MIN,
|
||||
MFI_LINUX_IOCTL_MAX};
|
||||
|
||||
SYSINIT (mfi_register, SI_SUB_KLD, SI_ORDER_MIDDLE,
|
||||
linux_ioctl_register_handler, &mfi_linux_handler);
|
||||
SYSUNINIT(mfi_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
|
||||
linux_ioctl_unregister_handler, &mfi_linux_handler);
|
||||
|
||||
static struct linux_device_handler mfi_device_handler =
|
||||
{ "mfi", "megaraid_sas", "mfi0", "megaraid_sas_ioctl_node", -1, 0, 1};
|
||||
|
||||
SYSINIT (mfi_register2, SI_SUB_KLD, SI_ORDER_MIDDLE,
|
||||
linux_device_register_handler, &mfi_device_handler);
|
||||
SYSUNINIT(mfi_unregister2, SI_SUB_KLD, SI_ORDER_MIDDLE,
|
||||
linux_device_unregister_handler, &mfi_device_handler);
|
||||
|
||||
static int
|
||||
mfi_linux_modevent(module_t mod, int cmd, void *data)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
DEV_MODULE(mfi_linux, mfi_linux_modevent, NULL);
|
||||
MODULE_DEPEND(mfi, linux, 1, 1, 1);
|
||||
|
||||
static int
|
||||
mfi_linux_ioctl(d_thread_t *p, struct linux_ioctl_args *args)
|
||||
{
|
||||
struct file *fp;
|
||||
int error;
|
||||
|
||||
if ((error = fget(p, args->fd, &fp)) != 0)
|
||||
return (error);
|
||||
error = fo_ioctl(fp, args->cmd, (caddr_t)args->arg, p->td_ucred, p);
|
||||
fdrop(fp, p);
|
||||
return (error);
|
||||
}
|
1586
sys/dev/sk/if_skreg.h
Normal file
1586
sys/dev/sk/if_skreg.h
Normal file
File diff suppressed because it is too large
Load Diff
11
sys/modules/linsysfs/Makefile
Normal file
11
sys/modules/linsysfs/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../compat/linsysfs
|
||||
|
||||
KMOD= linsysfs
|
||||
SRCS= vnode_if.h \
|
||||
device_if.h bus_if.h pci_if.h \
|
||||
linsysfs.c \
|
||||
opt_compat.h
|
||||
|
||||
.include <bsd.kmod.mk>
|
8
sys/modules/mfi/mfi_linux/Makefile
Normal file
8
sys/modules/mfi/mfi_linux/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../dev/mfi
|
||||
|
||||
KMOD= mfi_linux
|
||||
SRCS= mfi_linux.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
523
sys/pci/amdsmb.c
Normal file
523
sys/pci/amdsmb.c
Normal file
@ -0,0 +1,523 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include <dev/iicbus/iiconf.h>
|
||||
#include <dev/smbus/smbconf.h>
|
||||
#include "smbus_if.h"
|
||||
|
||||
#define AMDSMB_DEBUG(x) if (amdsmb_debug) (x)
|
||||
|
||||
#ifdef DEBUG
|
||||
static int amdsmb_debug = 1;
|
||||
#else
|
||||
static int amdsmb_debug = 0;
|
||||
#endif
|
||||
|
||||
#define AMDSMB_VENDORID_AMD 0x1022
|
||||
#define AMDSMB_DEVICEID_AMD8111_SMB2 0x746a
|
||||
|
||||
/*
|
||||
* ACPI 3.0, Chapter 12, Embedded Controller Interface.
|
||||
*/
|
||||
#define EC_DATA 0x00 /* data register */
|
||||
#define EC_SC 0x04 /* status of controller */
|
||||
#define EC_CMD 0x04 /* command register */
|
||||
|
||||
#define EC_SC_IBF 0x02 /* data ready for embedded controller */
|
||||
#define EC_SC_OBF 0x01 /* data ready for host */
|
||||
#define EC_CMD_WR 0x81 /* write EC */
|
||||
#define EC_CMD_RD 0x80 /* read EC */
|
||||
|
||||
/*
|
||||
* ACPI 3.0, Chapter 12, SMBus Host Controller Interface.
|
||||
*/
|
||||
#define SMB_PRTCL 0x00 /* protocol */
|
||||
#define SMB_STS 0x01 /* status */
|
||||
#define SMB_ADDR 0x02 /* address */
|
||||
#define SMB_CMD 0x03 /* command */
|
||||
#define SMB_DATA 0x04 /* 32 data registers */
|
||||
#define SMB_BCNT 0x24 /* number of data bytes */
|
||||
#define SMB_ALRM_A 0x25 /* alarm address */
|
||||
#define SMB_ALRM_D 0x26 /* 2 bytes alarm data */
|
||||
|
||||
#define SMB_STS_DONE 0x80
|
||||
#define SMB_STS_ALRM 0x40
|
||||
#define SMB_STS_RES 0x20
|
||||
#define SMB_STS_STATUS 0x1f
|
||||
#define SMB_STS_OK 0x00 /* OK */
|
||||
#define SMB_STS_UF 0x07 /* Unknown Failure */
|
||||
#define SMB_STS_DANA 0x10 /* Device Address Not Acknowledged */
|
||||
#define SMB_STS_DED 0x11 /* Device Error Detected */
|
||||
#define SMB_STS_DCAD 0x12 /* Device Command Access Denied */
|
||||
#define SMB_STS_UE 0x13 /* Unknown Error */
|
||||
#define SMB_STS_DAD 0x17 /* Device Access Denied */
|
||||
#define SMB_STS_T 0x18 /* Timeout */
|
||||
#define SMB_STS_HUP 0x19 /* Host Unsupported Protocol */
|
||||
#define SMB_STS_B 0x1a /* Busy */
|
||||
#define SMB_STS_PEC 0x1f /* PEC (CRC-8) Error */
|
||||
|
||||
#define SMB_PRTCL_WRITE 0x00
|
||||
#define SMB_PRTCL_READ 0x01
|
||||
#define SMB_PRTCL_QUICK 0x02
|
||||
#define SMB_PRTCL_BYTE 0x04
|
||||
#define SMB_PRTCL_BYTE_DATA 0x06
|
||||
#define SMB_PRTCL_WORD_DATA 0x08
|
||||
#define SMB_PRTCL_BLOCK_DATA 0x0a
|
||||
#define SMB_PRTCL_PROC_CALL 0x0c
|
||||
#define SMB_PRTCL_BLOCK_PROC_CALL 0x0d
|
||||
#define SMB_PRTCL_PEC 0x80
|
||||
|
||||
struct amdsmb_softc {
|
||||
int rid;
|
||||
struct resource *res;
|
||||
bus_space_tag_t smbst;
|
||||
bus_space_handle_t smbsh;
|
||||
|
||||
device_t smbus;
|
||||
};
|
||||
|
||||
#define AMDSMB_ECINB(amdsmb, register) \
|
||||
(bus_space_read_1(amdsmb->smbst, amdsmb->smbsh, register))
|
||||
#define AMDSMB_ECOUTB(amdsmb, register, value) \
|
||||
(bus_space_write_1(amdsmb->smbst, amdsmb->smbsh, register, value))
|
||||
|
||||
static int
|
||||
amdsmb_probe(device_t dev)
|
||||
{
|
||||
u_int16_t vid;
|
||||
u_int16_t did;
|
||||
|
||||
vid = pci_get_vendor(dev);
|
||||
did = pci_get_device(dev);
|
||||
|
||||
if (vid == AMDSMB_VENDORID_AMD) {
|
||||
switch(did) {
|
||||
case AMDSMB_DEVICEID_AMD8111_SMB2:
|
||||
device_set_desc(dev, "AMD-8111 SMBus 2.0 Controller");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_attach(device_t dev)
|
||||
{
|
||||
struct amdsmb_softc *amdsmb_sc = device_get_softc(dev);
|
||||
|
||||
/* Allocate I/O space */
|
||||
amdsmb_sc->rid = PCIR_BAR(0);
|
||||
|
||||
amdsmb_sc->res = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
|
||||
&amdsmb_sc->rid, RF_ACTIVE);
|
||||
|
||||
if (amdsmb_sc->res == NULL) {
|
||||
device_printf(dev, "could not map i/o space\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
amdsmb_sc->smbst = rman_get_bustag(amdsmb_sc->res);
|
||||
amdsmb_sc->smbsh = rman_get_bushandle(amdsmb_sc->res);
|
||||
|
||||
/* Allocate a new smbus device */
|
||||
amdsmb_sc->smbus = device_add_child(dev, "smbus", -1);
|
||||
if (!amdsmb_sc->smbus)
|
||||
return (EINVAL);
|
||||
|
||||
bus_generic_attach(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_detach(device_t dev)
|
||||
{
|
||||
struct amdsmb_softc *amdsmb_sc = device_get_softc(dev);
|
||||
|
||||
if (amdsmb_sc->smbus) {
|
||||
device_delete_child(dev, amdsmb_sc->smbus);
|
||||
amdsmb_sc->smbus = NULL;
|
||||
}
|
||||
|
||||
if (amdsmb_sc->res)
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, amdsmb_sc->rid,
|
||||
amdsmb_sc->res);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_callback(device_t dev, int index, caddr_t *data)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
switch (index) {
|
||||
case SMB_REQUEST_BUS:
|
||||
case SMB_RELEASE_BUS:
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_ec_wait_write(struct amdsmb_softc *sc)
|
||||
{
|
||||
int timeout = 500;
|
||||
|
||||
while (timeout-- && AMDSMB_ECINB(sc, EC_SC) & EC_SC_IBF)
|
||||
DELAY(1);
|
||||
if (timeout == 0) {
|
||||
device_printf(sc->smbus, "timeout waiting for IBF to clear\n");
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_ec_wait_read(struct amdsmb_softc *sc)
|
||||
{
|
||||
int timeout = 500;
|
||||
|
||||
while (timeout-- && ~AMDSMB_ECINB(sc, EC_SC) & EC_SC_OBF)
|
||||
DELAY(1);
|
||||
if (timeout == 0) {
|
||||
device_printf(sc->smbus, "timeout waiting for OBF to set\n");
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_ec_read(struct amdsmb_softc *sc, u_char addr, u_char *data)
|
||||
{
|
||||
|
||||
if (amdsmb_ec_wait_write(sc))
|
||||
return (1);
|
||||
AMDSMB_ECOUTB(sc, EC_CMD, EC_CMD_RD);
|
||||
|
||||
if (amdsmb_ec_wait_write(sc))
|
||||
return (1);
|
||||
AMDSMB_ECOUTB(sc, EC_DATA, addr);
|
||||
|
||||
if (amdsmb_ec_wait_read(sc))
|
||||
return (1);
|
||||
*data = AMDSMB_ECINB(sc, EC_DATA);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_ec_write(struct amdsmb_softc *sc, u_char addr, u_char data)
|
||||
{
|
||||
|
||||
if (amdsmb_ec_wait_write(sc))
|
||||
return (1);
|
||||
AMDSMB_ECOUTB(sc, EC_CMD, EC_CMD_WR);
|
||||
|
||||
if (amdsmb_ec_wait_write(sc))
|
||||
return (1);
|
||||
AMDSMB_ECOUTB(sc, EC_DATA, addr);
|
||||
|
||||
if (amdsmb_ec_wait_write(sc))
|
||||
return (1);
|
||||
AMDSMB_ECOUTB(sc, EC_DATA, data);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_wait(struct amdsmb_softc *sc)
|
||||
{
|
||||
u_char sts, temp;
|
||||
int error, count;
|
||||
|
||||
amdsmb_ec_read(sc, SMB_PRTCL, &temp);
|
||||
if (temp != 0)
|
||||
{
|
||||
count = 10000;
|
||||
do {
|
||||
DELAY(500);
|
||||
amdsmb_ec_read(sc, SMB_PRTCL, &temp);
|
||||
} while (temp != 0 && count--);
|
||||
if (count == 0)
|
||||
return (SMB_ETIMEOUT);
|
||||
}
|
||||
|
||||
amdsmb_ec_read(sc, SMB_STS, &sts);
|
||||
sts &= SMB_STS_STATUS;
|
||||
AMDSMB_DEBUG(printf("amdsmb: STS=0x%x\n", sts));
|
||||
|
||||
switch (sts) {
|
||||
case SMB_STS_OK:
|
||||
error = SMB_ENOERR;
|
||||
break;
|
||||
case SMB_STS_DANA:
|
||||
error = SMB_ENOACK;
|
||||
break;
|
||||
case SMB_STS_B:
|
||||
error = SMB_EBUSY;
|
||||
break;
|
||||
case SMB_STS_T:
|
||||
error = SMB_ETIMEOUT;
|
||||
break;
|
||||
case SMB_STS_DCAD:
|
||||
case SMB_STS_DAD:
|
||||
case SMB_STS_HUP:
|
||||
error = SMB_ENOTSUPP;
|
||||
break;
|
||||
default:
|
||||
error = SMB_EBUSERR;
|
||||
break;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_quick(device_t dev, u_char slave, int how)
|
||||
{
|
||||
struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
|
||||
u_char protocol;
|
||||
int error;
|
||||
|
||||
protocol = SMB_PRTCL_QUICK;
|
||||
|
||||
switch (how) {
|
||||
case SMB_QWRITE:
|
||||
protocol |= SMB_PRTCL_WRITE;
|
||||
AMDSMB_DEBUG(printf("amdsmb: QWRITE to 0x%x", slave));
|
||||
break;
|
||||
case SMB_QREAD:
|
||||
protocol |= SMB_PRTCL_READ;
|
||||
AMDSMB_DEBUG(printf("amdsmb: QREAD to 0x%x", slave));
|
||||
break;
|
||||
default:
|
||||
panic("%s: unknown QUICK command (%x)!", __func__, how);
|
||||
}
|
||||
|
||||
amdsmb_ec_write(sc, SMB_ADDR, slave);
|
||||
amdsmb_ec_write(sc, SMB_PRTCL, protocol);
|
||||
|
||||
error = amdsmb_wait(sc);
|
||||
|
||||
AMDSMB_DEBUG(printf(", error=0x%x\n", error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_sendb(device_t dev, u_char slave, char byte)
|
||||
{
|
||||
struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
amdsmb_ec_write(sc, SMB_CMD, byte);
|
||||
amdsmb_ec_write(sc, SMB_ADDR, slave);
|
||||
amdsmb_ec_write(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_BYTE);
|
||||
|
||||
error = amdsmb_wait(sc);
|
||||
|
||||
AMDSMB_DEBUG(printf("amdsmb: SENDB to 0x%x, byte=0x%x, error=0x%x\n",
|
||||
slave, byte, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_recvb(device_t dev, u_char slave, char *byte)
|
||||
{
|
||||
struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
amdsmb_ec_write(sc, SMB_ADDR, slave);
|
||||
amdsmb_ec_write(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_BYTE);
|
||||
|
||||
if ((error = amdsmb_wait(sc)) == SMB_ENOERR)
|
||||
amdsmb_ec_read(sc, SMB_DATA, byte);
|
||||
|
||||
AMDSMB_DEBUG(printf("amdsmb: RECVB from 0x%x, byte=0x%x, error=0x%x\n",
|
||||
slave, *byte, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_writeb(device_t dev, u_char slave, char cmd, char byte)
|
||||
{
|
||||
struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
amdsmb_ec_write(sc, SMB_CMD, cmd);
|
||||
amdsmb_ec_write(sc, SMB_DATA, byte);
|
||||
amdsmb_ec_write(sc, SMB_ADDR, slave);
|
||||
amdsmb_ec_write(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_BYTE_DATA);
|
||||
|
||||
error = amdsmb_wait(sc);
|
||||
|
||||
AMDSMB_DEBUG(printf("amdsmb: WRITEB to 0x%x, cmd=0x%x, byte=0x%x, "
|
||||
"error=0x%x\n", slave, cmd, byte, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_readb(device_t dev, u_char slave, char cmd, char *byte)
|
||||
{
|
||||
struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
amdsmb_ec_write(sc, SMB_CMD, cmd);
|
||||
amdsmb_ec_write(sc, SMB_ADDR, slave);
|
||||
amdsmb_ec_write(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_BYTE_DATA);
|
||||
|
||||
if ((error = amdsmb_wait(sc)) == SMB_ENOERR)
|
||||
amdsmb_ec_read(sc, SMB_DATA, byte);
|
||||
|
||||
AMDSMB_DEBUG(printf("amdsmb: READB from 0x%x, cmd=0x%x, byte=0x%x, "
|
||||
"error=0x%x\n", slave, cmd, (unsigned char)*byte, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_writew(device_t dev, u_char slave, char cmd, short word)
|
||||
{
|
||||
struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
amdsmb_ec_write(sc, SMB_CMD, cmd);
|
||||
amdsmb_ec_write(sc, SMB_DATA, word);
|
||||
amdsmb_ec_write(sc, SMB_DATA + 1, word >> 8);
|
||||
amdsmb_ec_write(sc, SMB_ADDR, slave);
|
||||
amdsmb_ec_write(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_WORD_DATA);
|
||||
|
||||
error = amdsmb_wait(sc);
|
||||
|
||||
AMDSMB_DEBUG(printf("amdsmb: WRITEW to 0x%x, cmd=0x%x, word=0x%x, "
|
||||
"error=0x%x\n", slave, cmd, word, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_readw(device_t dev, u_char slave, char cmd, short *word)
|
||||
{
|
||||
struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
|
||||
u_char temp[2];
|
||||
int error;
|
||||
|
||||
amdsmb_ec_write(sc, SMB_CMD, cmd);
|
||||
amdsmb_ec_write(sc, SMB_ADDR, slave);
|
||||
amdsmb_ec_write(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_WORD_DATA);
|
||||
|
||||
if ((error = amdsmb_wait(sc)) == SMB_ENOERR) {
|
||||
amdsmb_ec_read(sc, SMB_DATA + 0, &temp[0]);
|
||||
amdsmb_ec_read(sc, SMB_DATA + 1, &temp[1]);
|
||||
*word = temp[0] | (temp[1] << 8);
|
||||
}
|
||||
|
||||
AMDSMB_DEBUG(printf("amdsmb: READW from 0x%x, cmd=0x%x, word=0x%x, "
|
||||
"error=0x%x\n", slave, cmd, (unsigned short)*word, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
|
||||
{
|
||||
struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
|
||||
u_char len, i;
|
||||
int error;
|
||||
|
||||
len = min(count, 32);
|
||||
amdsmb_ec_write(sc, SMB_CMD, cmd);
|
||||
amdsmb_ec_write(sc, SMB_BCNT, len);
|
||||
for (i = 0; i < len; i++)
|
||||
amdsmb_ec_write(sc, SMB_DATA + i, buf[i]);
|
||||
amdsmb_ec_write(sc, SMB_ADDR, slave);
|
||||
amdsmb_ec_write(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_BLOCK_DATA);
|
||||
|
||||
error = amdsmb_wait(sc);
|
||||
|
||||
AMDSMB_DEBUG(printf("amdsmb: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, "
|
||||
"error=0x%x", slave, count, cmd, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
amdsmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
|
||||
{
|
||||
struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
|
||||
u_char len, i;
|
||||
int error;
|
||||
|
||||
amdsmb_ec_write(sc, SMB_CMD, cmd);
|
||||
amdsmb_ec_write(sc, SMB_ADDR, slave);
|
||||
amdsmb_ec_write(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_BLOCK_DATA);
|
||||
|
||||
if ((error = amdsmb_wait(sc)) == SMB_ENOERR) {
|
||||
amdsmb_ec_read(sc, SMB_BCNT, &len);
|
||||
len = min(len, 32);
|
||||
for (i = 0; i < len; i++)
|
||||
amdsmb_ec_read(sc, SMB_DATA + i, buf + i);
|
||||
}
|
||||
|
||||
AMDSMB_DEBUG(printf("amdsmb: READBLK to 0x%x, count=0x%x, cmd=0x%x, "
|
||||
"error=0x%x", slave, count, cmd, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static device_method_t amdsmb_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, amdsmb_probe),
|
||||
DEVMETHOD(device_attach, amdsmb_attach),
|
||||
DEVMETHOD(device_detach, amdsmb_detach),
|
||||
|
||||
/* SMBus interface */
|
||||
DEVMETHOD(smbus_callback, amdsmb_callback),
|
||||
DEVMETHOD(smbus_quick, amdsmb_quick),
|
||||
DEVMETHOD(smbus_sendb, amdsmb_sendb),
|
||||
DEVMETHOD(smbus_recvb, amdsmb_recvb),
|
||||
DEVMETHOD(smbus_writeb, amdsmb_writeb),
|
||||
DEVMETHOD(smbus_readb, amdsmb_readb),
|
||||
DEVMETHOD(smbus_writew, amdsmb_writew),
|
||||
DEVMETHOD(smbus_readw, amdsmb_readw),
|
||||
DEVMETHOD(smbus_bwrite, amdsmb_bwrite),
|
||||
DEVMETHOD(smbus_bread, amdsmb_bread),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static devclass_t amdsmb_devclass;
|
||||
|
||||
static driver_t amdsmb_driver = {
|
||||
"amdsmb",
|
||||
amdsmb_methods,
|
||||
sizeof(struct amdsmb_softc),
|
||||
};
|
||||
|
||||
DRIVER_MODULE(amdsmb, pci, amdsmb_driver, amdsmb_devclass, 0, 0);
|
||||
|
||||
MODULE_DEPEND(amdsmb, pci, 1, 1, 1);
|
||||
MODULE_DEPEND(amdsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
|
||||
MODULE_VERSION(amdsmb, 1);
|
552
sys/pci/nfsmb.c
Normal file
552
sys/pci/nfsmb.c
Normal file
@ -0,0 +1,552 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include <dev/iicbus/iiconf.h>
|
||||
#include <dev/smbus/smbconf.h>
|
||||
#include "smbus_if.h"
|
||||
|
||||
#define NFSMB_DEBUG(x) if (nfsmb_debug) (x)
|
||||
|
||||
#ifdef DEBUG
|
||||
static int nfsmb_debug = 1;
|
||||
#else
|
||||
static int nfsmb_debug = 0;
|
||||
#endif
|
||||
|
||||
/* NVIDIA nForce2/3/4 MCP */
|
||||
#define NFSMB_VENDORID_NVIDIA 0x10de
|
||||
#define NFSMB_DEVICEID_NF2_SMB 0x0064
|
||||
#define NFSMB_DEVICEID_NF2_ULTRA_SMB 0x0084
|
||||
#define NFSMB_DEVICEID_NF3_PRO150_SMB 0x00d4
|
||||
#define NFSMB_DEVICEID_NF3_250GB_SMB 0x00e4
|
||||
#define NFSMB_DEVICEID_NF4_SMB 0x0052
|
||||
|
||||
/* PCI Configuration space registers */
|
||||
#define NF2PCI_SMBASE_1 PCIR_BAR(4)
|
||||
#define NF2PCI_SMBASE_2 PCIR_BAR(5)
|
||||
|
||||
/*
|
||||
* ACPI 3.0, Chapter 12, SMBus Host Controller Interface.
|
||||
*/
|
||||
#define SMB_PRTCL 0x00 /* protocol */
|
||||
#define SMB_STS 0x01 /* status */
|
||||
#define SMB_ADDR 0x02 /* address */
|
||||
#define SMB_CMD 0x03 /* command */
|
||||
#define SMB_DATA 0x04 /* 32 data registers */
|
||||
#define SMB_BCNT 0x24 /* number of data bytes */
|
||||
#define SMB_ALRM_A 0x25 /* alarm address */
|
||||
#define SMB_ALRM_D 0x26 /* 2 bytes alarm data */
|
||||
|
||||
#define SMB_STS_DONE 0x80
|
||||
#define SMB_STS_ALRM 0x40
|
||||
#define SMB_STS_RES 0x20
|
||||
#define SMB_STS_STATUS 0x1f
|
||||
#define SMB_STS_OK 0x00 /* OK */
|
||||
#define SMB_STS_UF 0x07 /* Unknown Failure */
|
||||
#define SMB_STS_DANA 0x10 /* Device Address Not Acknowledged */
|
||||
#define SMB_STS_DED 0x11 /* Device Error Detected */
|
||||
#define SMB_STS_DCAD 0x12 /* Device Command Access Denied */
|
||||
#define SMB_STS_UE 0x13 /* Unknown Error */
|
||||
#define SMB_STS_DAD 0x17 /* Device Access Denied */
|
||||
#define SMB_STS_T 0x18 /* Timeout */
|
||||
#define SMB_STS_HUP 0x19 /* Host Unsupported Protocol */
|
||||
#define SMB_STS_B 0x1A /* Busy */
|
||||
#define SMB_STS_PEC 0x1F /* PEC (CRC-8) Error */
|
||||
|
||||
#define SMB_PRTCL_WRITE 0x00
|
||||
#define SMB_PRTCL_READ 0x01
|
||||
#define SMB_PRTCL_QUICK 0x02
|
||||
#define SMB_PRTCL_BYTE 0x04
|
||||
#define SMB_PRTCL_BYTE_DATA 0x06
|
||||
#define SMB_PRTCL_WORD_DATA 0x08
|
||||
#define SMB_PRTCL_BLOCK_DATA 0x0a
|
||||
#define SMB_PRTCL_PROC_CALL 0x0c
|
||||
#define SMB_PRTCL_BLOCK_PROC_CALL 0x0d
|
||||
#define SMB_PRTCL_PEC 0x80
|
||||
|
||||
struct nfsmb_softc {
|
||||
int rid;
|
||||
struct resource *res;
|
||||
bus_space_tag_t smbst;
|
||||
bus_space_handle_t smbsh;
|
||||
|
||||
device_t smbus;
|
||||
device_t subdev;
|
||||
};
|
||||
|
||||
#define NFSMB_SMBINB(nfsmb, register) \
|
||||
(bus_space_read_1(nfsmb->smbst, nfsmb->smbsh, register))
|
||||
#define NFSMB_SMBOUTB(nfsmb, register, value) \
|
||||
(bus_space_write_1(nfsmb->smbst, nfsmb->smbsh, register, value))
|
||||
|
||||
static int
|
||||
nfsmbsub_probe(device_t dev)
|
||||
{
|
||||
|
||||
device_set_desc(dev, "nForce2/3/4 MCP SMBus Controller");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
nfsmb_probe(device_t dev)
|
||||
{
|
||||
u_int16_t vid;
|
||||
u_int16_t did;
|
||||
|
||||
vid = pci_get_vendor(dev);
|
||||
did = pci_get_device(dev);
|
||||
|
||||
if (vid == NFSMB_VENDORID_NVIDIA) {
|
||||
switch(did) {
|
||||
case NFSMB_DEVICEID_NF2_SMB:
|
||||
case NFSMB_DEVICEID_NF2_ULTRA_SMB:
|
||||
case NFSMB_DEVICEID_NF3_PRO150_SMB:
|
||||
case NFSMB_DEVICEID_NF3_250GB_SMB:
|
||||
case NFSMB_DEVICEID_NF4_SMB:
|
||||
device_set_desc(dev, "nForce2/3/4 MCP SMBus Controller");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
nfsmbsub_attach(device_t dev)
|
||||
{
|
||||
device_t parent;
|
||||
struct nfsmb_softc *nfsmbsub_sc = device_get_softc(dev);
|
||||
|
||||
parent = device_get_parent(dev);
|
||||
|
||||
nfsmbsub_sc->rid = NF2PCI_SMBASE_2;
|
||||
|
||||
nfsmbsub_sc->res = bus_alloc_resource_any(parent, SYS_RES_IOPORT,
|
||||
&nfsmbsub_sc->rid, RF_ACTIVE);
|
||||
if (nfsmbsub_sc->res == NULL) {
|
||||
device_printf(dev, "could not map i/o space\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
nfsmbsub_sc->smbst = rman_get_bustag(nfsmbsub_sc->res);
|
||||
nfsmbsub_sc->smbsh = rman_get_bushandle(nfsmbsub_sc->res);
|
||||
|
||||
nfsmbsub_sc->smbus = device_add_child(dev, "smbus", -1);
|
||||
if (nfsmbsub_sc->smbus == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
bus_generic_attach(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
nfsmb_attach(device_t dev)
|
||||
{
|
||||
struct nfsmb_softc *nfsmb_sc = device_get_softc(dev);
|
||||
|
||||
/* Allocate I/O space */
|
||||
nfsmb_sc->rid = NF2PCI_SMBASE_1;
|
||||
|
||||
nfsmb_sc->res = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
|
||||
&nfsmb_sc->rid, RF_ACTIVE);
|
||||
|
||||
if (nfsmb_sc->res == NULL) {
|
||||
device_printf(dev, "could not map i/o space\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
nfsmb_sc->smbst = rman_get_bustag(nfsmb_sc->res);
|
||||
nfsmb_sc->smbsh = rman_get_bushandle(nfsmb_sc->res);
|
||||
|
||||
/* Allocate a new smbus device */
|
||||
nfsmb_sc->smbus = device_add_child(dev, "smbus", -1);
|
||||
if (!nfsmb_sc->smbus)
|
||||
return (EINVAL);
|
||||
|
||||
nfsmb_sc->subdev = NULL;
|
||||
switch (pci_get_device(dev)) {
|
||||
case NFSMB_DEVICEID_NF2_SMB:
|
||||
case NFSMB_DEVICEID_NF2_ULTRA_SMB:
|
||||
case NFSMB_DEVICEID_NF3_PRO150_SMB:
|
||||
case NFSMB_DEVICEID_NF3_250GB_SMB:
|
||||
case NFSMB_DEVICEID_NF4_SMB:
|
||||
/* Trying to add secondary device as slave */
|
||||
nfsmb_sc->subdev = device_add_child(dev, "nfsmb", -1);
|
||||
if (!nfsmb_sc->subdev)
|
||||
return (EINVAL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bus_generic_attach(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
nfsmbsub_detach(device_t dev)
|
||||
{
|
||||
device_t parent;
|
||||
struct nfsmb_softc *nfsmbsub_sc = device_get_softc(dev);
|
||||
|
||||
parent = device_get_parent(dev);
|
||||
|
||||
if (nfsmbsub_sc->smbus) {
|
||||
device_delete_child(dev, nfsmbsub_sc->smbus);
|
||||
nfsmbsub_sc->smbus = NULL;
|
||||
}
|
||||
if (nfsmbsub_sc->res) {
|
||||
bus_release_resource(parent, SYS_RES_IOPORT, nfsmbsub_sc->rid,
|
||||
nfsmbsub_sc->res);
|
||||
nfsmbsub_sc->res = NULL;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
nfsmb_detach(device_t dev)
|
||||
{
|
||||
struct nfsmb_softc *nfsmb_sc = device_get_softc(dev);
|
||||
|
||||
if (nfsmb_sc->subdev) {
|
||||
device_delete_child(dev, nfsmb_sc->subdev);
|
||||
nfsmb_sc->subdev = NULL;
|
||||
}
|
||||
|
||||
if (nfsmb_sc->smbus) {
|
||||
device_delete_child(dev, nfsmb_sc->smbus);
|
||||
nfsmb_sc->smbus = NULL;
|
||||
}
|
||||
|
||||
if (nfsmb_sc->res) {
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, nfsmb_sc->rid,
|
||||
nfsmb_sc->res);
|
||||
nfsmb_sc->res = NULL;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
nfsmb_callback(device_t dev, int index, caddr_t *data)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
switch (index) {
|
||||
case SMB_REQUEST_BUS:
|
||||
case SMB_RELEASE_BUS:
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
nfsmb_wait(struct nfsmb_softc *sc)
|
||||
{
|
||||
u_char sts;
|
||||
int error, count;
|
||||
|
||||
if (NFSMB_SMBINB(sc, SMB_PRTCL) != 0)
|
||||
{
|
||||
count = 10000;
|
||||
do {
|
||||
DELAY(500);
|
||||
} while (NFSMB_SMBINB(sc, SMB_PRTCL) != 0 && count--);
|
||||
if (count == 0)
|
||||
return (SMB_ETIMEOUT);
|
||||
}
|
||||
|
||||
sts = NFSMB_SMBINB(sc, SMB_STS) & SMB_STS_STATUS;
|
||||
NFSMB_DEBUG(printf("nfsmb: STS=0x%x\n", sts));
|
||||
|
||||
switch (sts) {
|
||||
case SMB_STS_OK:
|
||||
error = SMB_ENOERR;
|
||||
break;
|
||||
case SMB_STS_DANA:
|
||||
error = SMB_ENOACK;
|
||||
break;
|
||||
case SMB_STS_B:
|
||||
error = SMB_EBUSY;
|
||||
break;
|
||||
case SMB_STS_T:
|
||||
error = SMB_ETIMEOUT;
|
||||
break;
|
||||
case SMB_STS_DCAD:
|
||||
case SMB_STS_DAD:
|
||||
case SMB_STS_HUP:
|
||||
error = SMB_ENOTSUPP;
|
||||
break;
|
||||
default:
|
||||
error = SMB_EBUSERR;
|
||||
break;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
nfsmb_quick(device_t dev, u_char slave, int how)
|
||||
{
|
||||
struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
|
||||
u_char protocol;
|
||||
int error;
|
||||
|
||||
protocol = SMB_PRTCL_QUICK;
|
||||
|
||||
switch (how) {
|
||||
case SMB_QWRITE:
|
||||
protocol |= SMB_PRTCL_WRITE;
|
||||
NFSMB_DEBUG(printf("nfsmb: QWRITE to 0x%x", slave));
|
||||
break;
|
||||
case SMB_QREAD:
|
||||
protocol |= SMB_PRTCL_READ;
|
||||
NFSMB_DEBUG(printf("nfsmb: QREAD to 0x%x", slave));
|
||||
break;
|
||||
default:
|
||||
panic("%s: unknown QUICK command (%x)!", __func__, how);
|
||||
}
|
||||
|
||||
NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
|
||||
NFSMB_SMBOUTB(sc, SMB_PRTCL, protocol);
|
||||
|
||||
error = nfsmb_wait(sc);
|
||||
|
||||
NFSMB_DEBUG(printf(", error=0x%x\n", error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
nfsmb_sendb(device_t dev, u_char slave, char byte)
|
||||
{
|
||||
struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
NFSMB_SMBOUTB(sc, SMB_CMD, byte);
|
||||
NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
|
||||
NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_BYTE);
|
||||
|
||||
error = nfsmb_wait(sc);
|
||||
|
||||
NFSMB_DEBUG(printf("nfsmb: SENDB to 0x%x, byte=0x%x, error=0x%x\n", slave, byte, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
nfsmb_recvb(device_t dev, u_char slave, char *byte)
|
||||
{
|
||||
struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
|
||||
NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_BYTE);
|
||||
|
||||
if ((error = nfsmb_wait(sc)) == SMB_ENOERR)
|
||||
*byte = NFSMB_SMBINB(sc, SMB_DATA);
|
||||
|
||||
NFSMB_DEBUG(printf("nfsmb: RECVB from 0x%x, byte=0x%x, error=0x%x\n", slave, *byte, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
nfsmb_writeb(device_t dev, u_char slave, char cmd, char byte)
|
||||
{
|
||||
struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
|
||||
NFSMB_SMBOUTB(sc, SMB_DATA, byte);
|
||||
NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
|
||||
NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_BYTE_DATA);
|
||||
|
||||
error = nfsmb_wait(sc);
|
||||
|
||||
NFSMB_DEBUG(printf("nfsmb: WRITEB to 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, byte, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
nfsmb_readb(device_t dev, u_char slave, char cmd, char *byte)
|
||||
{
|
||||
struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
|
||||
NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
|
||||
NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_BYTE_DATA);
|
||||
|
||||
if ((error = nfsmb_wait(sc)) == SMB_ENOERR)
|
||||
*byte = NFSMB_SMBINB(sc, SMB_DATA);
|
||||
|
||||
NFSMB_DEBUG(printf("nfsmb: READB from 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, (unsigned char)*byte, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
nfsmb_writew(device_t dev, u_char slave, char cmd, short word)
|
||||
{
|
||||
struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
|
||||
NFSMB_SMBOUTB(sc, SMB_DATA, word);
|
||||
NFSMB_SMBOUTB(sc, SMB_DATA + 1, word >> 8);
|
||||
NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
|
||||
NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_WORD_DATA);
|
||||
|
||||
error = nfsmb_wait(sc);
|
||||
|
||||
NFSMB_DEBUG(printf("nfsmb: WRITEW to 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, word, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
nfsmb_readw(device_t dev, u_char slave, char cmd, short *word)
|
||||
{
|
||||
struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
|
||||
NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
|
||||
NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_WORD_DATA);
|
||||
|
||||
if ((error = nfsmb_wait(sc)) == SMB_ENOERR)
|
||||
*word = NFSMB_SMBINB(sc, SMB_DATA) |
|
||||
(NFSMB_SMBINB(sc, SMB_DATA + 1) << 8);
|
||||
|
||||
NFSMB_DEBUG(printf("nfsmb: READW from 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, (unsigned short)*word, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
nfsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
|
||||
{
|
||||
struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
|
||||
u_char len, i;
|
||||
int error;
|
||||
|
||||
len = min(count, 32);
|
||||
NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
|
||||
NFSMB_SMBOUTB(sc, SMB_BCNT, len);
|
||||
for (i = 0; i < len; i++)
|
||||
NFSMB_SMBOUTB(sc, SMB_DATA + i, buf[i]);
|
||||
NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
|
||||
NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_BLOCK_DATA);
|
||||
|
||||
error = nfsmb_wait(sc);
|
||||
|
||||
NFSMB_DEBUG(printf("nfsmb: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
nfsmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
|
||||
{
|
||||
struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
|
||||
u_char len, i;
|
||||
int error;
|
||||
|
||||
NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
|
||||
NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
|
||||
NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_BLOCK_DATA);
|
||||
|
||||
if ((error = nfsmb_wait(sc)) == SMB_ENOERR) {
|
||||
len = NFSMB_SMBINB(sc, SMB_BCNT);
|
||||
len = min(len, 32);
|
||||
for (i = 0; i < len; i++)
|
||||
buf[i] = NFSMB_SMBINB(sc, SMB_DATA + i);
|
||||
}
|
||||
|
||||
NFSMB_DEBUG(printf("nfsmb: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static device_method_t nfsmb_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, nfsmb_probe),
|
||||
DEVMETHOD(device_attach, nfsmb_attach),
|
||||
DEVMETHOD(device_detach, nfsmb_detach),
|
||||
|
||||
/* SMBus interface */
|
||||
DEVMETHOD(smbus_callback, nfsmb_callback),
|
||||
DEVMETHOD(smbus_quick, nfsmb_quick),
|
||||
DEVMETHOD(smbus_sendb, nfsmb_sendb),
|
||||
DEVMETHOD(smbus_recvb, nfsmb_recvb),
|
||||
DEVMETHOD(smbus_writeb, nfsmb_writeb),
|
||||
DEVMETHOD(smbus_readb, nfsmb_readb),
|
||||
DEVMETHOD(smbus_writew, nfsmb_writew),
|
||||
DEVMETHOD(smbus_readw, nfsmb_readw),
|
||||
DEVMETHOD(smbus_bwrite, nfsmb_bwrite),
|
||||
DEVMETHOD(smbus_bread, nfsmb_bread),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static device_method_t nfsmbsub_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, nfsmbsub_probe),
|
||||
DEVMETHOD(device_attach, nfsmbsub_attach),
|
||||
DEVMETHOD(device_detach, nfsmbsub_detach),
|
||||
|
||||
/* SMBus interface */
|
||||
DEVMETHOD(smbus_callback, nfsmb_callback),
|
||||
DEVMETHOD(smbus_quick, nfsmb_quick),
|
||||
DEVMETHOD(smbus_sendb, nfsmb_sendb),
|
||||
DEVMETHOD(smbus_recvb, nfsmb_recvb),
|
||||
DEVMETHOD(smbus_writeb, nfsmb_writeb),
|
||||
DEVMETHOD(smbus_readb, nfsmb_readb),
|
||||
DEVMETHOD(smbus_writew, nfsmb_writew),
|
||||
DEVMETHOD(smbus_readw, nfsmb_readw),
|
||||
DEVMETHOD(smbus_bwrite, nfsmb_bwrite),
|
||||
DEVMETHOD(smbus_bread, nfsmb_bread),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static devclass_t nfsmb_devclass;
|
||||
|
||||
static driver_t nfsmb_driver = {
|
||||
"nfsmb",
|
||||
nfsmb_methods,
|
||||
sizeof(struct nfsmb_softc),
|
||||
};
|
||||
|
||||
static driver_t nfsmbsub_driver = {
|
||||
"nfsmb",
|
||||
nfsmbsub_methods,
|
||||
sizeof(struct nfsmb_softc),
|
||||
};
|
||||
|
||||
DRIVER_MODULE(nfsmb, pci, nfsmb_driver, nfsmb_devclass, 0, 0);
|
||||
DRIVER_MODULE(nfsmb, nfsmb, nfsmbsub_driver, nfsmb_devclass, 0, 0);
|
||||
|
||||
MODULE_DEPEND(nfsmb, pci, 1, 1, 1);
|
||||
MODULE_DEPEND(nfsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
|
||||
MODULE_VERSION(nfsmb, 1);
|
65
tools/regression/geom_eli/nokey.t
Normal file
65
tools/regression/geom_eli/nokey.t
Normal file
@ -0,0 +1,65 @@
|
||||
#!/bin/sh
|
||||
# $FreeBSD$
|
||||
|
||||
base=`basename $0`
|
||||
no=45
|
||||
sectors=100
|
||||
keyfile=`mktemp /tmp/$base.XXXXXX` || exit 1
|
||||
mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
|
||||
|
||||
echo "1..8"
|
||||
|
||||
geli init -P md${no} 2>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ok 1"
|
||||
else
|
||||
echo "not ok 1"
|
||||
fi
|
||||
|
||||
dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1
|
||||
|
||||
geli init -P -K ${keyfile} md${no} 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "ok 2"
|
||||
else
|
||||
echo "not ok 2"
|
||||
fi
|
||||
geli attach -p md${no} 2>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ok 3"
|
||||
else
|
||||
echo "not ok 3"
|
||||
fi
|
||||
geli attach -p -k ${keyfile} md${no} 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "ok 4"
|
||||
else
|
||||
echo "not ok 4"
|
||||
fi
|
||||
geli setkey -n 0 -P md${no} 2>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ok 5"
|
||||
else
|
||||
echo "not ok 5"
|
||||
fi
|
||||
geli detach md${no} 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "ok 6"
|
||||
else
|
||||
echo "not ok 6"
|
||||
fi
|
||||
geli setkey -n 0 -p -P -K ${keyfile} md${no} 2>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ok 7"
|
||||
else
|
||||
echo "not ok 7"
|
||||
fi
|
||||
geli setkey -n 0 -p -k ${keyfile} -P md${no} 2>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ok 8"
|
||||
else
|
||||
echo "not ok 8"
|
||||
fi
|
||||
|
||||
mdconfig -d -u $no
|
||||
rm -f $keyfile
|
128
tools/tools/recoverdisk/recoverdisk.1
Normal file
128
tools/tools/recoverdisk/recoverdisk.1
Normal file
@ -0,0 +1,128 @@
|
||||
.\" Copyright (c) 2006 Ulrich Spoerlein <uspoerlein@gmail.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$
|
||||
.\"
|
||||
.Dd May 6, 2006
|
||||
.Dt RECOVERDISK 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm recoverdisk
|
||||
.Nd recover data from hard disk or optical media
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl r Ar rlist
|
||||
.Op Fl w Ar wlist
|
||||
.Ar special
|
||||
.Op file
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility reads data from the
|
||||
.Pa special
|
||||
file until all blocks could be successfully read.
|
||||
It starts reading in multiples of the sector size.
|
||||
Whenever a block fails, it is put to the end of the working queue and will be
|
||||
read again, possibly with a smaller read size.
|
||||
.Pp
|
||||
It uses block sizes of roughly 1 MB, 64kB, and the native sector size (usually
|
||||
512 bytes).
|
||||
These figures are adjusted slightly, for devices whose sectorsize is not a
|
||||
power of 2, e.g., audio CDs with a sector size of 2352 bytes.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width indent
|
||||
.It Fl r Ar rlist
|
||||
Read the list of blocks and block sizes to read from the specified file.
|
||||
.It Fl w Ar wlist
|
||||
Write the list of remaining blocks to read to the specified file if
|
||||
.Nm
|
||||
is aborted via SIGINT.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fl r
|
||||
and
|
||||
.Fl w
|
||||
option can be used in combination.
|
||||
Especially, they can point to the same file, which will be updated on abort.
|
||||
.Sh OUTPUT
|
||||
.Nm
|
||||
prints several columns, detailing the progress
|
||||
.Bl -tag -width remaining
|
||||
.It start
|
||||
Starting offset of the current block.
|
||||
.It size
|
||||
Read size of the current block.
|
||||
.It len
|
||||
Length of the current block.
|
||||
.It state
|
||||
Is increased for every failed read.
|
||||
.It done
|
||||
Number of bytes already read.
|
||||
.It remaining
|
||||
Number of bytes remaining.
|
||||
.It % done
|
||||
Percent complete.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
# recover data from failing hard drive ad3
|
||||
.Dl $ touch /data/lots_of_space
|
||||
.Dl $ recoverdisk /dev/ad3 /data/lots_of_space
|
||||
.Pp
|
||||
# clone a hard disk
|
||||
.Dl $ recoverdisk /dev/ad3 /dev/ad4
|
||||
.Pp
|
||||
# read an ISO image from a CD-ROM
|
||||
.Dl $ touch /data/cd.iso; recoverdisk /dev/acd0 /data/cd.iso
|
||||
.Pp
|
||||
# continue reading from a broken CD and update the existing worklist
|
||||
.Dl $ recoverdisk -r worklist -w worklist /dev/acd0 /data/cd.iso
|
||||
.Pp
|
||||
# recover a single file from the unreadable media
|
||||
.Dl $ touch file.avi; recoverdisk /cdrom/file.avi file.avi
|
||||
.Sh SEE ALSO
|
||||
.Xr dd 1
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command first appeared in
|
||||
.Fx 7.0 .
|
||||
.Sh BUGS
|
||||
Reading from media where the sectorsize is not a power of 2 will make all
|
||||
1 MB reads fail.
|
||||
This is due to the DMA reads being split up into blocks of at most 128kB.
|
||||
These reads then fail if the sectorsize is not a divisor of 128kB.
|
||||
When reading a full raw audio CD, this leads to roughly 700 error messages
|
||||
flying by.
|
||||
This is harmless.
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The original implementation was done by
|
||||
.An Poul-Henning Kamp Aq phk@freebsd.org
|
||||
with minor improvements from
|
||||
.An Ulrich Sp\(:orlein Aq uspoerlein@gmail.com .
|
||||
.Pp
|
||||
This manual page was written by
|
||||
.An Ulrich Sp\(:orlein Aq uspoerlein@gmail.com .
|
6
usr.bin/getent/Makefile
Normal file
6
usr.bin/getent/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= getent
|
||||
WARNS?= 3
|
||||
|
||||
.include <bsd.prog.mk>
|
129
usr.bin/getent/getent.1
Normal file
129
usr.bin/getent/getent.1
Normal file
@ -0,0 +1,129 @@
|
||||
.\" $NetBSD: getent.1,v 1.13 2005/09/11 23:16:15 wiz Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to The NetBSD Foundation
|
||||
.\" by Luke Mewburn.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd August 24, 2005
|
||||
.Dt GETENT 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm getent
|
||||
.Nd get entries from administrative database
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Ar database
|
||||
.Op Ar key ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
program retrieves and displays entries from the administrative
|
||||
database specified by
|
||||
.Ar database ,
|
||||
using the lookup order specified in
|
||||
.Xr nsswitch.conf 5 .
|
||||
The display format for a given
|
||||
.Ar database
|
||||
is as per the
|
||||
.Dq traditional
|
||||
file format for that database.
|
||||
.Pp
|
||||
.Ar database
|
||||
may be one of:
|
||||
.Bl -column "netgroup" -offset indent -compact
|
||||
.Sy Database Ta Sy Display format
|
||||
.It ethers Ta address name
|
||||
.It group Ta group:passwd:gid:[member[,member]...]
|
||||
.It hosts Ta address name [alias ...]
|
||||
.It networks Ta name network [alias ...]
|
||||
.It passwd Ta user:passwd:uid:gid:gecos:home_dir:shell
|
||||
.It protocols Ta name protocol [alias ...]
|
||||
.It rpc Ta name number [alias ...]
|
||||
.It services Ta name port/protocol [alias ...]
|
||||
.It shells Ta /path/to/shell
|
||||
.El
|
||||
.Pp
|
||||
If one or more
|
||||
.Ar key
|
||||
arguments are provided, they will be looked up in
|
||||
.Ar database
|
||||
using the appropriate function.
|
||||
For example,
|
||||
.Sy passwd
|
||||
supports a numeric UID or user name;
|
||||
.Sy hosts
|
||||
supports an IPv4 address, IPv6 address, or host name;
|
||||
and
|
||||
.Sy services
|
||||
supports a service name, service name/protocol name, numeric port, or
|
||||
numeric port/protocol name.
|
||||
.Pp
|
||||
If no
|
||||
.Ar key
|
||||
is provided and
|
||||
.Ar database
|
||||
supports enumeration, all entries for
|
||||
.Ar database
|
||||
will be retrieved using the appropriate enumeration function and printed.
|
||||
.Sh DIAGNOSTICS
|
||||
.Nm
|
||||
exits 0 on success,
|
||||
1 if there was an error in the command syntax,
|
||||
2 if one of the specified key names was not found in
|
||||
.Ar database ,
|
||||
or 3 if there is no support for enumeration on
|
||||
.Ar database .
|
||||
.Sh SEE ALSO
|
||||
.Xr ethers 5 ,
|
||||
.Xr group 5 ,
|
||||
.Xr hosts 5 ,
|
||||
.Xr networks 5 ,
|
||||
.Xr nsswitch.conf 5 ,
|
||||
.Xr passwd 5 ,
|
||||
.Xr protocols 5 ,
|
||||
.Xr rpc 5 ,
|
||||
.Xr services 5 ,
|
||||
.Xr shells 5
|
||||
.Sh HISTORY
|
||||
A
|
||||
.Nm
|
||||
command appeared in
|
||||
.Nx 3.0 ,
|
||||
and was imported into
|
||||
.Fx 7.0 .
|
||||
It was based on the command of the same name in
|
||||
.Tn Solaris
|
||||
and
|
||||
.Tn Linux .
|
564
usr.bin/getent/getent.c
Normal file
564
usr.bin/getent/getent.c
Normal file
@ -0,0 +1,564 @@
|
||||
/* $NetBSD: getent.c,v 1.7 2005/08/24 14:31:02 ginsbach Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Luke Mewburn.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/param.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/in.h> /* for INET6_ADDRSTRLEN */
|
||||
#include <rpc/rpcent.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int usage(void);
|
||||
static int parsenum(const char *, unsigned long *);
|
||||
static int ethers(int, char *[]);
|
||||
static int group(int, char *[]);
|
||||
static int hosts(int, char *[]);
|
||||
static int networks(int, char *[]);
|
||||
static int passwd(int, char *[]);
|
||||
static int protocols(int, char *[]);
|
||||
static int rpc(int, char *[]);
|
||||
static int services(int, char *[]);
|
||||
static int shells(int, char *[]);
|
||||
|
||||
enum {
|
||||
RV_OK = 0,
|
||||
RV_USAGE = 1,
|
||||
RV_NOTFOUND = 2,
|
||||
RV_NOENUM = 3,
|
||||
};
|
||||
|
||||
static struct getentdb {
|
||||
const char *name;
|
||||
int (*callback)(int, char *[]);
|
||||
} databases[] = {
|
||||
{ "ethers", ethers, },
|
||||
{ "group", group, },
|
||||
{ "hosts", hosts, },
|
||||
{ "networks", networks, },
|
||||
{ "passwd", passwd, },
|
||||
{ "protocols", protocols, },
|
||||
{ "rpc", rpc, },
|
||||
{ "services", services, },
|
||||
{ "shells", shells, },
|
||||
|
||||
{ NULL, NULL, },
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct getentdb *curdb;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
for (curdb = databases; curdb->name != NULL; curdb++) {
|
||||
if (strcmp(curdb->name, argv[1]) == 0) {
|
||||
exit(curdb->callback(argc, argv));
|
||||
break;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "Unknown database: %s\n", argv[1]);
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
return RV_USAGE;
|
||||
}
|
||||
|
||||
static int
|
||||
usage(void)
|
||||
{
|
||||
struct getentdb *curdb;
|
||||
|
||||
fprintf(stderr, "Usage: %s database [key ...]\n",
|
||||
getprogname());
|
||||
fprintf(stderr, " database may be one of:\n\t");
|
||||
for (curdb = databases; curdb->name != NULL; curdb++) {
|
||||
fprintf(stderr, " %s", curdb->name);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
exit(RV_USAGE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static int
|
||||
parsenum(const char *word, unsigned long *result)
|
||||
{
|
||||
unsigned long num;
|
||||
char *ep;
|
||||
|
||||
assert(word != NULL);
|
||||
assert(result != NULL);
|
||||
|
||||
if (!isdigit((unsigned char)word[0]))
|
||||
return 0;
|
||||
errno = 0;
|
||||
num = strtoul(word, &ep, 10);
|
||||
if (num == ULONG_MAX && errno == ERANGE)
|
||||
return 0;
|
||||
if (*ep != '\0')
|
||||
return 0;
|
||||
*result = num;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* printfmtstrings --
|
||||
* vprintf(format, ...),
|
||||
* then the aliases (beginning with prefix, separated by sep),
|
||||
* then a newline
|
||||
*/
|
||||
static void
|
||||
printfmtstrings(char *strings[], const char *prefix, const char *sep,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
const char *curpref;
|
||||
int i;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vprintf(fmt, ap);
|
||||
|
||||
curpref = prefix;
|
||||
for (i = 0; strings[i] != NULL; i++) {
|
||||
printf("%s%s", curpref, strings[i]);
|
||||
curpref = sep;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* ethers
|
||||
*/
|
||||
static int
|
||||
ethers(int argc, char *argv[])
|
||||
{
|
||||
char hostname[MAXHOSTNAMELEN + 1], *hp;
|
||||
struct ether_addr ea, *eap;
|
||||
int i, rv;
|
||||
|
||||
assert(argc > 1);
|
||||
assert(argv != NULL);
|
||||
|
||||
#define ETHERSPRINT printf("%-17s %s\n", ether_ntoa(eap), hp)
|
||||
|
||||
rv = RV_OK;
|
||||
if (argc == 2) {
|
||||
fprintf(stderr, "Enumeration not supported on ethers\n");
|
||||
rv = RV_NOENUM;
|
||||
} else {
|
||||
for (i = 2; i < argc; i++) {
|
||||
if ((eap = ether_aton(argv[i])) == NULL) {
|
||||
eap = &ea;
|
||||
hp = argv[i];
|
||||
if (ether_hostton(hp, eap) != 0) {
|
||||
rv = RV_NOTFOUND;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
hp = hostname;
|
||||
if (ether_ntohost(hp, eap) != 0) {
|
||||
rv = RV_NOTFOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ETHERSPRINT;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* group
|
||||
*/
|
||||
|
||||
static int
|
||||
group(int argc, char *argv[])
|
||||
{
|
||||
struct group *gr;
|
||||
unsigned long id;
|
||||
int i, rv;
|
||||
|
||||
assert(argc > 1);
|
||||
assert(argv != NULL);
|
||||
|
||||
#define GROUPPRINT printfmtstrings(gr->gr_mem, ":", ",", "%s:%s:%u", \
|
||||
gr->gr_name, gr->gr_passwd, gr->gr_gid)
|
||||
|
||||
setgroupent(1);
|
||||
rv = RV_OK;
|
||||
if (argc == 2) {
|
||||
while ((gr = getgrent()) != NULL)
|
||||
GROUPPRINT;
|
||||
} else {
|
||||
for (i = 2; i < argc; i++) {
|
||||
if (parsenum(argv[i], &id))
|
||||
gr = getgrgid((gid_t)id);
|
||||
else
|
||||
gr = getgrnam(argv[i]);
|
||||
if (gr != NULL)
|
||||
GROUPPRINT;
|
||||
else {
|
||||
rv = RV_NOTFOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
endgrent();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* hosts
|
||||
*/
|
||||
|
||||
static void
|
||||
hostsprint(const struct hostent *he)
|
||||
{
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
|
||||
assert(he != NULL);
|
||||
if (inet_ntop(he->h_addrtype, he->h_addr, buf, sizeof(buf)) == NULL)
|
||||
strlcpy(buf, "# unknown", sizeof(buf));
|
||||
printfmtstrings(he->h_aliases, " ", " ", "%-16s %s", buf, he->h_name);
|
||||
}
|
||||
|
||||
static int
|
||||
hosts(int argc, char *argv[])
|
||||
{
|
||||
struct hostent *he;
|
||||
char addr[IN6ADDRSZ];
|
||||
int i, rv;
|
||||
|
||||
assert(argc > 1);
|
||||
assert(argv != NULL);
|
||||
|
||||
sethostent(1);
|
||||
rv = RV_OK;
|
||||
if (argc == 2) {
|
||||
while ((he = gethostent()) != NULL)
|
||||
hostsprint(he);
|
||||
} else {
|
||||
for (i = 2; i < argc; i++) {
|
||||
if (inet_pton(AF_INET6, argv[i], (void *)addr) > 0)
|
||||
he = gethostbyaddr(addr, IN6ADDRSZ, AF_INET6);
|
||||
else if (inet_pton(AF_INET, argv[i], (void *)addr) > 0)
|
||||
he = gethostbyaddr(addr, INADDRSZ, AF_INET);
|
||||
else
|
||||
he = gethostbyname(argv[i]);
|
||||
if (he != NULL)
|
||||
hostsprint(he);
|
||||
else {
|
||||
rv = RV_NOTFOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
endhostent();
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* networks
|
||||
*/
|
||||
static void
|
||||
networksprint(const struct netent *ne)
|
||||
{
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
struct in_addr ianet;
|
||||
|
||||
assert(ne != NULL);
|
||||
ianet = inet_makeaddr(ne->n_net, 0);
|
||||
if (inet_ntop(ne->n_addrtype, &ianet, buf, sizeof(buf)) == NULL)
|
||||
strlcpy(buf, "# unknown", sizeof(buf));
|
||||
printfmtstrings(ne->n_aliases, " ", " ", "%-16s %s", ne->n_name, buf);
|
||||
}
|
||||
|
||||
static int
|
||||
networks(int argc, char *argv[])
|
||||
{
|
||||
struct netent *ne;
|
||||
in_addr_t net;
|
||||
int i, rv;
|
||||
|
||||
assert(argc > 1);
|
||||
assert(argv != NULL);
|
||||
|
||||
setnetent(1);
|
||||
rv = RV_OK;
|
||||
if (argc == 2) {
|
||||
while ((ne = getnetent()) != NULL)
|
||||
networksprint(ne);
|
||||
} else {
|
||||
for (i = 2; i < argc; i++) {
|
||||
net = inet_network(argv[i]);
|
||||
if (net != INADDR_NONE)
|
||||
ne = getnetbyaddr(net, AF_INET);
|
||||
else
|
||||
ne = getnetbyname(argv[i]);
|
||||
if (ne != NULL)
|
||||
networksprint(ne);
|
||||
else {
|
||||
rv = RV_NOTFOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
endnetent();
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* passwd
|
||||
*/
|
||||
static int
|
||||
passwd(int argc, char *argv[])
|
||||
{
|
||||
struct passwd *pw;
|
||||
unsigned long id;
|
||||
int i, rv;
|
||||
|
||||
assert(argc > 1);
|
||||
assert(argv != NULL);
|
||||
|
||||
#define PASSWDPRINT printf("%s:%s:%u:%u:%s:%s:%s\n", \
|
||||
pw->pw_name, pw->pw_passwd, pw->pw_uid, \
|
||||
pw->pw_gid, pw->pw_gecos, pw->pw_dir, pw->pw_shell)
|
||||
|
||||
setpassent(1);
|
||||
rv = RV_OK;
|
||||
if (argc == 2) {
|
||||
while ((pw = getpwent()) != NULL)
|
||||
PASSWDPRINT;
|
||||
} else {
|
||||
for (i = 2; i < argc; i++) {
|
||||
if (parsenum(argv[i], &id))
|
||||
pw = getpwuid((uid_t)id);
|
||||
else
|
||||
pw = getpwnam(argv[i]);
|
||||
if (pw != NULL)
|
||||
PASSWDPRINT;
|
||||
else {
|
||||
rv = RV_NOTFOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
endpwent();
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* protocols
|
||||
*/
|
||||
static int
|
||||
protocols(int argc, char *argv[])
|
||||
{
|
||||
struct protoent *pe;
|
||||
unsigned long id;
|
||||
int i, rv;
|
||||
|
||||
assert(argc > 1);
|
||||
assert(argv != NULL);
|
||||
|
||||
#define PROTOCOLSPRINT printfmtstrings(pe->p_aliases, " ", " ", \
|
||||
"%-16s %5d", pe->p_name, pe->p_proto)
|
||||
|
||||
setprotoent(1);
|
||||
rv = RV_OK;
|
||||
if (argc == 2) {
|
||||
while ((pe = getprotoent()) != NULL)
|
||||
PROTOCOLSPRINT;
|
||||
} else {
|
||||
for (i = 2; i < argc; i++) {
|
||||
if (parsenum(argv[i], &id))
|
||||
pe = getprotobynumber((int)id);
|
||||
else
|
||||
pe = getprotobyname(argv[i]);
|
||||
if (pe != NULL)
|
||||
PROTOCOLSPRINT;
|
||||
else {
|
||||
rv = RV_NOTFOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
endprotoent();
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* rpc
|
||||
*/
|
||||
static int
|
||||
rpc(int argc, char *argv[])
|
||||
{
|
||||
struct rpcent *re;
|
||||
unsigned long id;
|
||||
int i, rv;
|
||||
|
||||
assert(argc > 1);
|
||||
assert(argv != NULL);
|
||||
|
||||
#define RPCPRINT printfmtstrings(re->r_aliases, " ", " ", \
|
||||
"%-16s %6d", \
|
||||
re->r_name, re->r_number)
|
||||
|
||||
setrpcent(1);
|
||||
rv = RV_OK;
|
||||
if (argc == 2) {
|
||||
while ((re = getrpcent()) != NULL)
|
||||
RPCPRINT;
|
||||
} else {
|
||||
for (i = 2; i < argc; i++) {
|
||||
if (parsenum(argv[i], &id))
|
||||
re = getrpcbynumber((int)id);
|
||||
else
|
||||
re = getrpcbyname(argv[i]);
|
||||
if (re != NULL)
|
||||
RPCPRINT;
|
||||
else {
|
||||
rv = RV_NOTFOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
endrpcent();
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* services
|
||||
*/
|
||||
static int
|
||||
services(int argc, char *argv[])
|
||||
{
|
||||
struct servent *se;
|
||||
unsigned long id;
|
||||
char *proto;
|
||||
int i, rv;
|
||||
|
||||
assert(argc > 1);
|
||||
assert(argv != NULL);
|
||||
|
||||
#define SERVICESPRINT printfmtstrings(se->s_aliases, " ", " ", \
|
||||
"%-16s %5d/%s", \
|
||||
se->s_name, ntohs(se->s_port), se->s_proto)
|
||||
|
||||
setservent(1);
|
||||
rv = RV_OK;
|
||||
if (argc == 2) {
|
||||
while ((se = getservent()) != NULL)
|
||||
SERVICESPRINT;
|
||||
} else {
|
||||
for (i = 2; i < argc; i++) {
|
||||
proto = strchr(argv[i], '/');
|
||||
if (proto != NULL)
|
||||
*proto++ = '\0';
|
||||
if (parsenum(argv[i], &id))
|
||||
se = getservbyport(htons((u_short)id), proto);
|
||||
else
|
||||
se = getservbyname(argv[i], proto);
|
||||
if (se != NULL)
|
||||
SERVICESPRINT;
|
||||
else {
|
||||
rv = RV_NOTFOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
endservent();
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* shells
|
||||
*/
|
||||
static int
|
||||
shells(int argc, char *argv[])
|
||||
{
|
||||
const char *sh;
|
||||
int i, rv;
|
||||
|
||||
assert(argc > 1);
|
||||
assert(argv != NULL);
|
||||
|
||||
#define SHELLSPRINT printf("%s\n", sh)
|
||||
|
||||
setusershell();
|
||||
rv = RV_OK;
|
||||
if (argc == 2) {
|
||||
while ((sh = getusershell()) != NULL)
|
||||
SHELLSPRINT;
|
||||
} else {
|
||||
for (i = 2; i < argc; i++) {
|
||||
setusershell();
|
||||
while ((sh = getusershell()) != NULL) {
|
||||
if (strcmp(sh, argv[i]) == 0) {
|
||||
SHELLSPRINT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sh == NULL) {
|
||||
rv = RV_NOTFOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
endusershell();
|
||||
return rv;
|
||||
}
|
19
usr.sbin/ipfwpcap/Makefile
Normal file
19
usr.sbin/ipfwpcap/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
#
|
||||
# From: Id: Makefile,v 1.2 2004/01/15 16:20:56 pkern Exp
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
PROG= ipfwpcap
|
||||
|
||||
LDADD= -lpcap
|
||||
DPADD= ${LIBPCAP}
|
||||
|
||||
MAN= ipfwpcap.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
test: $(CMD)
|
||||
-rm /var/run/ipfwpcap.2000.pid
|
||||
./ipfwpcap -d 2000 - | tcpdump -r - -n -s 2000 -X
|
||||
|
583
usr.sbin/ntp/doc/ntp-keygen.8
Normal file
583
usr.sbin/ntp/doc/ntp-keygen.8
Normal file
@ -0,0 +1,583 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 17, 2006
|
||||
.Dt NTP-KEYGEN. 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ntp-keygen
|
||||
.Nd key generation program for ntpd
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl deGgHIMnPT
|
||||
.Op Fl c Oo Cm RSA-MD2 | RSA-MD5 | RSA-SHA | RSA-SHA1 | RSA-MDC2 | RSA-RIPEMD160 | DSA-SHA | DSA-SHA1 Oc
|
||||
.Op Fl i Ar name
|
||||
.Op Fl p Ar password
|
||||
.Op Fl S Oo Cm RSA | DSA Oc
|
||||
.Op Fl s Ar name
|
||||
.Op Fl v Ar nkeys
|
||||
|
||||
.Sh DESCRIPTION
|
||||
This program generates cryptographic data files used by the NTPv4
|
||||
authentication and identification schemes.
|
||||
It generates MD5 key files used in symmetric key cryptography.
|
||||
In addition, if the OpenSSL software library has been installed,
|
||||
it generates keys, certificate and identity files used in public key
|
||||
cryptography. These files are used for cookie encryption,
|
||||
digital signature and challenge/response identification algorithms
|
||||
compatible with the Internet standard security infrastructure.
|
||||
.Pp
|
||||
All files are in PEM-encoded printable ASCII format,
|
||||
so they can be embedded as MIME attachments in mail to other sites
|
||||
and certificate authorities.
|
||||
By default, files are not encrypted. The
|
||||
.Fl p Ar password
|
||||
option specifies the write password and
|
||||
.Fl q Ar password
|
||||
option the read password for previously encrypted files.
|
||||
The
|
||||
.Nm
|
||||
program prompts for the password if it reads an encrypted file
|
||||
and the password is missing or incorrect.
|
||||
If an encrypted file is read successfully and
|
||||
no write password is specified, the read password is used
|
||||
as the write password by default.
|
||||
.Pp
|
||||
The
|
||||
.Xr ntpd 8
|
||||
configuration command
|
||||
.Ic crypto pw Ar password
|
||||
specifies the read password for previously encrypted files.
|
||||
The daemon expires on the spot if the password is missing
|
||||
or incorrect.
|
||||
For convenience, if a file has been previously encrypted,
|
||||
the default read password is the name of the host running
|
||||
the program.
|
||||
If the previous write password is specified as the host name,
|
||||
these files can be read by that host with no explicit password.
|
||||
.Pp
|
||||
File names begin with the prefix
|
||||
.Cm ntpkey_
|
||||
and end with the postfix
|
||||
.Ar _hostname.filestamp ,
|
||||
where
|
||||
.Ar hostname
|
||||
is the owner name, usually the string returned
|
||||
by the Unix gethostname() routine, and
|
||||
.Ar filestamp
|
||||
is the NTP seconds when the file was generated, in decimal digits.
|
||||
This both guarantees uniqueness and simplifies maintenance
|
||||
procedures, since all files can be quickly removed
|
||||
by a
|
||||
.Ic rm ntpkey\&*
|
||||
command or all files generated
|
||||
at a specific time can be removed by a
|
||||
.Ic rm
|
||||
.Ar \&*filestamp
|
||||
command.
|
||||
To further reduce the risk of misconfiguration,
|
||||
the first two lines of a file contain the file name
|
||||
and generation date and time as comments.
|
||||
.Pp
|
||||
All files are installed by default in the keys directory
|
||||
.Pa /usr/local/etc ,
|
||||
which is normally in a shared filesystem
|
||||
in NFS-mounted networks. The actual location of the keys directory
|
||||
and each file can be overridden by configuration commands,
|
||||
but this is not recommended.
|
||||
Normally, the files for each host are generated by that host
|
||||
and used only by that host, although exceptions exist
|
||||
as noted later on this page.
|
||||
.Pp
|
||||
Normally, files containing private values,
|
||||
including the host key, sign key and identification parameters,
|
||||
are permitted root read/write-only;
|
||||
while others containing public values are permitted world readable.
|
||||
Alternatively, files containing private values can be encrypted
|
||||
and these files permitted world readable,
|
||||
which simplifies maintenance in shared file systems.
|
||||
Since uniqueness is insured by the hostname and
|
||||
file name extensions, the files for a NFS server and
|
||||
dependent clients can all be installed in the same shared directory.
|
||||
.Pp
|
||||
The recommended practice is to keep the file name extensions
|
||||
when installing a file and to install a soft link
|
||||
from the generic names specified elsewhere on this page
|
||||
to the generated files.
|
||||
This allows new file generations to be activated simply
|
||||
by changing the link.
|
||||
If a link is present, ntpd follows it to the file name
|
||||
to extract the filestamp.
|
||||
If a link is not present,
|
||||
.Xr ntpd 8
|
||||
extracts the filestamp from the file itself.
|
||||
This allows clients to verify that the file and generation times
|
||||
are always current. The
|
||||
.Nm
|
||||
program uses the same timestamp extension for all files generated
|
||||
at one time, so each generation is distinct and can be readily
|
||||
recognized in monitoring data.
|
||||
.Ss Running the program
|
||||
The safest way to run the
|
||||
.Nm
|
||||
program is logged in directly as root.
|
||||
The recommended procedure is change to the keys directory,
|
||||
usually
|
||||
.Pa /ust/local/etc ,
|
||||
then run the program. When run for the first time,
|
||||
or if all
|
||||
.Cm ntpkey
|
||||
files have been removed,
|
||||
the program generates a RSA host key file and matching RSA-MD5 certificate file,
|
||||
which is all that is necessary in many cases.
|
||||
The program also generates soft links from the generic names
|
||||
to the respective files.
|
||||
If run again, the program uses the same host key file,
|
||||
but generates a new certificate file and link.
|
||||
.Pp
|
||||
The host key is used to encrypt the cookie when required and so must be RSA type.
|
||||
By default, the host key is also the sign key used to encrypt signatures.
|
||||
When necessary, a different sign key can be specified and this can be
|
||||
either RSA or DSA type.
|
||||
By default, the message digest type is MD5, but any combination
|
||||
of sign key type and message digest type supported by the OpenSSL library
|
||||
can be specified, including those using the MD2, MD5, SHA, SHA1, MDC2
|
||||
and RIPE160 message digest algorithms.
|
||||
However, the scheme specified in the certificate must be compatible
|
||||
with the sign key.
|
||||
Certificates using any digest algorithm are compatible with RSA sign keys;
|
||||
however, only SHA and SHA1 certificates are compatible with DSA sign keys.
|
||||
.Pp
|
||||
Private/public key files and certificates are compatible with
|
||||
other OpenSSL applications and very likely other libraries as well.
|
||||
Certificates or certificate requests derived from them should be compatible
|
||||
with extant industry practice, although some users might find
|
||||
the interpretation of X509v3 extension fields somewhat liberal.
|
||||
However, the identification parameter files, although encoded
|
||||
as the other files, are probably not compatible with anything other than Autokey.
|
||||
.Pp
|
||||
Running the program as other than root and using the Unix
|
||||
.Ic su
|
||||
command
|
||||
to assume root may not work properly, since by default the OpenSSL library
|
||||
looks for the random seed file
|
||||
.Cm .rnd
|
||||
in the user home directory.
|
||||
However, there should be only one
|
||||
.Cm .rnd ,
|
||||
most conveniently
|
||||
in the root directory, so it is convenient to define the
|
||||
.Cm $RANDFILE
|
||||
environment variable used by the OpenSSL library as the path to
|
||||
.Cm /.rnd .
|
||||
.Pp
|
||||
Installing the keys as root might not work in NFS-mounted
|
||||
shared file systems, as NFS clients may not be able to write
|
||||
to the shared keys directory, even as root.
|
||||
In this case, NFS clients can specify the files in another
|
||||
directory such as
|
||||
.Pa /etc
|
||||
using the
|
||||
.Ic keysdir
|
||||
command.
|
||||
There is no need for one client to read the keys and certificates
|
||||
of other clients or servers, as these data are obtained automatically
|
||||
by the Autokey protocol.
|
||||
.Pp
|
||||
Ordinarily, cryptographic files are generated by the host that uses them,
|
||||
but it is possible for a trusted agent (TA) to generate these files
|
||||
for other hosts; however, in such cases files should always be encrypted.
|
||||
The subject name and trusted name default to the hostname
|
||||
of the host generating the files, but can be changed by command line options.
|
||||
It is convenient to designate the owner name and trusted name
|
||||
as the subject and issuer fields, respectively, of the certificate.
|
||||
The owner name is also used for the host and sign key files,
|
||||
while the trusted name is used for the identity files.
|
||||
.Pp
|
||||
.Ss Trusted Hosts and Groups
|
||||
Each cryptographic configuration involves selection of a signature scheme
|
||||
and identification scheme, called a cryptotype,
|
||||
as explained in the
|
||||
.Sx Authentication Options
|
||||
section of
|
||||
.Xr ntp.conf 5 .
|
||||
The default cryptotype uses RSA encryption, MD5 message digest
|
||||
and TC identification.
|
||||
First, configure a NTP subnet including one or more low-stratum
|
||||
trusted hosts from which all other hosts derive synchronization
|
||||
directly or indirectly. Trusted hosts have trusted certificates;
|
||||
all other hosts have nontrusted certificates.
|
||||
These hosts will automatically and dynamically build authoritative
|
||||
certificate trails to one or more trusted hosts.
|
||||
A trusted group is the set of all hosts that have, directly or indirectly,
|
||||
a certificate trail ending at a trusted host.
|
||||
The trail is defined by static configuration file entries
|
||||
or dynamic means described on the
|
||||
.Sx Automatic NTP Configuration Options
|
||||
section of
|
||||
.Xr ntp.conf 5 .
|
||||
.Pp
|
||||
On each trusted host as root, change to the keys directory.
|
||||
To insure a fresh fileset, remove all
|
||||
.Cm ntpkey
|
||||
files.
|
||||
Then run
|
||||
.Nm
|
||||
.Fl T
|
||||
to generate keys and a trusted certificate.
|
||||
On all other hosts do the same, but leave off the
|
||||
.Fl T
|
||||
flag to generate keys and nontrusted certificates.
|
||||
When complete, start the NTP daemons beginning at the lowest stratum
|
||||
and working up the tree.
|
||||
It may take some time for Autokey to instantiate the certificate trails
|
||||
throughout the subnet, but setting up the environment is completely automatic.
|
||||
.Pp
|
||||
If it is necessary to use a different sign key or different digest/signature
|
||||
scheme than the default, run
|
||||
.Nm
|
||||
with the
|
||||
.Fl S Ar type
|
||||
option, where
|
||||
.Ar type
|
||||
is either
|
||||
.Cm RSA
|
||||
or
|
||||
.Cm DSA .
|
||||
The most often need to do this is when a DSA-signed certificate is used.
|
||||
If it is necessary to use a different certificate scheme than the default,
|
||||
run
|
||||
.Nm
|
||||
with the
|
||||
.Fl c Ar scheme
|
||||
option and selected
|
||||
.Ar scheme
|
||||
as needed.
|
||||
If
|
||||
.Nm
|
||||
is run again without these options, it generates a new certificate
|
||||
using the same scheme and sign key.
|
||||
.Pp
|
||||
After setting up the environment it is advisable to update certificates
|
||||
from time to time, if only to extend the validity interval.
|
||||
Simply run
|
||||
.Nm
|
||||
with the same flags as before to generate new certificates
|
||||
using existing keys.
|
||||
However, if the host or sign key is changed,
|
||||
.Xr ntpd 8
|
||||
should be restarted.
|
||||
When
|
||||
.Xr ntpd 8
|
||||
is restarted, it loads any new files and restarts the protocol.
|
||||
Other dependent hosts will continue as usual until signatures are refreshed,
|
||||
at which time the protocol is restarted.
|
||||
.Ss Identity Schemes
|
||||
As mentioned on the Autonomous Authentication page,
|
||||
the default TC identity scheme is vulnerable to a middleman attack.
|
||||
However, there are more secure identity schemes available,
|
||||
including PC, IFF, GQ and MV described on the
|
||||
.Qq Identification Schemes
|
||||
page
|
||||
(maybe available at
|
||||
.Li http://www.eecis.udel.edu/%7emills/keygen.html ) .
|
||||
These schemes are based on a TA, one or more trusted hosts
|
||||
and some number of nontrusted hosts.
|
||||
Trusted hosts prove identity using values provided by the TA,
|
||||
while the remaining hosts prove identity using values provided
|
||||
by a trusted host and certificate trails that end on that host.
|
||||
The name of a trusted host is also the name of its sugroup
|
||||
and also the subject and issuer name on its trusted certificate.
|
||||
The TA is not necessarily a trusted host in this sense, but often is.
|
||||
.Pp
|
||||
In some schemes there are separate keys for servers and clients.
|
||||
A server can also be a client of another server,
|
||||
but a client can never be a server for another client.
|
||||
In general, trusted hosts and nontrusted hosts that operate
|
||||
as both server and client have parameter files that contain
|
||||
both server and client keys. Hosts that operate
|
||||
only as clients have key files that contain only client keys.
|
||||
.Pp
|
||||
The PC scheme supports only one trusted host in the group.
|
||||
On trusted host alice run
|
||||
.Nm
|
||||
.Fl P
|
||||
.Fl p Ar password
|
||||
to generate the host key file
|
||||
.Pa ntpkey_RSAkey_ Ns Ar alice.filestamp
|
||||
and trusted private certificate file
|
||||
.Pa ntpkey_RSA-MD5_cert_ Ns Ar alice.filestamp .
|
||||
Copy both files to all group hosts;
|
||||
they replace the files which would be generated in other schemes.
|
||||
On each host bob install a soft link from the generic name
|
||||
.Pa ntpkey_host_ Ns Ar bob
|
||||
to the host key file and soft link
|
||||
.Pa ntpkey_cert_ Ns Ar bob
|
||||
to the private certificate file.
|
||||
Note the generic links are on bob, but point to files generated
|
||||
by trusted host alice. In this scheme it is not possible to refresh
|
||||
either the keys or certificates without copying them
|
||||
to all other hosts in the group.
|
||||
.Pp
|
||||
For the IFF scheme proceed as in the TC scheme to generate keys
|
||||
and certificates for all group hosts, then for every trusted host in the group,
|
||||
generate the IFF parameter file.
|
||||
On trusted host alice run
|
||||
.Nm
|
||||
.Fl T
|
||||
.Fl I
|
||||
.Fl p Ar password
|
||||
to produce her parameter file
|
||||
.Pa ntpkey_IFFpar_ Ns Ar alice.filestamp ,
|
||||
which includes both server and client keys.
|
||||
Copy this file to all group hosts that operate as both servers
|
||||
and clients and install a soft link from the generic
|
||||
.Pa ntpkey_iff_ Ns Ar alice
|
||||
to this file.
|
||||
If there are no hosts restricted to operate only as clients,
|
||||
there is nothing further to do. As the IFF scheme is independent
|
||||
of keys and certificates, these files can be refreshed as needed.
|
||||
.Pp
|
||||
If a rogue client has the parameter file, it could masquerade
|
||||
as a legitimate server and present a middleman threat.
|
||||
To eliminate this threat, the client keys can be extracted
|
||||
from the parameter file and distributed to all restricted clients.
|
||||
After generating the parameter file, on alice run
|
||||
.Nm
|
||||
.Fl e
|
||||
and pipe the output to a file or mail program.
|
||||
Copy or mail this file to all restricted clients.
|
||||
On these clients install a soft link from the generic
|
||||
.Pa ntpkey_iff_ Ns Ar alice
|
||||
to this file. To further protect the integrity of the keys,
|
||||
each file can be encrypted with a secret password.
|
||||
.Pp
|
||||
For the GQ scheme proceed as in the TC scheme to generate keys
|
||||
and certificates for all group hosts, then for every trusted host
|
||||
in the group, generate the IFF parameter file.
|
||||
On trusted host alice run
|
||||
.Nm
|
||||
.Fl T
|
||||
.Fl G
|
||||
.Fl p Ar password
|
||||
to produce her parameter file
|
||||
.Pa ntpkey_GQpar_ Ns Ar alice.filestamp ,
|
||||
which includes both server and client keys.
|
||||
Copy this file to all group hosts and install a soft link
|
||||
from the generic
|
||||
.Pa ntpkey_gq_ Ns Ar alice
|
||||
to this file.
|
||||
In addition, on each host bob install a soft link
|
||||
from generic
|
||||
.Pa ntpkey_gq_ Ns Ar bob
|
||||
to this file.
|
||||
As the GQ scheme updates the GQ parameters file and certificate
|
||||
at the same time, keys and certificates can be regenerated as needed.
|
||||
.Pp
|
||||
For the MV scheme, proceed as in the TC scheme to generate keys
|
||||
and certificates for all group hosts.
|
||||
For illustration assume trish is the TA, alice one of several trusted hosts
|
||||
and bob one of her clients. On TA trish run
|
||||
.Nm
|
||||
.Fl V Ar n
|
||||
.Fl p Ar password ,
|
||||
where
|
||||
.Ar n
|
||||
is the number of revokable keys (typically 5) to produce
|
||||
the parameter file
|
||||
.Pa ntpkeys_MVpar_ Ns Ar trish.filestamp
|
||||
and client key files
|
||||
.Pa ntpkeys_MVkeyd_ Ns Ar trish.filestamp
|
||||
where
|
||||
.Ar d
|
||||
is the key number (0 \&<
|
||||
.Ar d
|
||||
\&<
|
||||
.Ar n ) .
|
||||
Copy the parameter file to alice and install a soft link
|
||||
from the generic
|
||||
.Pa ntpkey_mv_ Ns Ar alice
|
||||
to this file.
|
||||
Copy one of the client key files to alice for later distribution
|
||||
to her clients.
|
||||
It doesn't matter which client key file goes to alice,
|
||||
since they all work the same way.
|
||||
Alice copies the client key file to all of her cliens.
|
||||
On client bob install a soft link from generic
|
||||
.Pa ntpkey_mvkey_ Ns Ar bob
|
||||
to the client key file.
|
||||
As the MV scheme is independent of keys and certificates,
|
||||
these files can be refreshed as needed.
|
||||
.Ss Command Line Options
|
||||
.Bl -tag -width indent
|
||||
.It Fl c Oo Cm RSA-MD2 | RSA-MD5 | RSA-SHA | RSA-SHA1 | RSA-MDC2 | RSA-RIPEMD160 | DSA-SHA | DSA-SHA1 Oc
|
||||
Select certificate message digest/signature encryption scheme.
|
||||
Note that RSA schemes must be used with a RSA sign key and DSA
|
||||
schemes must be used with a DSA sign key.
|
||||
The default without this option is
|
||||
.Cm RSA-MD5 .
|
||||
.It Fl d
|
||||
Enable debugging.
|
||||
This option displays the cryptographic data produced in eye-friendly billboards.
|
||||
.It Fl e
|
||||
Write the IFF client keys to the standard output.
|
||||
This is intended for automatic key distribution by mail.
|
||||
.It Fl G
|
||||
Generate parameters and keys for the GQ identification scheme,
|
||||
obsoleting any that may exist.
|
||||
.It Fl g
|
||||
Generate keys for the GQ identification scheme
|
||||
using the existing GQ parameters.
|
||||
If the GQ parameters do not yet exist, create them first.
|
||||
.It Fl H
|
||||
Generate new host keys, obsoleting any that may exist.
|
||||
.It Fl I
|
||||
Generate parameters for the IFF identification scheme,
|
||||
obsoleting any that may exist.
|
||||
.It Fl i Ar name
|
||||
Set the suject name to
|
||||
.Ar name .
|
||||
This is used as the subject field in certificates
|
||||
and in the file name for host and sign keys.
|
||||
.It Fl M
|
||||
Generate MD5 keys, obsoleting any that may exist.
|
||||
.It Fl P
|
||||
Generate a private certificate.
|
||||
By default, the program generates public certificates.
|
||||
.It Fl p Ar password
|
||||
Encrypt generated files containing private data with
|
||||
.Ar password
|
||||
and the DES-CBC algorithm.
|
||||
.It Fl q
|
||||
Set the password for reading files to password.
|
||||
.It Fl S Oo Cm RSA | DSA Oc
|
||||
Generate a new sign key of the designated type,
|
||||
obsoleting any that may exist.
|
||||
By default, the program uses the host key as the sign key.
|
||||
.It Fl s Ar name
|
||||
Set the issuer name to
|
||||
.Ar name .
|
||||
This is used for the issuer field in certificates
|
||||
and in the file name for identity files.
|
||||
.It Fl T
|
||||
Generate a trusted certificate.
|
||||
By default, the program generates a non-trusted certificate.
|
||||
.It Fl V Ar nkeys
|
||||
Generate parameters and keys for the Mu-Varadharajan (MV) identification scheme.
|
||||
.El
|
||||
.Ss Random Seed File
|
||||
All cryptographically sound key generation schemes must have means
|
||||
to randomize the entropy seed used to initialize
|
||||
the internal pseudo-random number generator used
|
||||
by the library routines.
|
||||
The OpenSSL library uses a designated random seed file for this purpose.
|
||||
The file must be available when starting the NTP daemon and
|
||||
.Nm
|
||||
program. If a site supports OpenSSL or its companion OpenSSH,
|
||||
it is very likely that means to do this are already available.
|
||||
.Pp
|
||||
It is important to understand that entropy must be evolved
|
||||
for each generation, for otherwise the random number sequence
|
||||
would be predictable.
|
||||
Various means dependent on external events, such as keystroke intervals,
|
||||
can be used to do this and some systems have built-in entropy sources.
|
||||
Suitable means are described in the OpenSSL software documentation,
|
||||
but are outside the scope of this page.
|
||||
.Pp
|
||||
The entropy seed used by the OpenSSL library is contained in a file,
|
||||
usually called
|
||||
.Cm .rnd ,
|
||||
which must be available when starting the NTP daemon
|
||||
or the
|
||||
.Nm
|
||||
program. The NTP daemon will first look for the file
|
||||
using the path specified by the
|
||||
.Ic randfile
|
||||
subcommand of the
|
||||
.Ic crypto
|
||||
configuration command.
|
||||
If not specified in this way, or when starting the
|
||||
.Nm
|
||||
program,
|
||||
the OpenSSL library will look for the file using the path specified
|
||||
by the
|
||||
.Ev RANDFILE
|
||||
environment variable in the user home directory,
|
||||
whether root or some other user.
|
||||
If the
|
||||
.Ev RANDFILE
|
||||
environment variable is not present,
|
||||
the library will look for the
|
||||
.Cm .rnd
|
||||
file in the user home directory.
|
||||
If the file is not available or cannot be written,
|
||||
the daemon exits with a message to the system log and the program
|
||||
exits with a suitable error message.
|
||||
.Ss Cryptographic Data Files
|
||||
All other file formats begin with two lines.
|
||||
The first contains the file name, including the generated host name
|
||||
and filestamp.
|
||||
The second contains the datestamp in conventional Unix date format.
|
||||
Lines beginning with # are considered comments and ignored by the
|
||||
.Nm
|
||||
program and
|
||||
.Xr ntpd 8
|
||||
daemon.
|
||||
Cryptographic values are encoded first using ASN.1 rules,
|
||||
then encrypted if necessary, and finally written PEM-encoded
|
||||
printable ASCII format preceded and followed by MIME content identifier lines.
|
||||
.Pp
|
||||
The format of the symmetric keys file is somewhat different
|
||||
than the other files in the interest of backward compatibility.
|
||||
Since DES-CBC is deprecated in NTPv4, the only key format of interest
|
||||
is MD5 alphanumeric strings. Following hte heard the keys are
|
||||
entered one per line in the format
|
||||
.D1 Ar keyno type key
|
||||
where
|
||||
.Ar keyno
|
||||
is a positive integer in the range 1-65,535,
|
||||
.Ar type
|
||||
is the string MD5 defining the key format and
|
||||
.Ar key
|
||||
is the key itself,
|
||||
which is a printable ASCII string 16 characters or less in length.
|
||||
Each character is chosen from the 93 printable characters
|
||||
in the range 0x21 through 0x7f excluding space and the
|
||||
.Ql #
|
||||
character.
|
||||
.Pp
|
||||
Note that the keys used by the
|
||||
.Xr ntpq 8
|
||||
and
|
||||
.Xr ntpdc 8
|
||||
programs
|
||||
are checked against passwords requested by the programs
|
||||
and entered by hand, so it is generally appropriate to specify these keys
|
||||
in human readable ASCII format.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
program generates a MD5 symmetric keys file
|
||||
.Pa ntpkey_MD5key_ Ns Ar hostname.filestamp .
|
||||
Since the file contains private shared keys,
|
||||
it should be visible only to root and distributed by secure means
|
||||
to other subnet hosts.
|
||||
The NTP daemon loads the file
|
||||
.Pa ntp.keys ,
|
||||
so
|
||||
.Nm
|
||||
installs a soft link from this name to the generated file.
|
||||
Subsequently, similar soft links must be installed by manual
|
||||
or automated means on the other subnet hosts.
|
||||
While this file is not used with the Autokey Version 2 protocol,
|
||||
it is needed to authenticate some remote configuration commands
|
||||
used by the
|
||||
.Xr ntpq 8
|
||||
and
|
||||
.Xr ntpdc 8
|
||||
utilities.
|
||||
.Sh Bugs
|
||||
It can take quite a while to generate some cryptographic values,
|
||||
from one to several minutes with modern architectures
|
||||
such as UltraSPARC and up to tens of minutes to an hour
|
||||
with older architectures such as SPARC IPC.
|
Loading…
x
Reference in New Issue
Block a user